3

を使用して 5 億 5000 万の緯度と経度をプロットしてdatashaderいます。しかし、これを有効にするには、 を使用してマップ タイルとポリゴンをオーバーレイする必要があります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 ずつ縮小します。

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) データシェーダーのみ

ホロビューやジオを使用せずにデータシェーダーを使用するだけでも非常に高速です。出力は集計を含めて 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 

純粋なデータシェーダー バージョンの時間:

%%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 ミリ秒 壁時間: 506 ミリ秒

tf.shade(agg)

ただのデータシェーダー

(2) 突起なしdatashaderholoviewsgeoviews

# 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 ミリ秒、sys: 131 µs、合計: 3.45 ミリ秒 壁時間: 3.47 ミリ秒

shader

ホロビューのレンダリング

(3)タイルdatashader、ポリゴン、プロジェクションholoviewsgeoviews

問題の要点は次のとおりです。データシェーダー レイヤーをいくつかのマップ タイルと地理空間ポリゴンに合わせたいと思います。これにより、私が扱っているデータのサイズが大きく遅くなり、インタラクティブな視覚化が冗長になります。(レンダリングの合計待機時間は 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.5 秒

shader * map_tiles * polys

geoviews レンダー

4

1 に答える 1