如何在Python的Bokeh中为Datashader绘图叠加线条?
在Datashader可视化结果上叠加统计线条的实现方法
你当前的代码混用了Bokeh figure 和 HoloViews/Datashader 对象,两者无法直接兼容,可通过以下两种方式实现叠加:
方法一:基于HoloViews实现(推荐,更简洁)
利用HoloViews的叠加机制,将Datashader渲染的点图与统计曲线直接组合:
步骤1:导入依赖库并计算统计数据
import pandas as pd import holoviews as hv from holoviews.operation.datashader import datashade from bokeh.io import show hv.extension('bokeh') x = 'xcol' y = 'ycol' data = dataframe # 按x列分组计算y的均值、标准差,以及均值±标准差 stats = data.groupby(x)[y].agg(['mean', 'std']).reset_index() stats['mean_plus_std'] = stats['mean'] + stats['std'] stats['mean_minus_std'] = stats['mean'] - stats['std']
步骤2:生成可视化元素并叠加
# 生成Datashader渲染的高密度点图 points = hv.Points(data, [x, y], label='原始数据') shaded_points = datashade(points, cmap='crest') # 生成均值、标准差曲线 mean_line = hv.Curve(stats, x, 'mean', label='均值').opts(line_width=3, color='red') upper_std_line = hv.Curve(stats, x, 'mean_plus_std', label='均值+标准差').opts(line_width=2, color='orange', dash_pattern='dashed') lower_std_line = hv.Curve(stats, x, 'mean_minus_std', label='均值-标准差').opts(line_width=2, color='orange', dash_pattern='dashed') # 叠加所有可视化元素 final_plot = shaded_points * mean_line * upper_std_line * lower_std_line # 渲染并展示 show(hv.render(final_plot))
方法二:直接基于Bokeh+Datashader实现
如果更习惯Bokeh的原生API,可以将Datashader渲染结果嵌入Bokeh figure 后再添加线条:
from bokeh.plotting import figure, show import datashader as ds from datashader.bokeh_ext import InteractiveImage x = 'xcol' y = 'ycol' data = dataframe # 创建Bokeh画布 fig = figure(x_axis_label=x, y_axis_label=y) # 将Datashader渲染的动态图像绑定到Bokeh画布 def render_datashader(x_range, y_range): canvas = ds.Canvas(x_range=x_range, y_range=y_range) agg = canvas.points(data, x, y) shaded_img = ds.tf.shade(agg, cmap='crest') return ds.tf.dynspread(shaded_img) InteractiveImage(fig, render_datashader) # 计算统计数据并添加线条 stats = data.groupby(x)[y].agg(['mean', 'std']).reset_index() stats['mean_plus_std'] = stats['mean'] + stats['std'] stats['mean_minus_std'] = stats['mean'] - stats['std'] fig.line(stats[x], stats['mean'], line_width=3, color='red', legend_label='均值') fig.line(stats[x], stats['mean_plus_std'], line_width=2, color='orange', line_dash='dashed', legend_label='均值+标准差') fig.line(stats[x], stats['mean_minus_std'], line_width=2, color='orange', line_dash='dashed', legend_label='均值-标准差') # 展示最终图 show(fig)
注意事项
- 如果x是连续数值型,建议先对x进行分箱(比如用
pd.cut)再分组计算统计值,避免分组后x值过多导致曲线不流畅。 dynspread函数用于优化高密度点的显示,可根据需求调整参数或移除。
内容的提问来源于stack exchange,提问作者Koen van Beveren
相关产品推荐
相关产品推荐

