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

Plotly双Y轴柱状图(固定汇率转换)更优实现方案咨询

问题描述

我需要用Plotly Graph Objects绘制带双Y轴的堆叠柱状图,两个Y轴对应固定转换系数的不同货币(USD和Euro,转换系数为1.5)。目前的实现是为每个类别绘制两个轨迹,将第二个轨迹设为透明、隐藏图例并关闭悬浮信息,虽然能生效但维护繁琐。当前代码如下:

import pandas as pd
import numpy as np
import plotly.graph_objects as go
from plotly.subplots import make_subplots

# make up some data
dates = pd.DataFrame(pd.date_range('1/1/2023','1/7/2023'), columns=['date'])
dates["key"] = 0
items = pd.DataFrame(["A","B","C"], columns=['items'])
items["key"] = 0
df = dates.merge(items,on="key",how="outer").drop("key",axis=1)
df['price_USD'] = np.random.randint(0, 100, df.shape[0])
df['price_EURO'] = df['price_USD']/1.5

fig = make_subplots(specs=[[{"secondary_y": True}]])  
for item, _df in df.groupby("items",sort=True):
    ## we may set the colors of the individual items manually here
    fig.add_trace(
                go.Bar(
                    x=_df["date"],
                    y=_df["price_USD"],
                    showlegend=True,
                    name=item,
                    opacity=1.0,
                    #color=color,
                    legendgroup=item

                ),
                secondary_y=False,
            )

    # invisible trace
    fig.add_trace(
                go.Bar(
                    x=_df["date"],
                    y=_df["price_EURO"],
                    showlegend=False,
                    opacity=0.0,
                    name="",
                    hoverinfo="skip",
                    legendgroup=item
                ),
                secondary_y=True,
            )

fig.update_layout(barmode="stack")
fig.update_yaxes(title_text="<b>Cost USD", secondary_y=False)
fig.update_yaxes(title_text="<b>Cost Euro", showgrid=False, secondary_y=True)
fig.show()

双Y轴堆叠柱状图效果

请问有没有更简洁的实现方式?


简洁实现方案

不需要添加隐形轨迹,直接通过配置第二个Y轴的刻度值和刻度文本,基于第一个Y轴的数值进行固定系数转换即可。这样仅需绘制一组USD的柱状轨迹,第二个Y轴仅负责显示转换后的Euro刻度,大幅简化代码维护成本。

实现代码

import pandas as pd
import numpy as np
import plotly.graph_objects as go
from plotly.subplots import make_subplots

# 生成模拟数据
dates = pd.DataFrame(pd.date_range('1/1/2023','1/7/2023'), columns=['date'])
dates["key"] = 0
items = pd.DataFrame(["A","B","C"], columns=['items'])
items["key"] = 0
df = dates.merge(items,on="key",how="outer").drop("key",axis=1)
df['price_USD'] = np.random.randint(0, 100, df.shape[0])
conversion_rate = 1.5  # USD转Euro的固定转换系数

fig = make_subplots(specs=[[{"secondary_y": True}]])  

# 仅绘制USD的堆叠柱状轨迹
for item, _df in df.groupby("items",sort=True):
    fig.add_trace(
        go.Bar(
            x=_df["date"],
            y=_df["price_USD"],
            showlegend=True,
            name=item,
            legendgroup=item
        ),
        secondary_y=False,
    )

# 配置主Y轴(USD)
fig.update_yaxes(title_text="<b>Cost USD</b>", secondary_y=False)

# 配置次Y轴(Euro):复用主Y轴刻度值,显示转换后的Euro文本
usd_ticks = fig.layout.yaxis.tickvals
if usd_ticks:
    euro_ticks = [tick / conversion_rate for tick in usd_ticks]
    fig.update_yaxes(
        title_text="<b>Cost Euro</b>",
        tickvals=usd_ticks,
        ticktext=[f"{tick:.2f}" for tick in euro_ticks],
        showgrid=False,
        secondary_y=True
    )

fig.update_layout(barmode="stack")
fig.show()

方案优势

  • 仅需维护一组柱状轨迹,避免重复代码
  • 转换系数统一管理,修改时仅需调整conversion_rate变量
  • 次Y轴刻度与主Y轴严格对应,保证数据展示的准确性

内容的提问来源于stack exchange,提问作者Raphael Roth

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 13:52:11