在 Python 中对热图的刻度线进行分组
Grouping the tick marks for heatmaps in Python
我有一个看起来像这样的热图(来自:)。
我正在尝试创建一个没有每个值的刻度标签但按范围分组的热图。例如,前三个刻度线未签名但已与一个联合签名 'Apples'.
使用以下命令似乎很容易完全禁用滴答标签:
plt.tick_params(
axis='x',
which='both',
bottom=False,
top=False,
labelbottom=False)
或仅选择选定的刻度:
for (i,l) in enumerate(ax.xaxis.get_ticklabels()):
if i == 0 or i == 4 or i == 5:
l.set_visible(True)
else:
l.set_visible(False)
但是可以像下面那样做吗?
热图示例代码:
corr = np.corrcoef(np.random.randn(10, 200))
mask = np.zeros_like(corr)
mask[np.triu_indices_from(mask)] = True
with sns.axes_style("white"):
ax = sns.heatmap(corr, mask=mask, vmax=.3, square=True, cmap="YlGnBu")
plt.show()
您可以使用 x 轴变换来放置文本和绘制短线,x 位置使用数据坐标,y 位置使用轴坐标(底部为 0,顶部为 1)。默认情况下,文本不会被轴裁剪,但其他元素会被裁剪,因此它们需要 clip_on=False
才能在主绘图区域外可见。
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
corr = np.corrcoef(np.random.randn(10, 20))
corr[np.triu_indices_from(corr)] = np.nan
sns.set_style("white")
ax = sns.heatmap(corr, vmax=.3, square=True, cmap="YlGnBu",
annot=True, fmt='.2f', cbar_kws={'pad': 0})
labels = ['Apples', 'Oranges', 'Pears', 'Bananas']
label_lens = [4, 2, 1, 3]
ax.set_xticks([]) # remove the x ticks
ax.set_yticks([]) # remove the y ticks
pos = 0
for label, label_len in zip(labels, label_lens):
if pos != 0:
ax.vlines(pos, pos, len(corr), color='r', lw=2)
ax.vlines(pos, 0, -0.02, color='r', lw=2,
transform=ax.get_xaxis_transform(), clip_on=False)
ax.hlines(pos, 0, pos, color='r', lw=2)
ax.hlines(pos, 0, -0.02, color='r', lw=2,
transform=ax.get_yaxis_transform(), clip_on=False)
ax.text(pos + label_len / 2, -0.02, label, ha='center', va='top',
transform=ax.get_xaxis_transform())
ax.text(-0.02, pos + label_len / 2, label, ha='right', va='center', rotation=90,
transform=ax.get_yaxis_transform())
pos += label_len
plt.tight_layout()
plt.show()
我有一个看起来像这样的热图(来自:
我正在尝试创建一个没有每个值的刻度标签但按范围分组的热图。例如,前三个刻度线未签名但已与一个联合签名 'Apples'.
使用以下命令似乎很容易完全禁用滴答标签:
plt.tick_params(
axis='x',
which='both',
bottom=False,
top=False,
labelbottom=False)
或仅选择选定的刻度:
for (i,l) in enumerate(ax.xaxis.get_ticklabels()):
if i == 0 or i == 4 or i == 5:
l.set_visible(True)
else:
l.set_visible(False)
但是可以像下面那样做吗?
热图示例代码:
corr = np.corrcoef(np.random.randn(10, 200))
mask = np.zeros_like(corr)
mask[np.triu_indices_from(mask)] = True
with sns.axes_style("white"):
ax = sns.heatmap(corr, mask=mask, vmax=.3, square=True, cmap="YlGnBu")
plt.show()
您可以使用 x 轴变换来放置文本和绘制短线,x 位置使用数据坐标,y 位置使用轴坐标(底部为 0,顶部为 1)。默认情况下,文本不会被轴裁剪,但其他元素会被裁剪,因此它们需要 clip_on=False
才能在主绘图区域外可见。
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
corr = np.corrcoef(np.random.randn(10, 20))
corr[np.triu_indices_from(corr)] = np.nan
sns.set_style("white")
ax = sns.heatmap(corr, vmax=.3, square=True, cmap="YlGnBu",
annot=True, fmt='.2f', cbar_kws={'pad': 0})
labels = ['Apples', 'Oranges', 'Pears', 'Bananas']
label_lens = [4, 2, 1, 3]
ax.set_xticks([]) # remove the x ticks
ax.set_yticks([]) # remove the y ticks
pos = 0
for label, label_len in zip(labels, label_lens):
if pos != 0:
ax.vlines(pos, pos, len(corr), color='r', lw=2)
ax.vlines(pos, 0, -0.02, color='r', lw=2,
transform=ax.get_xaxis_transform(), clip_on=False)
ax.hlines(pos, 0, pos, color='r', lw=2)
ax.hlines(pos, 0, -0.02, color='r', lw=2,
transform=ax.get_yaxis_transform(), clip_on=False)
ax.text(pos + label_len / 2, -0.02, label, ha='center', va='top',
transform=ax.get_xaxis_transform())
ax.text(-0.02, pos + label_len / 2, label, ha='right', va='center', rotation=90,
transform=ax.get_yaxis_transform())
pos += label_len
plt.tight_layout()
plt.show()