如何使Plotly双Y轴零点对齐且仅调整刻度标签?
Plotly双Y轴零点对齐实现(仅调整刻度标签)
需求:绘制包含柱状图和折线图的双Y轴图表,要求右侧Y轴(对应折线图)与左侧Y轴(对应柱状图)零点对齐,仅调整Y轴刻度标签,不修改原始数据展示。
原代码:
bar_trace = go.Bar(x=line_s['Year/Quarter'], y=line_s['CUR (€)'], name='CUR (€)') line_trace1 = go.Scatter(x=line_s['Year/Quarter'], y=line_s['CUR PP'], name='CUR PP', yaxis='y2', mode='lines+markers', line=dict(color='orange')) layout = go.Layout(title='test', yaxis=dict(title='CUR (€)'), yaxis2=dict(title='CUR PP (%)', overlaying='y', side='right', tickmode="sync"), legend=dict(x=1.06)) fig = go.Figure(data=[bar_trace, line_trace1], layout=layout) fig.show()
图表示例:
解决方案
Plotly自带的tickmode="sync"仅同步刻度数量,无法实现零点对齐。要达成需求,需通过计算两个Y轴数据的极值,手动调整轴的range参数,让零点在同一水平线上。
步骤与修改后代码
- 获取两组数据的极值,计算零点到两端的范围比例
- 根据比例调整右侧Y轴的范围,确保与左侧Y轴零点对齐
完整代码如下:
import plotly.graph_objects as go # 假设line_s是已加载的数据集 bar_trace = go.Bar(x=line_s['Year/Quarter'], y=line_s['CUR (€)'], name='CUR (€)') line_trace1 = go.Scatter(x=line_s['Year/Quarter'], y=line_s['CUR PP'], name='CUR PP', yaxis='y2', mode='lines+markers', line=dict(color='orange')) # 获取两个系列的Y轴极值 y1_min = line_s['CUR (€)'].min() y1_max = line_s['CUR (€)'].max() y2_min = line_s['CUR PP'].min() y2_max = line_s['CUR PP'].max() # 计算左侧Y轴正负方向的范围(以零点为基准) y1_range_neg = abs(y1_min) if y1_min < 0 else 0 y1_range_pos = y1_max if y1_max > 0 else 0 # 计算右侧Y轴正负方向的范围 y2_range_neg = abs(y2_min) if y2_min < 0 else 0 y2_range_pos = y2_max if y2_max > 0 else 0 # 计算比例,确保零点对齐 ratio_neg = y1_range_neg / y2_range_neg if y2_range_neg != 0 else 1 ratio_pos = y1_range_pos / y2_range_pos if y2_range_pos != 0 else 1 # 确定右侧Y轴的新范围 if y2_range_neg > 0 and y2_range_pos > 0: target_ratio = max(ratio_neg, ratio_pos) y2_new_min = -y1_range_neg / target_ratio y2_new_max = y1_range_pos / target_ratio elif y2_range_neg > 0: y2_new_min = -y1_range_neg / ratio_neg y2_new_max = 0 else: y2_new_min = 0 y2_new_max = y1_range_pos / ratio_pos # 更新布局 layout = go.Layout(title='test', yaxis=dict(title='CUR (€)', range=[-y1_range_neg, y1_range_pos]), yaxis2=dict(title='CUR PP (%)', overlaying='y', side='right', range=[y2_new_min, y2_new_max]), legend=dict(x=1.06)) fig = go.Figure(data=[bar_trace, line_trace1], layout=layout) fig.show()
说明
- 该方案仅调整Y轴的刻度范围和标签,完全不修改原始数据的展示
- 通过计算正负范围的比例,确保两个Y轴的零点精确对齐
- 兼容单侧有负值、双侧都有负值或无负值的多种数据场景
内容的提问来源于stack exchange,提问作者hvahva
相关产品推荐
相关产品推荐

