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

如何控制Plotly子图中带注释热力图的宽度?

解决Plotly带注释热力图多子图宽度不一致问题

问题核心:使用plotly.figure_factory.create_annotated_heatmap生成的热力图在make_subplots布局中,第一个子图宽度明显窄于其他子图,导致内容显示不全。

问题原因

create_annotated_heatmap默认会根据x轴标签长度自动调整轴的显示范围,叠加Plotly子图的自动适配逻辑,标签较短的子图(如示例中的'a')会被压缩,无法与其他子图保持宽度一致。

解决方案

通过手动约束每个子图的x轴显示范围,强制子图宽度严格遵循column_widths设置的比例:

  • 为每个子图的x轴添加constrain='domain'配置,确保轴范围被限制在子图分配的区域内,不受标签长度影响
  • 统一设置column_widths为等比例数值,保证所有子图基础宽度一致

修改后的可复现代码

import plotly.graph_objects as go
import plotly.figure_factory as ff
from plotly.subplots import make_subplots
import pandas as pd

df = pd.DataFrame({'strats': ['a', 'a', 'b', 'b', 'c', 'c', 'de', 'de'],
                 'z': [1, 2, 3, 4, 5, 6, 7, 8],
                 'title': ['this day will never end ever more texts', 'short', 'short', 
                           'very long', 'very very long', 
                           'very very very very very long',
                          'short', 'short']})
strats = pd.unique(df['strats'])
fig = make_subplots(rows=1, cols=len(strats), 
                    horizontal_spacing=0.015,
                    column_widths=[1]*len(strats))  # 等比例分配子图宽度
heatmaps = []

for i in range(len(strats)):
    r_strat = df[df['strats'] == strats[i]]
    heatmaps.append(ff.create_annotated_heatmap(
        x=[strats[i]], 
        z=[[r] for r in r_strat['z']],
        annotation_text=[[r] for r in r_strat['title']],
        hoverinfo='text',
        colorscale='algae')
    )
    fig.add_trace(heatmaps[i].data[0], row=1, col=i+1)
    
    # 修正注释的轴引用
    annotations = heatmaps[i].layout.annotations
    for k in range(len(annotations)):
        annotations[k]['xref'] = f'x{i+1}'
        annotations[k]['yref'] = f'y{i+1}'
    for ano in annotations:
        fig.add_annotation(ano)
    
    # 统一设置y轴隐藏和x轴约束
    yaxis_key = f'yaxis{i+1}' if i !=0 else 'yaxis'
    xaxis_key = f'xaxis{i+1}' if i !=0 else 'xaxis'
    fig.update_layout(
        **{yaxis_key: dict(visible=False, categoryorder='array')},
        **{xaxis_key: dict(constrain='domain')}  # 关键:强制x轴范围匹配子图域
    )
        
fig.update_layout(
    title='Popularity Spectrum',
    paper_bgcolor='rgba(0,0,0,0)',
    plot_bgcolor='rgba(0,0,0,0)',
    width=1200  # 可选:设置整体画布宽度,配合比例更精准
)
fig.show()

关键修改说明

  • column_widths=[1]*len(strats):所有子图采用等比例宽度分配,若需单独调整某张子图宽度,可修改对应位置的数值(如[2,1,1,1]让第一个子图宽度翻倍)
  • xaxis_key: dict(constrain='domain'):禁止x轴因标签长度自动扩张,严格限制在子图分配的区域内,确保宽度一致
  • 简化原代码中多分支的y轴设置逻辑,用统一方式处理所有子图的轴配置

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 11:18:19