Plotly双堆叠图配置:共享X轴,线性/对数Y轴实现
解决方案
你的核心问题是创建子图后又用go.Figure()覆盖了subplot对象,导致共享X轴的配置完全失效。以下是修正后的完整代码,实现线性/对数双Y轴、共享X轴且缩放同步的需求:
import plotly.graph_objs as go from plotly.subplots import make_subplots # 假设table和model_sum已提前定义 x = table["E"] y = table["SigmaE"] yerr = table["SD_SigmaE"] # 1. 创建2行1列的子图,开启X轴共享 fig = make_subplots( rows=2, cols=1, shared_xaxes=True, # 开启X轴共享,自动同步缩放 vertical_spacing=0.08, # 调整子图间距,避免标签重叠 subplot_titles=("线性Y轴数据对比", "对数Y轴数据对比") # 可选子图标题 ) # 2. 向第1行(线性Y轴)添加所有原始trace # 实验数据点 fig.add_trace( go.Scatter( name='Experimental Data', x=table["E"], y=table["SigmaE"], mode='markers', line=dict(color='rgb(31, 119, 180)'), marker=dict(size=2, line=dict(width=1, color='DarkSlateGrey')) ), row=1, col=1 ) # 模型拟合线 fig.add_trace( go.Scatter( name='Modeled Data', x=table["E"], y=model_sum, mode='lines', line=dict(color='rgb(255, 0, 0)'), ), row=1, col=1 ) # 误差上界 fig.add_trace( go.Scatter( name='Experimental Data Upper Bound (one SD)', x=table['E'], y=table["SigmaE"] + table['SD_SigmaE'], mode='lines', marker=dict(color="#444"), line=dict(width=0), showlegend=False ), row=1, col=1 ) # 误差下界(带填充) fig.add_trace( go.Scatter( name='Experimental Data Lower Bound (one SD)', x=table['E'], y=table["SigmaE"] - table['SD_SigmaE'], marker=dict(color="#444"), line=dict(width=0), mode='lines', fillcolor='rgba(68, 68, 68, 0.3)', fill='tonexty', showlegend=False ), row=1, col=1 ) # 3. 向第2行(对数Y轴)添加相近数据(示例用同样数据,可按需替换) fig.add_trace( go.Scatter( name='Experimental Data (Log)', x=table["E"], y=table["SigmaE"], mode='markers', line=dict(color='rgb(31, 119, 180)'), marker=dict(size=2, line=dict(width=1, color='DarkSlateGrey')), showlegend=False # 避免重复图例 ), row=2, col=1 ) fig.add_trace( go.Scatter( name='Modeled Data (Log)', x=table["E"], y=model_sum, mode='lines', line=dict(color='rgb(255, 0, 0)'), showlegend=False # 避免重复图例 ), row=2, col=1 ) # 4. 配置轴属性和布局 fig.update_layout( title='Experimental vs Reconstructed Data', hovermode="x unified", # 鼠标悬停时同步显示两个子图的X对应数据 legend=dict(orientation="h", yanchor="bottom", y=1.02, xanchor="right", x=1) # 图例放在顶部 ) # 设置第1行Y轴为线性(默认),添加标题 fig.update_yaxes(title_text='Σ(E) (Linear)', row=1, col=1) # 设置第2行Y轴为对数,添加标题 fig.update_yaxes(title_text='Σ(E) (Log)', type="log", row=2, col=1) # 设置X轴标题(只需要在底部子图设置一次) fig.update_xaxes(title_text='E', row=2, col=1) fig.show()
关键修改说明
- 保留子图对象:不再用
go.Figure()覆盖make_subplots创建的fig,确保共享X轴的配置生效。 - 指定trace位置:所有
add_trace都通过row和col参数指定添加到哪个子图。 - 对数轴配置:单独对第2行的Y轴设置
type="log",不影响第一行的线性轴。 - 同步缩放:
shared_xaxes=True自动实现缩放/平移时两个子图的X轴同步。 - 优化交互:
hovermode="x unified"让鼠标悬停时两个子图同时显示对应X值的数据,提升体验。
内容的提问来源于stack exchange,提问作者twistfire
相关产品推荐
相关产品推荐

