重叠 yticklabels:是不是可以控制 seaborn 中热图的单元格大小?

Posted

技术标签:

【中文标题】重叠 yticklabels:是不是可以控制 seaborn 中热图的单元格大小?【英文标题】:Overlapping yticklabels: Is it possible to control cell size of heatmap in seaborn?重叠 yticklabels:是否可以控制 seaborn 中热图的单元格大小? 【发布时间】:2016-05-09 18:00:00 【问题描述】:

我有一个包含大约 200 个观察值的数据集,我想将其绘制为热图。每个观察都有一个与之关联的字符串,我想显示它。我的问题是我无法阅读这些标签,因为它们相互重叠。因此,我的问题是,是否可以以某种方式将热图的单元格大小设置为 yticklabel 的字体大小,或者是否有任何其他解决方法。

在下面的示例中,我使用随机数据进行说明:

import seaborn as sns
import numpy as np
data = np.random.rand(200, 10)
ax = sns.heatmap(data)
for item in ax.get_yticklabels():
    item.set_rotation(0)

这给了我:

有没有办法让这些yticklabels 可读?在理想情况下,我有一个选项允许我将单元格的高度设置为yticklabels 的字体大小。这可能吗?

编辑:

如 cmets 中所述,一种可能性是增加图形的大小。我尝试如下:

import seaborn as sns
import numpy as np
import matplotlib.pyplot as plt

data = np.random.rand(200, 10)

fig, ax = plt.subplots()
fig.set_size_inches(38.5, 10.5)

ax2 = sns.heatmap(data, ax=ax)
for item in ax2.get_yticklabels():
    item.set_rotation(0)

这给了我相同的输出。我使用正确吗?

【问题讨论】:

是否可以只打印 5 个或 10 个中的 1 个? 不,我想将它们全部显示出来,这很棘手,我想。 你可以把它切成两半,然后在右边画一半,在另一边画一半? 但是我怎么知道哪个标签属于哪一行呢?在理想的世界中,我可以选择:cellheight = seizeOfYticklabel 如果您希望所有这些标签都可见,您显然需要更多空间。您是否尝试过简单地增加图形高度? 【参考方案1】:

为标签腾出更多空间的唯一方法是增加矩阵的高度。唯一的其他选择是减小字体大小,但我想这不是你想要的。 因此,您可以根据矩阵中的行数和标签的字体大小来计算理想的图形高度。当您保存结果图时,您会得到预期的结果。您在调用plt.show() 时看到的GUI 窗口的高度似乎仅限于屏幕高度:

import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

# create some random data
data = np.random.rand(150, 10)

# get the tick label font size
fontsize_pt = plt.rcParams['ytick.labelsize']
dpi = 72.27

# comput the matrix height in points and inches
matrix_height_pt = fontsize_pt * data.shape[0]
matrix_height_in = matrix_height_pt / dpi

# compute the required figure height 
top_margin = 0.04  # in percentage of the figure height
bottom_margin = 0.04 # in percentage of the figure height
figure_height = matrix_height_in / (1 - top_margin - bottom_margin)


# build the figure instance with the desired height
fig, ax = plt.subplots(
        figsize=(6,figure_height), 
        gridspec_kw=dict(top=1-top_margin, bottom=bottom_margin))

# let seaborn do it's thing
ax = sns.heatmap(data, ax=ax)

# save the figure
plt.savefig('/tmp/test.png')

结果:

【讨论】:

太棒了!正是我想要的!我现在赞成它,以后可能会接受它,这取决于其他答案的质量。编辑:您可能还想将旋转 yticklabels 的方式添加到代码中。 很高兴我能帮上忙。在您的示例中,您将旋转设置为 0,这是默认设置(因此设置它并没有真正做任何事情)。测量旋转文本对象的文本高度会困难得多,因为它取决于字体系列等其他因素...... 那么我们可能有不同版本的seaborn。看来,我需要rotation=0 才能获得水平输出。 是的,看起来是这样。我不经常使用它,所以我可能有一个过时的版本(0.7.dev)......顺便说一句:pyplot 提供了一个方便的功能来设置多个艺术家的属性,您可以使用它来使旋转设置更加紧凑: plt.setp(ax.get_yticklabels(), 'rotation', 0) 哦,很高兴知道,谢谢!不幸的是,我只能投票一次;)

以上是关于重叠 yticklabels:是不是可以控制 seaborn 中热图的单元格大小?的主要内容,如果未能解决你的问题,请参考以下文章

用protel做PCB图怎样允许元件重叠

检查范围是不是重叠

三角形三角形重叠(但不是边缘)

Vue Element UI el-table 样式属性重叠发生错位

单独初始化的字符串变量是不是可以重叠?

当来自不同实体类型的 ID 重叠时,是不是可以将 @JsonIdentityInfo 与 ObjectIdGenerators.PropertyGenerator 一起使用?