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

Python Plotly中y轴autorange功能失效问题求助

Plotly子图X轴同步后Y轴自动适配可见数据范围的解决方法

仅设置autorange=True无法实现X轴缩放时Y轴自动适配,因为Plotly默认只在图表初始化阶段计算Y轴范围。要实现动态调整,需添加自定义JavaScript逻辑监听缩放事件,重新计算每个子图的Y轴范围。

修改后的完整代码:

import plotly.graph_objects as go
from plotly.subplots import make_subplots

fig = make_subplots(rows=4, cols=1)
fig.append_trace(go.Line(x=df["Datetime"], y=df["Pnl"], name="Pnl"), row=1, col=1)
fig.append_trace(go.Line(x=df["Datetime"], y=df["USDCAD"], name="USDCAD"), row=2, col=1)
fig.append_trace(go.Line(x=df["Datetime"], y=df["USD"], name="USD"), row=3, col=1)
fig.append_trace(go.Line(x=df["Datetime"], y=df["USD_SMA30"], name="USD SMA"), row=3, col=1)
fig.append_trace(go.Line(x=df["Datetime"], y=df["CAD"], name="CAD"), row=4, col=1)
fig.append_trace(go.Line(x=df["Datetime"], y=df["CAD_SMA30"], name="CAD SMA"), row=4, col=1)

fig.update_layout(width=1000, height=2000)
fig.update_xaxes(matches='x')
fig.update_yaxes(autorange=True)

# 注入自定义JS监听缩放事件,动态调整Y轴范围
fig.add_annotation(
    text=f"""
    <script>
    var gd = document.getElementById('{fig.layout.id}');
    gd.on('plotly_relayout', function(eventData) {{
        if (eventData['xaxis.range[0]'] || eventData['xaxis.range[1]']) {{
            const xMin = eventData['xaxis.range[0]'] || gd.layout.xaxis.range[0];
            const xMax = eventData['xaxis.range[1]'] || gd.layout.xaxis.range[1];
            
            // 遍历4个子图的Y轴
            for (let i = 1; i <= 4; i++) {{
                const yAxisKey = i === 1 ? 'yaxis' : `yaxis${{i}}`;
                const relevantTraces = gd.data.filter(t => t.yaxis === yAxisKey);
                if (!relevantTraces.length) continue;
                
                // 收集当前X范围内的所有Y值
                const yValues = [];
                relevantTraces.forEach(trace => {{
                    trace.x.forEach((xVal, idx) => {{
                        if (xVal >= xMin && xVal <= xMax) {{
                            yValues.push(trace.y[idx]);
                        }}
                    }});
                }});
                
                // 计算Y轴范围并添加边距
                const yMin = Math.min(...yValues);
                const yMax = Math.max(...yValues);
                const margin = (yMax - yMin) * 0.05;
                
                // 更新Y轴范围
                Plotly.relayout(gd, {{
                    [`${{yAxisKey}}.range[0]`]: yMin - margin,
                    [`${{yAxisKey}}.range[1]`]: yMax + margin
                }});
            }}
        }}
    }});
    </script>
    """,
    showarrow=False,
    x=0, y=0,
    xref='paper', yref='paper',
    xanchor='left', yanchor='bottom',
    font=dict(size=0)
)

fig.show()

代码说明

  • 监听plotly_relayout事件:用户缩放或平移图表时触发该事件,捕获X轴的新范围。
  • 筛选可见数据:针对每个子图,提取当前X轴范围内的所有Y值,计算最大最小值。
  • 动态更新Y轴:为Y轴范围添加5%的边距(避免数据紧贴轴边界),然后更新对应子图的Y轴范围。
  • 保留X轴同步:原有的matches='x'设置确保所有子图X轴范围始终一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 08:27:01