如何在 Seaborn 的热图轴上表达 类
How to express classes on the axis of a heatmap in Seaborn
我用 Seaborn 创建了一个非常简单的热图图表,显示了一个相似性方阵。这是我使用的一行代码:
sns.heatmap(sim_mat, linewidths=0, square=True, robust=True)
sns.plt.show()
这是我得到的输出:
我想要做的是在 x 和 y 轴上表示不是我的实例的标签,而是一个彩色指示器(想象一下像每个轴上的小触动图),其中每种颜色代表另一个关联的变量每个实例(假设我将此信息存储在一个名为 labels
的列表中)加上此类信息的另一个图例,旁边是指定热图颜色的图例(类似于 lmplot
的那个)。重要的是,这两个信息具有不同的调色板。
这在 Seaborn 中可行吗?
更新
我正在寻找的是正确建议的 clustermap
。
sns.clustermap(sim_mat, row_colors=label_cols, col_colors=label_cols
row_cluster=False, col_cluster=False)
这是我得到的顺便说一句,点和线太小,我在文档中看不到放大它们的方法。我想
另外,如何添加图例并将两个并排放置在同一位置?
有两种选择:
首先,heatmap
是一个轴级别图,因此您可以为相关矩阵设置一个主要的大型主热图轴,并在其两侧放置热图,然后将 class 颜色传递给自己.这将需要一些工作,但可以让您充分控制一切的运作方式。
虽然这或多或少是 clustermap
中的一个选项,所以我将在这里演示如何这样做。这有点 hack,但它会起作用。
首先,我们将加载示例数据并进行一些迂回转换以获得 class 标签的颜色。
networks = sns.load_dataset("brain_networks", index_col=0, header=[0, 1, 2])
network_labels = networks.columns.get_level_values("network")
network_pal = sns.cubehelix_palette(network_labels.unique().size,
light=.9, dark=.1, reverse=True,
start=1, rot=-2)
network_lut = dict(zip(map(str, network_labels.unique()), network_pal))
network_colors = pd.Series(network_labels).map(network_lut)
接下来调用clustermap
制作主线
g = sns.clustermap(networks.corr(),
# Turn off the clustering
row_cluster=False, col_cluster=False,
# Add colored class labels
row_colors=network_colors, col_colors=network_colors,
# Make the plot look better when many rows/cols
linewidths=0, xticklabels=False, yticklabels=False)
侧面颜色是用热图绘制的,matplotlib 将其视为定量数据,因此没有直接从中获取图例的直接方法。相反,我们将添加一个带有正确颜色和标签的不可见条形图,然后为 that.
添加图例
for label in network_labels.unique():
g.ax_col_dendrogram.bar(0, 0, color=network_lut[label],
label=label, linewidth=0)
g.ax_col_dendrogram.legend(loc="center", ncol=6)
最后,让我们移动颜色条以占据行树状图通常所在的空白 space 并保存图形。
g.cax.set_position([.15, .2, .03, .45])
g.savefig("clustermap.png")
在 的基础上,我认为值得注意标签的多个颜色级别的可能性 - 正如 clustermap 文档 ({row,col}_colors) 中所述。我找不到多层次的例子,所以我想在这里分享一个例子。
networks = sns.load_dataset("brain_networks", index_col=0, header=[0, 1, 2])
网络等级
network_labels = networks.columns.get_level_values("network")
network_pal = sns.cubehelix_palette(network_labels.unique().size, light=.9, dark=.1, reverse=True, start=1, rot=-2)
network_lut = dict(zip(map(str, network_labels.unique()), network_pal))
使用网络列创建索引
network_colors = pd.Series(network_labels, index=networks.columns).map(network_lut)
节点级别
node_labels = networks.columns.get_level_values("node")
node_pal = sns.cubehelix_palette(node_labels.unique().size)
node_lut = dict(zip(map(str, node_labels.unique()), node_pal))
使用节点的列创建索引
node_colors = pd.Series(node_labels, index=networks.columns).map(node_lut)
为行和列颜色级别创建数据框
network_node_colors = pd.DataFrame(network_colors).join(pd.DataFrame(node_colors))
创建clustermap
g = sns.clustermap(networks.corr(),
# Turn off the clustering
row_cluster=False, col_cluster=False,
# Add colored class labels using data frame created from node and network colors
row_colors = network_node_colors,
col_colors = network_node_colors,
# Make the plot look better when many rows/cols
linewidths=0,
xticklabels=False, yticklabels=False,
center=0, cmap="vlag")
创建两个图例 - 通过创建不可见的列和行条形图(如上所述)每个级别一个图例
网络传奇
from matplotlib.pyplot import gcf
for label in network_labels.unique():
g.ax_col_dendrogram.bar(0, 0, color=network_lut[label], label=label, linewidth=0)
l1 = g.ax_col_dendrogram.legend(title='Network', loc="center", ncol=5, bbox_to_anchor=(0.47, 0.8), bbox_transform=gcf().transFigure)
节点图例
for label in node_labels.unique():
g.ax_row_dendrogram.bar(0, 0, color=node_lut[label], label=label, linewidth=0)
l2 = g.ax_row_dendrogram.legend(title='Node', loc="center", ncol=2, bbox_to_anchor=(0.8, 0.8), bbox_transform=gcf().transFigure)
plt.show()
当两个树状图都使用时,还可以添加一个新的隐藏轴并绘制图例。
ax= f.add_axes((0,0,0,0))
ax.xaxis.set_visible(False)
ax.yaxis.set_visible(False)
for label in node_labels.unique():
ax.bar(0, 0, color=node_lut[label], label=label, linewidth=0)
l2 = g.ax_row_dendrogram.legend(title='Node', loc="center", ncol=2, bbox_to_anchor=(0.8, 0.8), bbox_transform=f.transFigure)
我用 Seaborn 创建了一个非常简单的热图图表,显示了一个相似性方阵。这是我使用的一行代码:
sns.heatmap(sim_mat, linewidths=0, square=True, robust=True)
sns.plt.show()
这是我得到的输出:
我想要做的是在 x 和 y 轴上表示不是我的实例的标签,而是一个彩色指示器(想象一下像每个轴上的小触动图),其中每种颜色代表另一个关联的变量每个实例(假设我将此信息存储在一个名为 labels
的列表中)加上此类信息的另一个图例,旁边是指定热图颜色的图例(类似于 lmplot
的那个)。重要的是,这两个信息具有不同的调色板。
这在 Seaborn 中可行吗?
更新
我正在寻找的是正确建议的 clustermap
。
sns.clustermap(sim_mat, row_colors=label_cols, col_colors=label_cols
row_cluster=False, col_cluster=False)
这是我得到的顺便说一句,点和线太小,我在文档中看不到放大它们的方法。我想
另外,如何添加图例并将两个并排放置在同一位置?
有两种选择:
首先,heatmap
是一个轴级别图,因此您可以为相关矩阵设置一个主要的大型主热图轴,并在其两侧放置热图,然后将 class 颜色传递给自己.这将需要一些工作,但可以让您充分控制一切的运作方式。
虽然这或多或少是 clustermap
中的一个选项,所以我将在这里演示如何这样做。这有点 hack,但它会起作用。
首先,我们将加载示例数据并进行一些迂回转换以获得 class 标签的颜色。
networks = sns.load_dataset("brain_networks", index_col=0, header=[0, 1, 2])
network_labels = networks.columns.get_level_values("network")
network_pal = sns.cubehelix_palette(network_labels.unique().size,
light=.9, dark=.1, reverse=True,
start=1, rot=-2)
network_lut = dict(zip(map(str, network_labels.unique()), network_pal))
network_colors = pd.Series(network_labels).map(network_lut)
接下来调用clustermap
制作主线
g = sns.clustermap(networks.corr(),
# Turn off the clustering
row_cluster=False, col_cluster=False,
# Add colored class labels
row_colors=network_colors, col_colors=network_colors,
# Make the plot look better when many rows/cols
linewidths=0, xticklabels=False, yticklabels=False)
侧面颜色是用热图绘制的,matplotlib 将其视为定量数据,因此没有直接从中获取图例的直接方法。相反,我们将添加一个带有正确颜色和标签的不可见条形图,然后为 that.
添加图例for label in network_labels.unique():
g.ax_col_dendrogram.bar(0, 0, color=network_lut[label],
label=label, linewidth=0)
g.ax_col_dendrogram.legend(loc="center", ncol=6)
最后,让我们移动颜色条以占据行树状图通常所在的空白 space 并保存图形。
g.cax.set_position([.15, .2, .03, .45])
g.savefig("clustermap.png")
在
networks = sns.load_dataset("brain_networks", index_col=0, header=[0, 1, 2])
网络等级
network_labels = networks.columns.get_level_values("network")
network_pal = sns.cubehelix_palette(network_labels.unique().size, light=.9, dark=.1, reverse=True, start=1, rot=-2)
network_lut = dict(zip(map(str, network_labels.unique()), network_pal))
使用网络列创建索引
network_colors = pd.Series(network_labels, index=networks.columns).map(network_lut)
节点级别
node_labels = networks.columns.get_level_values("node")
node_pal = sns.cubehelix_palette(node_labels.unique().size)
node_lut = dict(zip(map(str, node_labels.unique()), node_pal))
使用节点的列创建索引
node_colors = pd.Series(node_labels, index=networks.columns).map(node_lut)
为行和列颜色级别创建数据框
network_node_colors = pd.DataFrame(network_colors).join(pd.DataFrame(node_colors))
创建clustermap
g = sns.clustermap(networks.corr(),
# Turn off the clustering
row_cluster=False, col_cluster=False,
# Add colored class labels using data frame created from node and network colors
row_colors = network_node_colors,
col_colors = network_node_colors,
# Make the plot look better when many rows/cols
linewidths=0,
xticklabels=False, yticklabels=False,
center=0, cmap="vlag")
创建两个图例 - 通过创建不可见的列和行条形图(如上所述)每个级别一个图例
网络传奇
from matplotlib.pyplot import gcf
for label in network_labels.unique():
g.ax_col_dendrogram.bar(0, 0, color=network_lut[label], label=label, linewidth=0)
l1 = g.ax_col_dendrogram.legend(title='Network', loc="center", ncol=5, bbox_to_anchor=(0.47, 0.8), bbox_transform=gcf().transFigure)
节点图例
for label in node_labels.unique():
g.ax_row_dendrogram.bar(0, 0, color=node_lut[label], label=label, linewidth=0)
l2 = g.ax_row_dendrogram.legend(title='Node', loc="center", ncol=2, bbox_to_anchor=(0.8, 0.8), bbox_transform=gcf().transFigure)
plt.show()
当两个树状图都使用时,还可以添加一个新的隐藏轴并绘制图例。
ax= f.add_axes((0,0,0,0))
ax.xaxis.set_visible(False)
ax.yaxis.set_visible(False)
for label in node_labels.unique():
ax.bar(0, 0, color=node_lut[label], label=label, linewidth=0)
l2 = g.ax_row_dendrogram.legend(title='Node', loc="center", ncol=2, bbox_to_anchor=(0.8, 0.8), bbox_transform=f.transFigure)