You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Plotly绘制正负值柱状图时Y轴错乱、负值柱方向异常问题

Plotly 营收/净利润柱状图Y轴异常修复

异常表现

绘制企业营收与净利润分组柱状图时出现三类显示问题:

  • Y轴未以0为正确基准值
  • 2017/6、2018/6对应的净利润为负值,柱状图未向下延伸反而向上展示
  • Y轴刻度排列顺序混乱

异常效果参考:
负值柱反向、刻度混乱效果1
负值柱反向、刻度混乱效果2

问题根因

代码中调用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 03:24:18