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

Python Plotly:多子图绘制统一悬停竖线时X轴异常

问题解决:多子图悬停竖线导致X轴数据偏移

问题原因

你遇到的X轴异常是因为fig.update_traces(xaxis='x')这行代码强制将所有子图的trace绑定到主X轴x,但共享X轴的多子图中,第二个子图的原始X轴是x2。当你把第二个trace的x轴改为x后,日期类型的X值会被转换为对应的时间戳数值,这个数值远大于X轴的定义域范围(0-1,共享轴默认的domain设置),所以所有数据都会被挤压到图表最右侧。

修正方案

不需要强制修改所有trace的x轴关联,直接通过配置X轴的spikemode和调整spike线的xref即可实现跨子图的悬停竖线效果,同时保留子图的轴关联逻辑。

修正后的完整代码

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

trace1 = go.Scatter(x=[date(2023, 1, 15), date(2023, 2, 15), date(2023, 3, 15), date(2023, 4, 15),
                       date(2023, 5, 15), date(2023, 6, 15), date(2023, 7, 15), date(2023, 8, 15),
                       date(2023, 9, 15), date(2023, 10, 15), date(2023, 11, 15), date(2023, 12, 15)],
                    y=[1000, 2000, 3000, 4000,
                       5000, 6000, 7000, 8000,
                       9000, 10000, 11000, 12000],
                    name='trace1')

trace2 = go.Scatter(x=[date(2023, 1, 15), date(2023, 2, 15), date(2023, 3, 15), date(2023, 4, 15),
                       date(2023, 5, 15), date(2023, 6, 15), date(2023, 7, 15), date(2023, 8, 15),
                       date(2023, 9, 15), date(2023, 10, 15), date(2023, 11, 15), date(2023, 12, 15)],
                    y=[10_000, 20_000, 30_000, 40_000,
                       50_000, 60_000, 70_000, 80_000,
                       90_000, 100_000, 110_000, 120_000],
                    name='trace2')

fig = make_subplots(rows=2, cols=1, shared_xaxes=True, vertical_spacing=0.02)

fig.add_trace(trace1, row=1, col=1)
fig.add_trace(trace2, row=2, col=1)

fig.add_annotation(
    xref='x domain',
    yref='y domain',
    x=0,
    y=1,
    text='FIRST ANNOTATION',
    showarrow=False,
    font=dict(size=14, color='blue'),
    row=1, col=1
)

fig.add_annotation(
    xref='x domain',
    yref='y domain',
    x=0,
    y=1,
    text='SECOND ANNOTATION',
    showarrow=False,
    font=dict(size=14, color='red'),
    row=2, col=1
)

# 关键修改:移除强制绑定x轴的代码,仅配置spike模式和线的xref
fig.update_xaxes(spikemode='across+marker')
# 针对悬停生成的竖线,设置xref为"x"以实现跨子图贯穿
fig.update_shapes(selector=dict(type="line"), xref="x")

fig.update_layout(height=600, width=600, title_text='Example Chart')
fig.show()

关键修改说明

  1. 移除fig.update_traces(xaxis='x'):避免破坏子图默认的轴关联,第二个子图的trace会自动绑定到x2,共享轴设置会保证两个X轴的范围同步。
  2. 保留fig.update_xaxes(spikemode='across+marker'):开启跨子图的悬停竖线和标记点显示。
  3. 保留fig.update_shapes(selector=dict(type="line"), xref="x"):将悬停生成的竖线绑定到主X轴x,确保竖线能贯穿所有子图。

这样修改后,既能实现跨子图的统一悬停竖线,又不会破坏X轴的正常显示。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 13:35:55