首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Geoview+ Datashader在投影点时速度慢

Geoview+ Datashader在投影点时速度慢
EN

Stack Overflow用户
提问于 2018-11-29 17:38:28
回答 1查看 1.2K关注 0票数 3

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

下面有一个可重复的例子,但简而言之,我试图使地理视图实现(3)足够快,以交互的方式工作。

首先设置一些数据

代码语言:javascript
复制
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。

代码语言:javascript
复制
uk_bounding_box = (-14.02,2.09,49.67,61.06)
n = int(550000000 / 10)

# Generate some fake data of the same size
df = dd.from_pandas(
    pd.DataFrame.from_dict({
        'longitude': np.random.normal(
            np.mean(uk_bounding_box[0:2]),
            np.diff(uk_bounding_box[0:2]) / 5, n
        ),
        'latitude': np.random.normal(
            np.mean(uk_bounding_box[2:4]),
            np.diff(uk_bounding_box[2:4]) / 5, n
        )
    }), npartitions=8
)

# Persist data in memory so reading wont slow down datashader
df = df.persist()

(1)数据处理

仅仅使用没有全息视图或geo的数据哈德是非常快的-输出在4秒内呈现,包括聚合,所以如果交互的话,重新呈现将会更快。

代码语言:javascript
复制
# 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 

纯数据增强版本的时间:

代码语言:javascript
复制
%%time
cvs = ds.Canvas(plot_width=plot_width, plot_height=plot_height, **bounds)
agg = cvs.points(df, 'longitude', 'latitude', ds.count())

CPU时间:用户968 ms,sys: 29.9 ms,总计: 998 ms,Wall time: 506 ms

代码语言:javascript
复制
tf.shade(agg)

(2)无datashader投影的holoviews中的geoviews

代码语言:javascript
复制
# 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进行比较。

代码语言:javascript
复制
%%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 ms,sys: 131 ms,总计: 3.45 ms墙壁时间: 3.47 ms

代码语言:javascript
复制
shader

(3) datashaderholoviews中具有geoviews块、多边形和投影

这是问题的症结所在--我想要对齐数据哈德层和一些地图块和地理空间多边形。这导致了一个大的减速,就我所处理的数据的大小而言,这使得交互式可视化变得多余。(渲染的等待时间总计为12分钟)。

我确信这与投影点相关的开销有关--有什么方法可以避免这种情况或任何其他解决办法,比如预计算投影吗?

代码语言:javascript
复制
# 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()和投影一样。

代码语言:javascript
复制
%%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秒,sys: 3.16秒,总计:15s墙壁时间: 12.5秒

代码语言:javascript
复制
shader * map_tiles * polys

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-11-30 16:32:28

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

就像这样:

代码语言:javascript
复制
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一起使用,详细说明。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53544693

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档