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

Plotly子图中热力图的宽高比设置方法求助

解决Plotly子图中所有热力图的宽高比统一设置问题

问题现状

常规图表的宽高比设置方案在子图场景下完全失效,具体表现为:

  • 使用px.imshow(df, aspect='equal')结合fig.add_trace()时,宽高比设置被完全忽略
  • 通过布局调整宽高比仅对第一个子图生效,无法作用于所有子图

测试代码如下:

import pandas as pd
import plotly.express as px
import plotly.graph_objects as go

## Example data
df = pd.DataFrame([[0,0,0,0,0],
                   [0,0,1,0,0],
                   [0,1,2,1,0],
                   [0,0,1,0,0],
                   [0,0,0,0,0],
                  ])

## Subplots w/ go.Heatmap()
layout = dict(
    # yaxis=...,
    # xaxis=...,
    # width=plot_width,
    # height=plot_height,
    # autosize=False,
    yaxis_scaleanchor="x" ,  # <---- 仅对第一个子图生效 :(
    )

fig = go.Figure(layout=layout).set_subplots(rows=1, cols=2, subplot_titles=['#1', '#2'])

fig.add_trace(
    go.Heatmap(
        z = df,
        coloraxis = "coloraxis",  # 所有子图共用颜色轴
    ), 
    1,1)
fig.add_trace(
    go.Heatmap(
        z = df*2,
        coloraxis = "coloraxis",  # 所有子图共用颜色轴
    ),
    1,2)

## Update y-axes
fig.update_yaxes(
    title_text="yaxis #1", 
    row=1, col=1, 
    scaleanchor='x',  # <---- 仅对第一个子图生效 :(
    ) 
fig.update_yaxes(
    title_text="yaxis #2",
    row=1, col=2,
    scaleanchor='x',  # <---- 仅对第一个子图生效 :(
    )

## Update layout
# fig['layout']['yaxis']['scaleanchor']='x' # <--- 仅更新第一个子图 :(

fig.update_layout(
    title='2D Heatmaps',
    autosize=False,
    # yaxis_scaleanchor="x",  # <--- 仅更新第一个子图 :(
    yaxis = dict(scaleanchor = 'x'),   # <--- 仅更新第一个子图 :(
    # coloraxis_colorscale='Viridis',
    )

# fig.show()

有效解决方案

要让所有子图的热力图都保持等宽高比,核心是为每个子图的y轴明确指定对应子图的x轴作为缩放锚点,同时避免轴共享带来的设置冲突:

步骤说明

  1. 创建子图时关闭轴共享:设置shared_xaxes=False和shared_yaxes=False,防止不同子图的轴设置互相覆盖
  2. 为每个子图的y轴单独配置:
    • scaleanchor指定对应子图的x轴ID(如第2列子图对应x2)
    • scaleratio=1强制保持等宽高比例
    • autorange='reversed'可选,用于调整热力图的y轴方向(根据需求选择)

修改后的完整代码

import pandas as pd
import plotly.graph_objects as go

# 示例数据
df = pd.DataFrame([[0,0,0,0,0],
                   [0,0,1,0,0],
                   [0,1,2,1,0],
                   [0,0,1,0,0],
                   [0,0,0,0,0],
                  ])

# 创建子图,关闭轴共享
fig = go.Figure().set_subplots(rows=1, cols=2, subplot_titles=['#1', '#2'],
                               shared_xaxes=False, shared_yaxes=False)

# 添加热力图轨迹,共用颜色轴
fig.add_trace(
    go.Heatmap(z=df, coloraxis="coloraxis"), 
    row=1, col=1
)
fig.add_trace(
    go.Heatmap(z=df*2, coloraxis="coloraxis"),
    row=1, col=2
)

# 配置第一个子图的轴
fig.update_xaxes(row=1, col=1, title_text="x轴 #1")
fig.update_yaxes(row=1, col=1, title_text="y轴 #1",
                 scaleanchor="x1", scaleratio=1, autorange='reversed')

# 配置第二个子图的轴
fig.update_xaxes(row=1, col=2, title_text="x轴 #2")
fig.update_yaxes(row=1, col=2, title_text="y轴 #2",
                 scaleanchor="x2", scaleratio=1, autorange='reversed')

# 全局布局设置
fig.update_layout(
    title='2D热力图',
    autosize=False,
    width=800,
    height=400,
    coloraxis_colorscale='Viridis'
)

fig.show()

方案原理

之前的设置中,scaleanchor='x'默认只会匹配第一个子图的x1轴,第二个子图的y轴必须明确指定锚定x2轴才能生效。关闭轴共享后,每个子图的轴属性可以独立配置,不会被其他子图的设置覆盖。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 20:45:06