Bokeh热图中如何基于circle的value2值创建大小图例?
在Bokeh中实现圆形大小图例的方法
好问题!在Bokeh里确实没有直接内置的「大小图例」组件,但我们可以手动构建一组参考圆形来模拟这个效果,完全能满足你的热图场景需求。下面是具体的实现思路和代码示例:
核心思路
我们通过创建一组带有明确数值标签的参考圆形,将它们放置在主图的侧边(比如和color_bar相邻的位置),以此来直观展示value2数值和圆形大小的对应关系。
完整代码示例
假设你已经有了基础的热图代码,我们在此基础上添加大小图例:
from bokeh.plotting import figure, show from bokeh.models import ColumnDataSource, LinearColorMapper, ColorBar, Range1d import pandas as pd # 模拟你的DataFrame数据(替换成你实际的数据) data = { 'categories': ['CatA', 'CatA', 'CatB', 'CatB', 'CatC', 'CatC'], 'Species': ['Sp1', 'Sp2', 'Sp1', 'Sp2', 'Sp1', 'Sp2'], 'value1': [10, 20, 30, 40, 50, 60], 'value2': [15, 30, 45, 60, 75, 90] } df = pd.DataFrame(data) # ---------------------- 主热图部分(你已实现的代码) ---------------------- # 配置value1的颜色映射 color_mapper = LinearColorMapper(palette="Viridis256", low=df['value1'].min(), high=df['value1'].max()) # 创建主图对象 p = figure( x_range=df['categories'].unique(), y_range=df['Species'].unique(), toolbar_location=None, tools="hover", tooltips=[("Value1", "@value1"), ("Value2", "@value2")], title="Categories vs Species Heatmap" ) # 绘制核心圆形热图 p.circle( x='categories', y='Species', size='value2', # 用value2控制大小 color={'field': 'value1', 'transform': color_mapper}, # 用value1控制颜色 source=df, alpha=0.8 ) # 添加value1的颜色条 color_bar = ColorBar( color_mapper=color_mapper, label_standoff=12, location=(0,0), title="Value1" ) p.add_layout(color_bar, 'right') # ---------------------- 添加value2的大小图例 ---------------------- # 1. 选择value2的关键刻度值(比如最小值、中位数、最大值,也可以自定义分位数) size_ticks = [df['value2'].min(), df['value2'].median(), df['value2'].max()] # 2. 构建图例数据源:定义参考圆形的位置、大小和标签 # 这里把图例放在主图X轴右侧的空白区域,位置可以根据你的图调整 legend_data = { 'x': [len(df['categories'].unique()) + 0.6] * len(size_ticks), 'y': [1.6, 0.5, -0.6], # 垂直排列的位置,对应Y轴的Species范围 'size': size_ticks, 'label': [f"Value2: {tick}" for tick in size_ticks] } legend_source = ColumnDataSource(legend_data) # 3. 添加参考圆形和标签文本 p.circle(x='x', y='y', size='size', color='gray', source=legend_source, alpha=0.9) p.text( x='x', y='y', text='label', text_align='left', text_baseline='middle', source=legend_source, x_offset=12, text_font_size='10pt' ) # 4. 调整X轴范围,给图例留出足够空间 p.x_range = Range1d(-0.5, len(df['categories'].unique()) + 1.2) # 显示最终图形 show(p)
关键细节说明
- 刻度值选择:你可以根据
value2的分布调整刻度值,比如如果数值跨度大,用对数刻度或者分位数(如25%、50%、75%分位数)会更合理。 - 位置调整:如果你的Y轴物种数量更多,需要对应调整
legend_data里的y值,保证所有参考圆形都能显示在图内。 - 缩放适配:如果你的
value2是经过缩放(比如用LinearInterpolator映射到10-100的像素大小),那么图例里的size也要用同样的缩放逻辑,确保大小对应关系准确。 - 样式优化:你可以给图例添加标题(用
p.text添加固定文本)、调整圆形颜色和透明度,让它和主图风格更统一。
内容的提问来源于stack exchange,提问作者Corsair
相关产品推荐
相关产品推荐

