datashader xarray.Image 到 holoviews 点

datashader xarray.Image to holoviews Points

这是代码:

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

以上代码基于来自 pandas 数据帧的数据创建了一个全息视图 Points 对象,并使用全息视图中的 spread()datashade() 函数在地图。但是,我想在将数据绘制在地图上之前对数据进行一些转换。我尝试使用数据着色器中已有的功能,但我无法弄清楚如何将数据着色器创建的 xarray.Image 对象转换为可以绘制在顶部的全息视图 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'

Datashader创建的Image对象是一个正则的grid/array值,将原始点按bin聚合,因此无法再恢复原始点。在这个已经是 2D 直方图的数据上使用 HoloViews Points 对象是没有意义的; Points 对象需要一组单独的点,而不是二维数组。相反,您可以使用 HoloViews Image 对象,它接受像 Datashader 生成的二维数组。语法类似于 hv.Image(img),但我无法使用上面的代码对其进行测试,因为没有 CSV 文件它无法运行。

请注意,如果采用这种方法,Datashader 会将点渲染到固定大小的网格中,然后 HoloViews 会将特定的值网格覆盖到地图上。即使放大或平移,您仍然会看到相同的网格;它永远不会像您当前的代码那样更新以显示更高分辨率的数据子集,因为在您开始使用 HoloViews 或 Bokeh 绘制任何内容之前,Datashader 计算将全部完成并为您提供一个固定的数组。如果要动态缩放和更新,请不要单独使用Datashader API(Canvas.pointstf.shade等);您需要使用您已经在使用的 HoloViews 操作(datashadespreadrasterize 等)或定义自定义 HoloViews 操作来封装您想要执行的处理(如果需要,可以包括手动调用 Datashader API)并允许在用户每次平移或缩放时动态应用处理。