Гистограмма NumPy2d с повернутой неортогональной сеткой биннинга - PullRequest
0 голосов
/ 08 октября 2019

Мне нужно вычислить (и построить) a histogram2d, но моя сетка биннинга повернута и не ортогональна.
Один из способов сделать это - применить преобразование к моим данным, чтобы я превратил их вдекартова система, вычислите my histogram2d и затем примените обратное преобразование.
Можно ли это сделать напрямую без этого служебного преобразования?

Наверное, мой вопрос: как мне определить bins для моего histogram2d в этом случае? (AFAIK, histogram2d будет принимать только выровненные по x и y bins)

Мои данные представляют собой 2 огромных списка точек (по 10k ~ 100k каждая), координаты которых даны в декартовой системе координат (на самом деле это спроектированный CRS, потому что это реальные местоположения), но они организованы в регулярную сетку, которая не выровнена по осям X и Y (повернута) и может быть или не быть ортогональной. Сетка биннинга будет получена из нее, поэтому она будет (повернутой) регулярной четырехугольной сеткой.

Я видел, что matplotlib имеет объект QuadMesh ( см. Здесь ), поэтому я надеюсь, но я не уверен, как справиться с этим в NumPy.

В основном это то, чего я хочу достичь:

enter image description here

1 Ответ

0 голосов
/ 23 октября 2019

После некоторого тестирования я пришел к выводу, что накладные расходы на преобразование координат в декартову сетку для вычисления гистограммы и обратно для построения графика приемлемы. Матричные операции в NumPy довольно эффективны, и я могу обработать 115+ миллионов точек менее чем за 7 секунд.

Однако «задняя» часть может обрабатываться Matplotlib напрямую с помощью matplotlib.transforms.
pcolormesh, hist2d и imshow. Все они принимают ключевое слово transform, которое может бытьиспользуется для построения декартовых данных в нужные координаты, например:

# set I, J, bins (in the Cartesian system) and cmap
# a, b, c, d, e, f are values of the transformation matrix
transform = matplotlib.transforms.Affine2D.from_values(a, b, c, f, d, e, f)
fig, ax = plt.subplots(figsize=figsize)
_, _, _, im = ax.hist2d(I, J, bins=bins, cmap=cmap, transform=transform + ax.transData)
fig.colorbar(im)
ax.autoscale()

Это не намного быстрее, чем обработка «обратного» преобразования с помощью NumPy, но может сделать код легче, так как требует только1 дополнительная строка и 1 дополнительное ключевое слово.
imshow может быть немного болезненно, поскольку не будет обновлять экстент отображения после использования ax.autoscale() и обрабатывает координаты в виде изображений или матрицы, так что transform имеетбыть скорректированы соответственно. По этим причинам я предпочитаю hist2d.

Справочные материалы:

  1. https://matplotlib.org/3.1.1/api/transformations.html#module-matplotlib.transforms
  2. https://matplotlib.org/3.1.1/tutorials/advanced/transforms_tutorial.html
...