使用热图居中表格

2024-04-28

我正在尝试在seaborn 热图下添加一个matplotlib 表。 我已经能够绘制它们,但没有对齐的运气。

# Main data
df = pd.DataFrame({"A": [20, 10, 7, 39], 
                   "B": [1, 8, 12, 9], 
                   "C": [780, 800, 1200, 250]})

# It contains min and max values for the df cols
df_info =  pd.DataFrame({"A": [22, 35], 
                   "B": [5, 10], 
                   "C": [850, 900]})

df_norm = (df - df.min())/(df.max() - df.min())


# Plot the heatmap
vmin = df_norm.min().min()
vmax = df_norm.max().max()

fig, (ax1, ax2) = plt.subplots(nrows=2, sharex=True)
sns.heatmap(df_norm, ax=ax1, annot=df, cmap='RdBu_r', cbar=True)

当我将表添加到ax2它是根据热图的所有宽度绘制的(包括颜色条)。我已经尝试了所有可能的组合locor bbox但我无法将表格精确居中并赋予其与顶部热图相同的宽度(整个表格以及单个单元格的宽度)。

table = df_info
cell_text = []
for row in range(len(table)):
    cell_text.append(table.iloc[row])

ax2.axis('off')
ax2.table(cellText=cell_text,
          rowLabels=table.index,
          colLabels=None,
          loc='center')

有时我也会将参数传递给热图square=True打印平方单元格,结果是这样的:

问题:如何将表格及其单元格附加到热图并将其居中?

EDIT:从技术上来说tdy的回答 https://stackoverflow.com/a/66827453/1191416解决我的简单示例的问题是正确的。尽管我可能过于简化了它并遗漏了一条重要的信息。
在我的真实案例中,如果我使用以下命令创建图形:

fig, (ax1, ax2) = plt.subplots(nrows=2,
                               **{"figsize": (18, 18),
                                  "dpi": 200,
                                  "tight_layout": True})

并应用上面提到的答案我得到这样的东西:

表格距离底部很远并且比热图更宽。

另外如果我设置tight_layout=False我获得了一个宽度正确但仍位于底部很远的表格:

fig, (ax1, ax2) = plt.subplots(nrows=2,
                               **{"figsize": (18, 18),
                                  "dpi": 200,
                                  "tight_layout": False})

我想就我而言"figsize": (18, 18) and tight_layout对我的问题有很大影响,但我不确定为什么也不知道如何解决它。


短法

您可以使用以下命令移动/调整表格大小Axes.set_position() https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.set_position.html. The left/bottom/width/height可以根据需要调整参数:

bbox1 = ax1.get_position()
bbox2 = ax2.get_position()

# modify as needed
left = bbox1.x0
bottom = bbox1.y0 - (bbox2.height * 0.8)
width = bbox1.x0 + (bbox1.width * 0.8)
height = bbox2.height

ax2.set_position([left, bottom, width, height])

较长的方法

如果简单方法效果不佳,请尝试设置轴height_ratios via gridspec_kw in plt.subplots()。我还需要设置tight_layout=False.

Use height_ratios设置比例ax1:ax2(热图:表),并使用*_offset根据需要调整表格大小/位置的变量。这些值适用于我的系统,但您可以针对您的系统进行调整:

### modify these params as needed ###

height_ratios = (20, 1) # heatmap:table ratio (20:1)
left_offset = 0         # table left position adjustment
bottom_offset = -0.025  # table bottom position adjustment
width_offset = -0.0005  # table width adjustment
height_offset = 0       # table height adjusment

#####################################

fig_kw = dict(figsize=(18, 18), dpi=200, tight_layout=False)
gridspec_kw = dict(height_ratios=height_ratios)
fig, (ax1, ax2) = plt.subplots(nrows=2, gridspec_kw=gridspec_kw, **fig_kw)

sns.heatmap(df_norm, ax=ax1, annot=df, cmap='RdBu_r', cbar=True)
ax2.table(cellText=[df_info.iloc[row] for row in range(len(df_info))],
          rowLabels=table.index,
          colLabels=None,
          loc='center')
ax2.axis('off')

bbox1 = ax1.get_position()
bbox2 = ax2.get_position()

left = bbox1.x0 + left_offset
bottom = bbox1.y0 - bbox2.height + bottom_offset
width = bbox1.width + width_offset
height = bbox2.height + height_offset

ax2.set_position([left, bottom, width, height])
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用热图居中表格 的相关文章

随机推荐