1

这是代码:

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

Points上面的代码基于 pandas 数据帧中的数据创建了一个 holoviews对象,并在 holoviews 中使用spread()datashade()函数在地图上绘制点。但是,我想在将数据绘制在地图上之前对数据进行一些转换。我尝试使用 datashader 中已有的功能,但我无法弄清楚如何将xarray.Imagedatashader 创建的对象转换为Point可以绘制在地图图块顶部的 holoviews 对象。

编辑

我无法在注释中正确格式化代码,所以我将其放在这里。

我尝试将以下作为退化案例:

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'

4

1 回答 1

2

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

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

于 2019-10-04T19:17:14.110 回答