【问题标题】:datashader xarray.Image to holoviews Pointsdatashader xarray.Image 到 holoviews 点
【发布时间】:2020-02-02 23:37:08
【问题描述】:

这是代码:

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() 函数在地图上绘制点。但是,我想在将数据绘制在地图上之前对数据进行一些转换。我尝试使用 datashader 中已有的功能,但我无法弄清楚如何将 datashader 创建的 xarray.Image 对象转换为可以绘制在地图图块顶部的全息视图 Point 对象。

编辑

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

我尝试在退化的情况下执行以下操作:

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'

【问题讨论】:

    标签: python holoviews datashader


    【解决方案1】:

    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 操作(datashadespreadrasterize 等)或定义自定义 HoloViews 操作来封装您想要执行的处理(其中可以包括手动调用Datashader API(如果需要)并允许在每次用户平移或缩放时动态应用处理。

    【讨论】:

    • 非常感谢您的回复,真的很有帮助!你能否给我一些关于如何在这一行中实现聚合的指示:img = tf.shade(agg.where(agg['x']&gt;0), cmap=fire) 通过使用 HoloViews 操作?
    • 我不认为我们有这样的例子,但我们应该。一些起点是holoviews.org/user_guide/…,更具体地说是holoviews.org/user_guide/…。具体来说,编写一个自定义操作,获取rasterize() 的输出并实现一个类似agg = element.data; element.data = agg.where(agg['x']&gt;0) 的_process() 方法。
    • 如果您尝试过并且效果很好,请考虑提交 PR,将该示例添加到 holoviews.org/user_guide/Large_Data.html 文档中。如果您有问题,请告诉我,我可以自己举一个这样的例子。
    • 请参阅我编辑的帖子以了解我的尝试。我无法在 cmets 中正确设置代码格式。
    • 我很乐意帮助调试它,但您首先必须对其进行编辑才能运行;只需添加一些合成(随机等)点,而不是调用读取 CSV。
    猜你喜欢
    • 2017-11-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-17
    • 2019-10-22
    相关资源
    最近更新 更多