【问题标题】:How to resize of bins/pixels when zooming缩放时如何调整箱/像素的大小
【发布时间】:2020-02-29 20:28:13
【问题描述】:

我目前正在尝试在数据着色器和散景的帮助下将数据集(柏林公共交通站点)投影到地图瓷砖上。在一定程度上它运行良好,但仍然存在三个问题:

  1. 放大数据时,像素仍然相当大,并且 未重新排列 - 怎么做?
  2. 如何让投影数据半透明仍能看到下面的地图?
  3. 散景工具栏的“保存”功能消失了,因为地图图块已合并。如何找回?

感谢您的任何意见!

编写的(远非完美的)代码:

import numpy as np
import pandas as pd
import geopandas as gp
import datashader as ds
import datashader.transfer_functions as tf
from datashader.utils import export_image
from datashader.utils import lnglat_to_meters as webm
from datashader.colors import Hot
import dask.dataframe as dd
import multiprocessing as mp
from functools import partial
from IPython.core.display import HTML, display
import matplotlib.pyplot as plt
import holoviews as hv
from holoviews.operation.datashader import datashade, dynspread
hv.extension("bokeh", "matplotlib")
from bokeh.io import output_file, output_notebook, show
from bokeh.plotting import figure, show
from holoviews import dim, opts
import geoviews as gv
from colorcet import palette, fire

#get official data of bus/subway stops in Berlin
# -> https://www.vbb.de/media/download/2035
#read data
df = pd.read_csv('UMBW.CSV', engine= 'python', sep=';', usecols=['Y-Koordinate', 'X-Koordinate'])

##some formatting
##replace comma by point
df = df.apply(lambda x: x.str.replace(',','.'))
#delete rows witn NaN -> pandas.DataFrame.dropna
df = df.dropna()
#entries were objects - need to convert to floats
df['X-Koordinate']=pd.to_numeric(df['X-Koordinate'])
df['Y-Koordinate']=pd.to_numeric(df['Y-Koordinate'])

# Project longitude and latitude onto web mercator plane.
df.loc[:, 'easting'], df.loc[:, 'northing'] = webm(df['X-Koordinate'],df['Y-Koordinate'])

# Getting range/box of latitude and longitude for plotting later.
# drop the points lying on the border
y_range_min = df['Y-Koordinate'].quantile(0.01)
y_range_max = df['Y-Koordinate'].quantile(0.99)
x_range_min = df['X-Koordinate'].quantile(0.01)
x_range_max = df['X-Koordinate'].quantile(0.99)

#cornerspots for canvas
sw = webm(x_range_min,y_range_min)#southwest
ne = webm(x_range_max,y_range_max)#northeast
SF = zip(sw, ne)

dask_df = dd.from_pandas(df, npartitions=mp.cpu_count())
dask_df = dask_df.compute()

display(HTML("<style>.container { width:100% !important; }</style>"))

plot_width = int(3600)
plot_height = int(3600)
cvs = ds.Canvas(plot_width, plot_height, *SF)
agg = cvs.points(dask_df, 'easting', 'northing')

#dynamic map tiles -> https://wiki.openstreetmap.org/wiki/Tile_servers
#url="http://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{Z}/{Y}/{X}.png"
url="https://a.tile.openstreetmap.org/{Z}/{X}/{Y}.png"
geomap = gv.WMTS(url)

#manipulate pixelsize for zoom
dynspread.max_px=1
dynspread.threshold=0.1

points = hv.Points(gv.Dataset(dask_df, kdims=['easting', 'northing']))
bvg_stops = dynspread(datashade(points, cmap=Hot).opts(height=640,width=640))
fig = geomap * bvg_stops
hv.save(fig, 'berlin.html', backend='bokeh')

初始散景图的示例输出和放大版本(科特布斯市周围)。

【问题讨论】:

    标签: python zooming bokeh holoviews datashader


    【解决方案1】:
    1. “当放大数据时,像素仍然很大并且没有重新排列 - 如何做到这一点?”

      Datashader 是一个 Python 程序,当给定数据结构时,它会生成一个光栅化值数组。在这里,它根据请求呈现您的数据,然后您使用hv.save 将其输出保存到 HTML 文件中。一旦你这样做了,你将拥有一个永远不会更新的数字。您将放大 HTML 页面,导致浏览器的 JavaScript 代码向 Python 请求更新,但 Python 未运行并且无法响应更新图形的请求。如果您想将可缩放的图像导出为 HTML,则需要使用 datashade(..., dynamic=False, height=4000, width=4000) 之类的东西指定更高的初始分辨率(这会产生很大的文件大小并且最初可能看起来不太好,但可以进行一定程度的缩放),或者以多种不同的分辨率生成一整套数据图块(由 Datashader 支持,但还没有很好的文档记录),或者(为了充分利用)使用 Bokeh 服务器提供 Python 进程来伴随 HTML/JavaScript 代码。即,或者最初生成更多数据,预先生成所有数据组合,或者提供可以按需重新生成它们的服务器。如果没有其中一种方法,您不应该期望在初始渲染之外还有任何可用数据。

    2. 如何让投影数据半透明仍能看到下面的地图?

      bvg_stops.opts(alpha=0.5)。您还可以考虑使用 Panel.pyviz.org 为地图和数据添加一些不透明度小部件,以便您以交互方式打开和关闭它们;有关示例,请参见 examples.pyviz.org。

    3. 散景工具栏的“保存”功能消失了,因为地图图块被合并了。怎么找回来?

      不幸的是,这是由浏览器的安全模型造成的限制,而 Bokeh 或此处的任何其他工具都无法覆盖。地图图块来自单独的服务器,浏览器禁止导出此类“跨域”内容以避免某些安全问题 (Can't Save Bokeh Plot with Panel from PyViz Example)。

    【讨论】:

    • 非常感谢这些详细的回答。我肯定会更深入地研究 Bokeh 服务器。顺便说一句,Datashader 是一个很棒的图形系统!
    猜你喜欢
    • 2023-01-26
    • 2021-05-20
    • 1970-01-01
    • 1970-01-01
    • 2015-12-27
    • 2012-02-02
    • 1970-01-01
    • 2016-06-01
    • 2014-10-29
    相关资源
    最近更新 更多