datashader xarray.Image к holoviews Очки - PullRequest
0 голосов
/ 04 октября 2019

Это код:

import datashader as ds
import pandas as pd
from colorcet import fire
from datashader import transfer_functions as tf
from datashader.utils import lnglat_to_meters
import holoviews as hv
import geoviews as gv
from holoviews.operation.datashader import datashade, spread, aggregate
hv.extension('bokeh')  

df = pd.read_csv('...')

agg = ds.Canvas().points(df, 'x', 'y', agg=ds.count())
img = tf.shade(agg.where(agg['x']>0), cmap=fire)

url = 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{Z}/{Y}/{X}.jpg'
tile_opts = dict(width=1000,height=600,xaxis=None,yaxis=None,show_grid=False,bgcolor='black')
map_tiles = gv.WMTS(url).opts(style=dict(alpha=1.0), plot=tile_opts)
points = hv.Points(df, ['x', 'y'])
#points = img    # <-- Using this does not work
ds_points = spread(datashade(points, width=1000, height=600, cmap=fire), px=2)

map_tiles * ds_points

Приведенный выше код создает объект holoviews Points на основе данных из фрейма данных pandas и использует функции spread() и datashade() в holoviews для построения точекна карте. Тем не менее, я хочу сделать некоторые преобразования в данных, прежде чем я нанесу их на карту. Я пытался использовать функциональность, уже доступную в datashader, но не могу понять, как я могу преобразовать объект xarray.Image, созданный datashader, в объект holoviews Point, который можно нанести поверх плиток карты.

РЕДАКТИРОВАТЬ

Я не могу правильно отформатировать код в комментариях, поэтому просто добавлю его сюда.

Я попытался сделать следующеев качестве вырожденного случая:

from custom_operation import CustomOperation
points = hv.Points(df, ['x', 'y'])
CustomOperation(rasterize(points))

, где CustomOperation определяется как:

from holoviews.operation import Operation

class CustomOperation(Operation):
    def _process(self, element, key=None):
        return element

Это приводит к следующей ошибке:

AttributeError: 'Image' object has no attribute 'get'

1 Ответ

1 голос
/ 04 октября 2019

Объект Image, созданный Datashader, представляет собой обычную сетку / массив значений, которая объединяет исходные точки по бинам, поэтому восстановить исходные точки больше невозможно. Было бы бессмысленно использовать объект точек HoloViews для этих уже 2D-гистограммированных данных;объект Points ожидает набор отдельных точек, а не двумерный массив. Вместо этого вы можете использовать объект изображения HoloViews, который принимает двухмерный массив, подобный массиву, сгенерированному Datashader. Синтаксис будет примерно таким: hv.Image(img), хотя я не могу проверить его с помощью приведенного выше кода, потому что он не работает без файла CSV.

Обратите внимание, что если вы воспользуетесь этим подходом, то произойдет, что Datashaderотобразит точки в сетке фиксированного размера, а затем HoloViews наложит эту конкретную сетку значений на карту. Даже если вы увеличите или панорамируете, вы все равно увидите ту же сетку;он никогда не обновится, чтобы показать подмножество данных с более высоким разрешением, как ваш текущий код, потому что все вычисления Datashader будут завершены и предоставят вам фиксированный массив, прежде чем вы начнете строить что-либо с помощью HoloViews или Bokeh. Если вы хотите динамическое масштабирование и обновление, не используйте API Datashader (Canvas, .points, tf.shade и т. Д.) Отдельно;вам нужно будет использовать либо уже используемые вами операции HoloViews (datashade, spread, rasterize и т. д.), либо определить собственную операцию HoloViews для инкапсуляции обработки, которую вы хотите выполнить (которая может включать в себя вызов вручнуюAPI Datashader, если необходимо) и позволяет динамически применять обработку при каждом панорамировании или увеличении масштаба.

...