Bokeh 3.3.0版本下为线性图表添加对数刻度副X轴散点图的实现问题
Bokeh 3.3.0版本下为线性图表添加对数刻度副X轴散点图的实现问题
嗨,我来帮你搞定这个双X轴的需求!你想要在现有的线性主X轴图表上,叠加一个对数刻度的副X轴来绘制散点图对吧?我结合你的代码片段,整理了完整的实现方案,一步步来给你讲清楚:
1. 导入依赖并准备数据
先把需要的库导入,然后补全并整理好数据集,确保有对应主线性轴和副对数轴的两类数据:
import pandas as pd from bokeh.plotting import figure, show, ColumnDataSource from bokeh.models import LogAxis, Range1d # 完善示例数据集,包含时间、UTCs、海拔以及两类对应不同X轴的数据 df = pd.DataFrame({ 'time': ['2024-06-21 06:22:38', '2024-06-21 06:23:38', '2024-06-21 06:24:38', '2024-06-21 06:25:38'], 'UTCs': [605.9683, 606.9683, 607.9683, 608.9683], 'altitude': [1000, 2000, 3000, 4000], 'linear_data': [15, 25, 35, 45], # 对应主线性X轴的数据集 'log_data': [10, 100, 1000, 10000] # 对应副对数X轴的数据集 }) # 把时间字段转成datetime类型,方便Bokeh处理时间轴 df['time'] = pd.to_datetime(df['time'])
2. 创建主线性X轴图表
先画出你的主图,这里假设主X轴是时间(线性刻度),如果你的主X轴是UTCs这类数值型线性轴,只需要调整x_axis_type即可:
# 创建主图,主X轴用线性时间刻度 p = figure( x_axis_label='时间', y_axis_label='海拔/数值', x_axis_type='datetime', # 如果主X轴是UTCs,改成'linear'就行 width=800, height=400, toolbar_location='right' ) # 绘制主图的线性曲线(比如海拔随时间的变化) p.line( x='time', y='altitude', source=df, line_color='navy', line_width=2, legend_label='海拔(线性时间轴)' )
3. 添加对数刻度的副X轴
这一步是核心,需要先定义副X轴的范围,再把它添加到图表上:
# 定义副X轴的范围,对数轴的起始值必须大于0,根据你的log_data调整 p.extra_x_ranges = {"log_x_axis": Range1d(start=1, end=100000)} # 把对数轴添加到图表顶部(也可以选bottom,不过副轴放顶部更易区分) p.add_layout( LogAxis(x_range_name="log_x_axis", axis_label='对数刻度X轴'), 'above' )
4. 在副X轴上绘制散点图
绘制散点时一定要指定x_range_name,告诉Bokeh使用我们刚创建的对数副轴:
# 绘制对数副轴上的散点图,Y轴可以和主图共用(也可以单独设置,按需调整) p.scatter( x='log_data', y='altitude', source=df, x_range_name="log_x_axis", # 必须指定这个参数,否则会默认用主X轴 marker='circle', size=12, color='crimson', fill_alpha=0.7, legend_label='散点(对数X轴)' )
5. 优化图表并显示
最后调整图例位置避免遮挡,然后显示图表:
# 调整图例位置,让图表更整洁 p.legend.location = 'top_left' # 显示最终图表 show(p)
几个关键注意点
- 对数轴的范围不能包含0或负数,所以设置
Range1d时start必须大于0 - 绘制副轴的图形时,一定要指定
x_range_name,否则会默认使用主X轴,导致图形显示异常 - 如果你的主X轴是数值型线性轴(比如UTCs),只需要把创建figure时的
x_axis_type改成默认的'linear'即可
备注:内容来源于stack exchange,提问作者Swawa
相关产品推荐
相关产品推荐

