Bokeh-Holoviews-Datashader:流式数据曲线无法更新坐标轴范围
解决方案
方法1:使用dynamic=True参数(推荐)
datashade的dynamic=True参数会自动管理PlotSize和RangeXY流,同时在数据更新时自动适配轴范围,无需手动添加流:
修改datashade调用部分:
ds = datashade(hv.DynamicMap(hv.Curve, streams=[self.buf]), dynamic=True).opts( min_height=400, max_height=600, tools=["save, undo, redo"], responsive=True, active_tools=['box_zoom'])
这是官方推荐的方式,既保证缩放时着色图像实时更新,又能在Buffer推送新数据时自动调整轴范围匹配新数据。
方法2:手动更新RangeXY流范围
如果需要保留手动添加流的方式,可以在更新数据后,手动计算新数据的范围并更新RangeXY流:
修改Dashboard类代码:
class Dashboard: def __init__(self): arr = np.vstack([np.arange(100), np.random.random(100)]).T self.buf = Buffer(data=arr, length=100) self.dynamic_curve = hv.DynamicMap(hv.Curve, streams=[self.buf]) # 保存datashade对象和RangeXY流引用 self.ds = datashade(self.dynamic_curve, streams=[hv.streams.PlotSize, hv.streams.RangeXY]).opts( min_height=400, max_height=600, tools=["save, undo, redo"], responsive=True, active_tools=['box_zoom']) self.range_stream = next(s for s in self.ds.streams if isinstance(s, hv.streams.RangeXY)) self.button = pn.widgets.Button(name='Next buffer', button_type='primary', margin=(22, 10, 10, 10)) self.button.on_click(self.update_data) self.col = pn.Column(self.ds, self.button) self.iter = 1 def update_data(self, event): arr = np.vstack([np.arange(100), np.random.random(100)]).T new_data = arr + self.iter self.buf.send(new_data) # 计算新数据的轴范围 x_min, x_max = new_data[:,0].min(), new_data[:,0].max() y_min, y_max = new_data[:,1].min(), new_data[:,1].max() # 更新RangeXY流,触发datashade重新渲染 self.range_stream.update(x_range=(x_min, x_max), y_range=(y_min, y_max)) self.iter += 1
原理说明
- 添加
RangeXY流后,datashade会固定使用当前的轴范围渲染,Buffer更新数据时不会自动触发范围重计算。 dynamic=True会让Holoviews自动监听数据变化和轴范围变化,同时处理两种场景下的渲染更新。- 手动更新方式通过主动修改
RangeXY流的范围值,强制datashade根据新数据的范围重新绘制图像,同时保留缩放交互的响应性。
内容的提问来源于stack exchange,提问作者Cunningham
相关产品推荐
相关产品推荐

