От Matplotlib Raster к Geoviews / Holoviews / hvplot: как преобразовать x, y и z

Я понимаю, что Geoviews и Holoviews имеют общие атрибуты, а Hvplot предназначен для создания высокоуровневого API построения графиков для всех трех.

Сейчас, перейдя из Matplotlib, я все еще испытываю трудности с адаптацией к параметрам, необходимым для отображения растровых изображений в Geoviews или Holoviews.

Вот пример, в котором я выполняю оценку плотности ядра для пространственных данных:

# add coordinates of observations
xy_train = np.vstack([y, x]).T
print(xy_train)
# [[5654810.66920637  413645.79802685]
# [5654712.51814666  412629.87266155]
# [5656120.03682466  411642.74943511]
# ...
# [5656316.96943554  411795.80163676]
# [5656299.73356505  411795.50717494]
# [5655756.85624901  411734.34680852]]

# create mesh
xbins=100j
ybins=100j
xx, yy = np.mgrid[left_bound:right_bound:xbins, 
                bottom_bound:top_bound:ybins]
xy_sample = np.vstack([yy.ravel(), xx.ravel()]).T
# compute Kernel Density here
# ..
kde = KernelDensity(kernel='gaussian', bandwidth=100, algorithm='ball_tree')
kde.fit(xy_train)
# get results
z = np.exp(kde.score_samples(xy_sample))
# reshape results to mesh
zz = z.reshape(xx.shape)
# plot in matplotlib
fig, ax_lst = plt.subplots(111)
levels = np.linspace(zz.min(), zz.max(), 25)
axis.contourf(xx, yy, zz, levels=levels, cmap='viridis')
axis.plot()
plt.show()

Показывает мое изображение:  введите описание изображения здесь

Теперь я хочу использовать среду pyviz для интерактивного отображения и наложения карты, например. используя Geoviews.

Это как-то работает, но дает мне ошибку:

xr_dataset = gv.Dataset(hv.Image((xx, yy, zz.T), datatype=['grid']), crs=ccrs.UTM(zone='33N'))

Image02195: Размеры изображения x и y не выбираются равномерно с относительным допуском 0,001. Используйте элемент QuadMesh для нерегулярной выборки данных или установите более высокий допуск для hv.config.image_rtol или параметра rtol в конструкторе изображений.

Я все еще могу отображать изображение (как-то с низким разрешением).

gv.tile_sources.CartoLight.opts(width=800, height=480) * xr_dataset.to.image(['x', 'y']).opts(cmap='viridis', alpha=0.5)

введите описание изображения здесь

.. но когда я пытаюсь создать FilledContours в Geoviews, похоже, это работает не так, как в matplotlib:

gv.FilledContours(xx, yy, zz, levels=levels, cmap='viridis')

ValueError: аргумент kdims ожидает измерение или список измерений, заданных как кортежи, строки, словари или экземпляры измерения, а не тип ndarray. Убедитесь, что вы передали данные в качестве первого аргумента.

В документации нет подробной информации о том, как мне форматировать размеры (hv.help(gv.FilledContours)). Я думаю, что где-то заблудился, когда мне нужно создать растр из numpy xx / yy координатной сетки (hv.Image((xx, yy, zz.T), datatype=['grid'])).

Может ли кто-нибудь объяснить разницу в синтаксисе, которая требуется для matplotlib Contourf и Holoviews / Geoviews / Hvplot FilledContours?

[редактировать]

Я нашел способ рисовать контуры, но проблема с размерами сохраняется:

# get xarray dataset, suited for handling raster data in pyviz
xr_dataset = gv.Dataset(hv.Image((xx.T, yy.T, zz.T), bounds=(left_bound,bottom_bound,right_bound,top_bound), 
        kdims=[hv.Dimension('x'),  hv.Dimension('y')], datatype=['grid']), crs=ccrs.UTM(zone='33N'))
# Error: Image06593: Image dimension(s) x and y are not evenly sampled to relative tolerance of 0.001

# create contours from image
gv.FilledContours(xr_dataset)

# plot
gv.tile_sources.EsriImagery.opts(width=800, height=480) * gv.FilledContours(xr_dataset).opts(cmap='viridis', alpha=0.5)

введите описание изображения здесь


person Alex    schedule 01.03.2019    source источник


Ответы (1)


Главное, что нужно знать об элементах HoloViews / GeoViews, - это то, что данные почти всегда указываются в качестве первого аргумента, в отличие от matplotlib, где данные часто указываются с использованием нескольких аргументов. В вашем случае у вас уже был правильный синтаксис для Image, но он не перенесен на другие элементы. Итак, чтобы сделать это конкретным, чтобы построить изображение, вы должны сделать:

img = gv.Image((xx, yy, zz.T), crs=ccrs.UTM(zone='33N'))

Однако, поскольку у вас есть массивы 2D-координат, а не 1D-координаты, которые ожидает изображение (в следующем выпуске это будет ошибка), у вас фактически есть QuadMesh, который создается таким же образом:

qmesh = gv.QuadMesh((xx, yy, zz.T), crs=ccrs.UTM(zone='33N'))

То же самое и с geoviews FilledContours:

contours = gv.FilledContours((xx, yy, zz.T), crs=ccrs.UTM(zone='33N'))

Подводя итог, можно сказать, что разница между элементами HoloViews и вызовами matplotlib заключается в том, что HoloViews представляет собой легкую оболочку вокруг ваших данных, которая позволяет вам придавать семантическое значение каждой координате и массиву значений, назначая их измерению ключа или значения, в то время как matplotlib делает это сопоставление более сложным. явный.

HoloViews понимает ряд форматов для определения данных с координатной привязкой, подобных вашему, самый простой - это кортеж массивов x / y-координат и массив значений, он также понимает объекты xarray и словари различных массивов, которые будут выглядеть следующим образом:

contours = gv.FilledContours({'x': xx, 'y': yy, 'z': zz.T}, ['x', 'y'], 'z', crs=ccrs.UTM(zone='33N'))

В этом формате мы можем явно видеть, как массивы координат «x» и «y» сопоставляются с ключевыми измерениями, а массив значений «z» - с измерениями значений.

person philippjfr    schedule 01.03.2019
comment
Спасибо! Так что мой обход набора данных xarray был действительно бесполезен. Предложенный вами код работает, однако мне пришлось переставить 2D-координаты x и y, иначе изображение выглядело перевернутым: contours = gv.FilledContours((xx.T, yy.T, zz.T), crs=ccrs.UTM(zone='33N')) - person Alex; 01.03.2019
comment
Тогда может быть проще отменить транспонирование вашего zz, т.е. gv.FilledContours((xx, yy, zz), crs=ccrs.UTM(zone='33N')) - person philippjfr; 01.03.2019
comment
Ух .. Мне действительно нужно задуматься! Большое спасибо. Очень доволен результатами, click, библиотека pyviz просто потрясающая. - person Alex; 02.03.2019