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

Plotly多Y轴图表优化:内置第三Y轴与单位切换实现

Plotly 双问题解决方案:内部右侧Y轴布局 + 单位切换单选按钮

问题1:将第三个Y轴置于右侧Y轴内部

Plotly中实现右侧内部Y轴,核心是通过position、overlaying和side参数调整轴的位置与层级:

关键配置逻辑

  • 将第三个Y轴的side设为"right",与主右侧Y轴同方向
  • 用position参数控制轴的水平位置(范围0-1,0最左,1最右),设为0.9-0.95即可嵌入主右侧轴内部
  • 开启overlaying参数,指定覆盖在主右侧Y轴(通常是y2)之上
  • 关闭showgrid避免网格线重叠,缩小tickfont提升紧凑感

代码示例

# 假设主右侧轴为y2,第三个轴为y3
fig.update_layout(
    yaxis2=dict(
        side="right",
        title="速度 (m/s)",
        domain=[0, 1]  # 主右侧轴占满垂直范围
    ),
    yaxis3=dict(
        side="right",
        position=0.95,  # 调整此值控制内部嵌入的位置
        overlaying="y2",
        title="距离 (mm)",
        showgrid=False,
        tickfont=dict(size=10),
        titlefont=dict(size=10)
    )
)

常见问题排查

  • 若轴仍显示在外部:检查是否未设置overlaying,或position值过大(超过0.95可能超出图表范围)
  • 若刻度重叠:调整两个右侧轴的tickangle或tickfont大小,或设置tickmode="linear"控制刻度密度

问题2:单选按钮切换米制/英制单位

利用Plotly的updatemenus组件创建单选按钮,通过单位转换系数更新数据与轴标签:

核心实现步骤

  1. 定义单位转换系数(米制转英制)
  2. 创建单选按钮组,每个按钮触发update方法,同步更新所有trace的数值与对应轴的标签

代码示例

import plotly.graph_objects as go
import pandas as pd

# 模拟测试数据
df = pd.DataFrame({
    "time": [1,2,3,4,5],
    "pressure": [1.2, 1.5, 1.3, 1.7, 1.4],
    "velocity": [20, 25, 22, 28, 24],
    "distance": [50, 60, 55, 65, 58]
})

# 初始化图表
fig = go.Figure()

# 添加压力bar图(y轴)
fig.add_trace(go.Bar(x=df["time"], y=df["pressure"], name="压力", yaxis="y"))
# 添加速度线图(y2轴)
fig.add_trace(go.Scatter(x=df["time"], y=df["velocity"], name="速度", yaxis="y2", line=dict(color="red")))
# 添加距离线图(y3轴)
fig.add_trace(go.Scatter(x=df["time"], y=df["distance"], name="距离", yaxis="y3", line=dict(color="green")))

# 单位转换配置
unit_config = {
    "metric": {
        "coeffs": {"pressure": 1, "velocity": 1, "distance": 1},
        "labels": {"y": "压力 (bar)", "y2": "速度 (m/s)", "y3": "距离 (mm)"}
    },
    "imperial": {
        "coeffs": {"pressure": 14.5038, "velocity": 3.28084, "distance": 0.0393701},
        "labels": {"y": "压力 (Psi)", "y2": "速度 (fps)", "y3": "距离 (inch)"}
    }
}

# 添加单选按钮
fig.update_layout(
    updatemenus=[
        dict(
            type="buttons",
            direction="right",
            x=0.05,
            y=1.18,
            buttons=[
                dict(
                    label="米制单位",
                    method="update",
                    args=[
                        # 更新所有trace的y值
                        {"y": [
                            df["pressure"] * unit_config["metric"]["coeffs"]["pressure"],
                            df["velocity"] * unit_config["metric"]["coeffs"]["velocity"],
                            df["distance"] * unit_config["metric"]["coeffs"]["distance"]
                        ]},
                        # 更新所有轴的标签
                        {"yaxis": {"title": unit_config["metric"]["labels"]["y"]},
                         "yaxis2": {"title": unit_config["metric"]["labels"]["y2"]},
                         "yaxis3": {"title": unit_config["metric"]["labels"]["y3"]}}
                    ]
                ),
                dict(
                    label="英制单位",
                    method="update",
                    args=[
                        {"y": [
                            df["pressure"] * unit_config["imperial"]["coeffs"]["pressure"],
                            df["velocity"] * unit_config["imperial"]["coeffs"]["velocity"],
                            df["distance"] * unit_config["imperial"]["coeffs"]["distance"]
                        ]},
                        {"yaxis": {"title": unit_config["imperial"]["labels"]["y"]},
                         "yaxis2": {"title": unit_config["imperial"]["labels"]["y2"]},
                         "yaxis3": {"title": unit_config["imperial"]["labels"]["y3"]}}
                    ]
                )
            ]
        )
    ],
    # 初始化轴布局(包含问题1的内部Y轴配置)
    yaxis=dict(title="压力 (bar)", side="left"),
    yaxis2=dict(title="速度 (m/s)", side="right", domain=[0,1]),
    yaxis3=dict(title="距离 (mm)", side="right", position=0.95, overlaying="y2", showgrid=False, tickfont=dict(size=10))
)

fig.show()

其他多单位展示方案

  1. Hover提示双单位:在hovertemplate中同时显示米制与英制数值,无需切换,示例:
    fig.update_traces(hovertemplate="压力: %{y} bar (%{y*14.5038:.2f} Psi)<extra></extra>")
    
  2. 下拉菜单替代单选按钮:将updatemenus的type设为"dropdown",样式更紧凑,适合多单位场景
  3. 自定义刻度格式:利用tickformat直接在轴上显示双单位,但会增加视觉复杂度,仅适合简单场景

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 20:54:54