python - 使用热图居中表格
问题描述
我正在尝试在 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
它会绘制热图的所有宽度(包括彩条)。我已经尝试了 or 的所有可能组合,loc
但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
以打印平方单元格,结果是这样的:
问题:如何将表格及其单元格附加到热图中并将其居中?
编辑:从技术上讲, tdy 的答案对于解决我的简单示例的问题是正确的。尽管我可能过度简化了它并遗漏了一条重要信息。
在我的真实案例场景中,如果我使用以下命令创建图形:
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)
对tight_layout
我的问题有很大的影响,但我既不知道为什么也不知道如何解决它。
解决方案
短方法
您可以使用 移动/调整表格大小Axes.set_position()
。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
通过gridspec_kw
in设置轴plt.subplots()
。我还需要设置tight_layout=False
.
用于设置(热图:表格)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])
推荐阅读
- c# - 获取 TraceTelemetry 以显示在 Application Insights 时间轴中
- lua - LUA|MTASA 尝试索引字段“?” (零值)
- c# - 如何在asp.net mvc5中操作ViewBag.Title中的文本
- c++ - [CURL][VS2017] 错误 LNK2019:未解析的外部符号 _curl_global_init 引用
- c++ - 在成员初始化器列表中,我可以创建对不在列表中的成员变量的引用吗?
- spring - Cassandra 连接断开期间的查询也不例外
- python - 使用 FBV 使用多个图像进行后期创建
- java - 如何在不破坏 for 循环的情况下抛出异常?
- regex - 如何在linux中以秒为单位解析经过的时间
- c# - 我一直在尝试使用多维数组来创建电影院的布局。使用 X 表示关闭,使用 O 表示打开