如何在Bokeh/HoloViews+Datashader中禁用无限缩放
用HoloViews Datashader结合Bokeh时限制缩放级别
我在处理千万级数据时,必须使用HoloViews的Datashader来渲染,但遇到了无法限制图表缩放最小/最大级别的问题。不使用Datashader时,通过Bokeh的Range设置可以正常限制缩放,但用rasterize操作后,所有x_range相关参数都被忽略,图表仍能无限放大或缩小。
基础环境代码:
import bokeh import datashader as ds import holoviews as hv from holoviews import opts from holoviews.operation.datashader import datashade, shade, dynspread, spread, rasterize hv.extension('bokeh')
模拟千万级数据:
import numpy as np import pandas as pd N = int(10e6) x_r = (0,100) y_r = (100,2000) z_r = (0,10e8) x = np.random.randint(x_r[0]*1000,x_r[1]*1000,size=(N, 1)) y = np.random.randint(y_r[0]*1000,y_r[1]*1000,size=(N, 1)) z = np.random.randint(z_r[0]*1000,z_r[1]*1000,size=(N, 1)) z2 = np.ones((N,1)).astype(int) df = pd.DataFrame(np.column_stack([x,y,z,z2]), columns=['x','y','z','z2']) df[['x','y','z']] = df[['x','y','z']].div(1000, axis=0)
原Datashader渲染代码(无法限制缩放):
from matplotlib.cm import get_cmap palette = get_cmap('viridis') p=hv.Points(df,['x','y'], ['z','z2']) P=rasterize(p, aggregator=ds.sum("z2"),x_range=(0,100)).opts(cmap=palette) P.opts(tools=["hover"]).opts(height=500, width=500,xlim=(0,100),ylim=(100,2000))
解决方案
要限制缩放级别,需要直接配置Bokeh的Range1d对象,设置min_interval(最小缩放区间,即放大的极限)和max_interval(最大缩放区间,即缩小的极限),然后通过HoloViews的opts将其绑定到图表的x/y轴范围上。
修改后的代码:
from matplotlib.cm import get_cmap from bokeh.models import Range1d palette = get_cmap('viridis') p=hv.Points(df,['x','y'], ['z','z2']) # 配置x轴范围:初始0-100,最小缩放区间1,最大缩放区间100(不能缩小到超过初始范围) x_range = Range1d(start=0, end=100, min_interval=1, max_interval=100) # 配置y轴范围:初始100-2000,最小缩放区间10,最大缩放区间1900 y_range = Range1d(start=100, end=2000, min_interval=10, max_interval=1900) P=rasterize(p, aggregator=ds.sum("z2")).opts(cmap=palette) P.opts( tools=["hover"], height=500, width=500, x_range=x_range, y_range=y_range )
说明
min_interval:设置轴上允许的最小区间长度,比如x轴设为1,意味着放大时x轴范围不能小于1(无法再放大);max_interval:设置轴上允许的最大区间长度,比如x轴设为100,意味着缩小不能超过初始的0-100范围(无法再缩小到显示更多内容);- 不需要在
rasterize中传入x_range参数,而是通过opts绑定Bokeh的Range对象来实现缩放限制。
内容的提问来源于stack exchange,提问作者mths
相关产品推荐
相关产品推荐

