Geoviews+Datashader在投影点时速度较慢

2024-06-16 11:15:01 发布

您现在位置:Python中文网/ 问答频道 /正文

我用datashader绘制了550000000个纬度和经度。但是,为了使其有用,我需要使用geoviews覆盖地图分幅和多边形。问题是geoviews.points()和相关的投影会导致很大的减速,这使得holoview+bokeh图的交互性质变得多余。在

下面有一个可复制的例子,但是,简而言之,我正在努力使geoviews实现(3)足够快,以交互方式工作。在

首先设置一些数据

import numpy as np
import pandas as pd
import dask.dataframe as dd
import datashader as ds
import datashader.transfer_functions as tf
import holoviews as hv 
from holoviews.operation.datashader import datashade
import geopandas as gpd
import geoviews as gv

例如,将数据的大小缩小10。在

^{pr2}$

(1) 只是数据阴影

仅仅使用没有全息视图或地理信息的datashader是非常快的-输出是在4秒钟内呈现的,包括聚合,所以如果是交互式的,重新渲染会更快。在

# Set some plotting params
bounds = dict(x_range = uk_bounding_box[0:2],
              y_range = uk_bounding_box[2:4])
plot_width = 400
plot_height = 300 

纯datashader版本的时间:

%%time
cvs = ds.Canvas(plot_width=plot_width, plot_height=plot_height, **bounds)
agg = cvs.points(df, 'longitude', 'latitude', ds.count())

CPU时间:用户968毫秒,系统:29.9毫秒,总计:998毫秒 壁厚:506ms

tf.shade(agg)

just data shader

(2) datashader中没有geoviews投影

# Set some params
sizes = dict(width=plot_width, height=plot_height)
opts = dict(bgcolor="black", **sizes)

hv.extension('bokeh')

hv.util.opts('Image Curve RGB Polygons [width=400 height=300 shared_axes=False] {+axiswise} ')

没有任何投影,这相当于使用纯datashader

%%time
points = hv.Points(df, ['longitude', 'latitude']).redim.range(
    x=bounds['x_range'], y=bounds['y_range'])

shader = datashade(points, precompute=True ,**sizes).options(**opts)

CPU时间:用户3.32毫秒,系统:131微秒,总计:3.45毫秒 壁厚:3.47 ms

shader

holoviews render

(3) datashaderholoviews中,具有geoviews平铺、多边形和投影

这是问题的症结-我想对齐,数据阴影层与一些地图平铺和地理空间多边形。这导致了一个巨大的减速,对于我正在处理的数据量来说,这使得交互式可视化变得多余。(渲染总共等待12分钟)。在

我确信这是与投影点相关的开销有关的-有没有一种方法可以避免这种情况或任何其他的解决方法,如预先计算投影?在

# Grab an example shape file to work with
ne_path = gpd.datasets.get_path('naturalearth_lowres')
example_shapes_df = gpd.read_file(ne_path)
uk_shape = example_shapes_df[example_shapes_df.name.str.contains('United K')]


# Grab maptiles
map_tiles = gv.tile_sources.ESRI

# In actual workflow I need to add some polygons
polys = gv.Polygons(uk_shape)

这与上面添加了gv.points()和投影一样

%%time 
points = gv.Points(df, ['longitude', 'latitude']).redim.range(
    x=bounds['x_range'], y=bounds['y_range'])

projected = gv.operation.project_points(points)

shader = datashade(projected, precompute=True ,**sizes).options(**opts)

CPU时间:用户11.8秒,系统:3.16秒,总计:15秒 壁厚:12.5s

shader * map_tiles * polys

geoviews render


Tags: 数据importdfplotasrangewidthpoints
1条回答
网友
1楼 · 发布于 2024-06-16 11:15:01

根据@philippjfr的建议,解决方案是将坐标投影到适当的坐标系中,并使用上述方法2或3进行渲染。在

像这样:

import cartopy

def platcaree_to_mercator_vectorised(x, y):
    '''Use cartopy to convert Platecarree coords to Mercator.'''
    return(cartopy.crs.GOOGLE_MERCATOR.transform_points(
        cartopy.crs.PlateCarree(), x, y))

def platcaree_for_map_partitions(pddf):
    '''Wrapper to apply mercator conversion and convert back to dataframe for Dask.'''
    as_arrays = platcaree_to_mercator_vectorised(pddf.longitude.values,pddf.latitude.values)
    as_df = pd.DataFrame.from_records(as_arrays[:, :2], columns=['longitude', 'latitude'])
    return(as_df)


# Project the points
df_projected = df.map_partitions(platcaree_for_map_partitions,
                                 meta={'longitude': 'f8', 'latitude': 'f8'})
from dask.diagnostics import ProgressBar
with ProgressBar():
    df_projected.to_parquet('abb_projected.parquet', compression='SNAPPY')

在问题2或3中使用投影数据集。在

相关问题 更多 >