如何在Seaborn的热图轴上表达类

时间:2015-01-16 16:51:49

标签: python matplotlib heatmap seaborn

我创建了一个非常简单的热图图表,Seaborn显示了相似性方阵。这是我使用的一行代码:

sns.heatmap(sim_mat, linewidths=0, square=True, robust=True)
sns.plt.show()

这是我得到的输出:

enter image description here

我想要做的是在x和y轴上表示我的实例的标签,而不是彩色指示器(想象每个轴上的一个小的palplot),其中每种颜色代表与之相关的另一个变量。每个实例(让我说这个信息存储了一个名为labels的列表)加上另一个图例,这个信息旁边的那个信息指定了热图的颜色(一个像{{1 }})。重要的是这两种信息具有不同的调色板。

Seaborn有可能吗?

更新

我正在寻找的是正确建议的lmplot

clustermap

这是我得到的顺序,点和线太小,我没有看到在文档中放大它们的方法。我想

另外,如何添加图例并将两个图例放在另一个图例的相同位置?

enter image description here

3 个答案:

答案 0 :(得分:20)

有两种选择:

首先,heatmap是一个Axes级别的数字,因此您可以为相关矩阵设置一个主要的大型主热图轴,并在其后面加上热图,然后将类颜色传递给自己。这将是一些工作,但让你可以控制一切的工作方式。

这或多或少是clustermap中的一个选项,所以我将在这里演示如何做到这一点。这有点像黑客,但它会奏效。

首先,我们将加载示例数据并进行一些环形转换以获取类标签的颜色。

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认为它是定量数据,因此不是直接从中获取图例的简单方法。而不是那样,我们将添加一个带有正确颜色和标签的隐形条形图,然后为 添加一个图例。

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)

最后,让我们移动颜色条以占据行树形图通常所在的空白区域并保存图形。

g.cax.set_position([.15, .2, .03, .45])
g.savefig("clustermap.png")

enter image description here

答案 1 :(得分:1)

above answer的基础上,我认为值得注意的是标签具有多种颜色级别的可能性-如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")

创建两个图例-通过创建不可见的列和行条形图,每个级别对应一个图例(如上所述)

网络传奇

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()

enter image description here

答案 2 :(得分:0)

同时使用两个树状图时,还可以添加新的隐藏轴并绘制图例。

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)