Plotly绘制正负值柱状图时Y轴错乱、负值柱方向异常问题
Plotly 营收/净利润柱状图Y轴异常修复
异常表现
绘制企业营收与净利润分组柱状图时出现三类显示问题:
- Y轴未以0为正确基准值
- 2017/6、2018/6对应的净利润为负值,柱状图未向下延伸反而向上展示
- Y轴刻度排列顺序混乱
异常效果参考:

问题根因
代码中调用make_subplots时声明了secondary_y=True双Y轴布局,但两个柱状图轨迹未显式指定绑定的Y轴,会被自动分配到两个独立Y轴上;两个Y轴默认未做0基准对齐、量程适配,叠加营收与净利润数值量级差异较大的情况,就会触发上述显示异常。多数同类型营收利润图不需要双Y轴配置,该声明属于冗余设置。
修复方案
方案1:单Y轴实现(绝大多数场景适用)
移除冗余的双Y轴子图配置,直接初始化普通Figure对象,移除硬编码的base=0参数(Plotly柱状图默认基准为0),同时显式配置Y轴强制以0为起点适配正负值,核心代码如下:
def create_visual(filename): createDir_if_not_exist('out/y') createDir_if_not_exist('out/y/interactive') print('read file: ' ,filename) df = pd.read_csv('data/y/'+ filename) # 提前校验数值列类型,若为带逗号/单位的字符串先转数值 df['Total Turnover'] = df['Total Turnover'].astype(str).str.replace(',', '').astype(float) df['Net Profit'] = df['Net Profit'].astype(str).str.replace(',', '').astype(float) stockcode = filename[0:5] print('stockcode: ', stockcode) # 替换原双Y轴subplots声明,用普通Figure fig = go.Figure() fig.add_trace(go.Bar(name='Revenue', x=df['Closing Date'], y=df['Total Turnover'],textposition='auto')) fig.add_trace(go.Bar(name='Net Profit', x=df['Closing Date'], y=df['Net Profit'],textposition='auto')) fig.update_layout(barmode='group',template="seaborn", title_text=str(df_stock[df_stock['StockCode'] == int(stockcode)]['Name of Securities'].values[0]) + ' ' + stockcode +'.HK', xaxis_title="date", title_font_color="red", yaxis_title=df['Unit'].values[0] +' '+ df['Currency'].values[0], # 强制Y轴以0为基准,自动适配正负值量程 yaxis=dict(rangemode='tozero'), font=dict( size=18, )) pio.write_image(fig,'out/y/'+str(stockcode)+'.png', width=1480, height=780,format ='png') fig.write_html('out/y/interactive/'+str(stockcode)+'.html')
方案2:双Y轴实现(营收、净利润量级差过大场景适用)
如果确实需要双Y轴分别展示两个量级差异大的指标,需显式为两个柱状图指定绑定的Y轴,同时给两个Y轴都配置0基准规则,核心修改点如下:
fig = make_subplots(specs=[[{"secondary_y": True}]]) # 显式指定两个trace绑定的Y轴 fig.add_trace(go.Bar(name='Revenue', x=df['Closing Date'], y=df['Total Turnover'],textposition='auto'), secondary_y=False) fig.add_trace(go.Bar(name='Net Profit', x=df['Closing Date'], y=df['Net Profit'],textposition='auto'), secondary_y=True) fig.update_layout(barmode='group',template="seaborn", title_text=str(df_stock[df_stock['StockCode'] == int(stockcode)]['Name of Securities'].values[0]) + ' ' + stockcode +'.HK', xaxis_title="date", title_font_color="red", font=dict(size=18,)) # 双Y轴都设置0基准 fig.update_yaxes(title_text=df['Unit'].values[0] +' '+ df['Currency'].values[0], rangemode='tozero', secondary_y=False) fig.update_yaxes(rangemode='tozero', secondary_y=True)
注意事项
如果修改配置后异常仍存在,优先检查两个数值列的类型:若CSV读入后列值为带千分位逗号、货币单位的字符串,Plotly会将其识别为分类数据而非数值,必然出现刻度混乱、柱方向错误问题,必须先清洗转换为浮点/整数类型再传入绘图接口。
内容的提问来源于stack exchange,提问作者Napas Vinitnantharat
相关产品推荐
相关产品推荐

