如何用Plotly Graph Objects与Subplots实现行间列数及列宽不同的子图?
实现Plotly子图的自定义行列数与列宽
可以通过Plotly的make_subplots参数配置或手动指定子图域(domain)的方式,实现每行不同列数、不同列宽的子图布局,以下是针对你需求的具体解决方案:
方案1:用make_subplots实现不同行列数(示例1:第1行2列,第2行4列)
通过specs参数定义每行的子图数量,结合colspan属性合并列,快速实现不同行的列数差异:
import plotly.graph_objects as go from plotly.subplots import make_subplots # 创建子图,specs定义每行子图结构 fig = make_subplots( rows=2, cols=4, # 全局最大列数设为第2行的列数 specs=[ [{"colspan": 2}, {"colspan": 2}, None, None], # 第1行2个子图,各占2列 [{}, {}, {}, {}] # 第2行4个子图,各占1列 ], column_widths=[0.25, 0.25, 0.25, 0.25] # 基础列宽,配合colspan实现均分 ) # 填充第1行子图 fig.add_trace(go.Scatter(x=[1,2,3], y=[4,5,6]), row=1, col=1) fig.add_trace(go.Bar(x=[1,2,3], y=[4,5,6]), row=1, col=3) # 填充第2行子图 fig.add_trace(go.Scatter(x=[1,2,3], y=[6,5,4]), row=2, col=1) fig.add_trace(go.Bar(x=[1,2,3], y=[6,5,4]), row=2, col=2) fig.add_trace(go.Scatter(x=[1,2,3], y=[5,4,3]), row=2, col=3) fig.add_trace(go.Bar(x=[1,2,3], y=[5,4,3]), row=2, col=4) fig.update_layout(height=600, width=800, title_text="示例1:第1行2列,第2行4列") fig.show()
方案2:手动设置domain实现自定义列宽(示例2:复杂列宽需求)
当需要每行独立配置列宽时,直接手动指定每个子图的xaxis.domain和yaxis.domain,完全摆脱全局列宽限制,精准匹配你的需求:
import plotly.graph_objects as go fig = go.Figure() # ---------------------- 第1行子图(Y轴范围:0.55-1) ---------------------- # 第1列:占总宽度37.5%,与第2列同宽 fig.add_trace( go.Scatter(x=[1,2,3], y=[4,5,6]), xaxis=dict(domain=[0, 0.375]), yaxis=dict(domain=[0.55, 1]) ) # 第2列:占总宽度37.5% fig.add_trace( go.Bar(x=[1,2,3], y=[4,5,6]), xaxis=dict(domain=[0.375, 0.75]), yaxis=dict(domain=[0.55, 1]) ) # 第3列:占总宽度25%,与第2行每列宽度一致 fig.add_trace( go.Scatter(x=[1,2,3], y=[4,5,6]), xaxis=dict(domain=[0.75, 1]), yaxis=dict(domain=[0.55, 1]) ) # ---------------------- 第2行子图(Y轴范围:0-0.45) ---------------------- # 4列各占总宽度25%,与第1行第3列宽度一致 fig.add_trace( go.Scatter(x=[1,2,3], y=[6,5,4]), xaxis=dict(domain=[0, 0.25]), yaxis=dict(domain=[0, 0.45]) ) fig.add_trace( go.Bar(x=[1,2,3], y=[6,5,4]), xaxis=dict(domain=[0.25, 0.5]), yaxis=dict(domain=[0, 0.45]) ) fig.add_trace( go.Scatter(x=[1,2,3], y=[5,4,3]), xaxis=dict(domain=[0.5, 0.75]), yaxis=dict(domain=[0, 0.45]) ) fig.add_trace( go.Bar(x=[1,2,3], y=[5,4,3]), xaxis=dict(domain=[0.75, 1]), yaxis=dict(domain=[0, 0.45]) ) # 调整布局样式 fig.update_layout( height=600, width=1000, title_text="示例2:自定义列宽布局", yaxis_title="第1行Y轴", yaxis2_title="第2行Y轴" ) fig.show()
总结
- 简单的行列数差异:用
make_subplots的specs+colspan/rowspan即可快速实现。 - 复杂的列宽自定义:手动设置子图的
domain属性是最灵活的方案,可任意控制每个子图的位置和宽度。
内容的提问来源于stack exchange,提问作者Salvatore Saladino
相关产品推荐
相关产品推荐

