简体   繁体   English

使用单独的颜色条绘制多个 seaborn 热图

[英]Plotting multiple seaborn heatmaps with individual color bar

Is it possible to plot multiple seaborn heatmaps into a single figure, with a shared yticklabel, and individual color bars, like the figure below?是否可以将多个 seaborn 热图绘制成一个图形,使用共享的 yticklabel 和单独的颜色条,如下图所示?

在此处输入图片说明

What I can do is to plot the heatmaps individually, using the following code:我能做的是使用以下代码单独绘制热图:

#Figure 1 #图1

plt.figure()
sns.set()
comp = sns.heatmap(df, cmap="coolwarm", linewidths=.5, xticklabels=True, yticklabels=True, cbar_kws={"orientation": "horizontal", "label": "Pathway completeness", "pad": 0.004})
comp.set_xticklabels(comp.get_xticklabels(), rotation=-90)
comp.xaxis.tick_top() # x axis on top
comp.xaxis.set_label_position('top')
cbar = comp.collections[0].colorbar
cbar.set_ticks([0, 50, 100])
cbar.set_ticklabels(['0%', '50%', '100%'])          
figure = comp.get_figure()
figure.savefig("hetmap16.png", format='png', bbox_inches='tight')

#Figure 2 (figure 3 is the same, but with a different database) #图2(图3相同,只是数据库不同)

plt.figure()
sns.set()
df = pd.DataFrame(heatMapFvaMinDictP)
fvaMax = sns.heatmap(df, cmap="rocket_r", linewidths=.5, xticklabels=True, cbar_kws={"orientation": "horizontal", "label": "Minimum average flux", "pad": 0.004})
fvaMax.set_xticklabels(fvaMax.get_xticklabels(), rotation=-90)
fvaMax.xaxis.tick_top() # x axis on top
fvaMax.xaxis.set_label_position('top')
fvaMax.tick_params(axis='y', labelleft=False)
figure = fvaMax.get_figure()
figure.savefig("fva1.png", format='png', bbox_inches='tight')

Seaborn builds upon matplotlib, which can be used for further customizing plots. Seaborn 基于 matplotlib 构建,可用于进一步自定义绘图。 plt.subplots(ncols=3, sharey=True, ...) creates three subplots with a shared y-axis. plt.subplots(ncols=3, sharey=True, ...)创建三个共享 y 轴的子图。 Adding ax=ax1 to sns.heatmap(..., ax=...) creates the heatmap on the desired subplot.ax=ax1添加到sns.heatmap(..., ax=...)在所需的子图上创建热图。 Note that the return value of sns.heatmap is again that same ax .请注意, sns.heatmap的返回值再次与ax相同。

The following code shows an example.以下代码显示了一个示例。 vmin and vmax are explicitly set for the first heatmap to make sure that both values will appear in the colorbar (the default colorbar runs between the minimum and maximum of the encountered values).为第一个热图明确设置了vminvmax ,以确保两个值都出现在颜色条中(默认颜色条在遇到的值的最小值和最大值之间运行)。

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

sns.set()
fig, (ax1, ax2, ax3) = plt.subplots(ncols=3, sharey=True, figsize=(20, 8))

N = 20
labels = [''.join(np.random.choice(list('abcdefghi '), 40)) for _ in range(N)]
df = pd.DataFrame({'column 1': np.random.uniform(0, 100, N), 'column 2': np.random.uniform(0, 100, N)},
                  index=labels)
sns.heatmap(df, cmap="coolwarm", linewidths=.5, xticklabels=True, yticklabels=True, ax=ax1, vmin=0, vmax=100,
            cbar_kws={"orientation": "horizontal", "label": "Pathway completeness", "pad": 0.004})
ax1.set_xticklabels(ax1.get_xticklabels(), rotation=-90)
ax1.xaxis.tick_top()  # x axis on top
ax1.xaxis.set_label_position('top')
cbar = ax1.collections[0].colorbar
cbar.set_ticks([0, 50, 100])
cbar.set_ticklabels(['0%', '50%', '100%'])

for ax in (ax2, ax3):
    max_value = 10 if ax == ax2 else 1000
    df = pd.DataFrame({'column 1': np.random.uniform(0, max_value, N), 'column 2': np.random.uniform(0, max_value, N)},
                      index=labels)
    sns.heatmap(df, cmap="rocket_r", linewidths=.5, xticklabels=True, ax=ax,
                cbar_kws={"orientation": "horizontal", "pad": 0.004,
                          "label": ("Minimum" if ax == ax2 else "Minimum") + " average flux"})
    ax.set_xticklabels(ax.get_xticklabels(), rotation=-90)
    ax.xaxis.tick_top()  # x axis on top
    ax.xaxis.set_label_position('top')

plt.tight_layout()
fig.savefig("subplots.png", format='png', bbox_inches='tight')
plt.show()

示例图

You can concatenate the two dataframes and use FacetGrid with FacetGrid.map_dataframe , and I guess you might need to adjust the aesthetics a bit.您可以连接两个数据FacetGrid并将FacetGridFacetGrid.map_dataframe FacetGrid使用,我想您可能需要稍微调整一下美感。 Don't have your data so I try it with an example data:没有您的数据,所以我用示例数据尝试一下:

import pandas as pd
import numpy as np
import seaborn as sns

np.random.seed(111)
df1 = pd.DataFrame({'A':np.random.randn(15),'B':np.random.randn(15)},
                   index=['row_variable'+str(i+1) for i in range(15)])

df2 = pd.DataFrame({'A':np.random.randn(15),'B':np.random.randn(15)},
                   index=['row_variable'+str(i+1) for i in range(15)])

We annotate the data.frames with a column indicating the database like you have, and also set a dictionary for the color schemes for each dataframes:我们用一列来注释 data.frames ,指示您拥有的数据库,并为每个数据帧的配色方案设置一个字典:

df1['database'] = "database1"
df2['database'] = "database2"

dat = pd.concat([df1,df2])
cdict = {'database1':'rocket_r','database2':'coolwarm'}

And define a function to draw the heatmap:并定义一个函数来绘制热图:

def heat(data,color):
    sns.heatmap(data[['A','B']],cmap=cdict[data['database'][0]],
                cbar_kws={"orientation": "horizontal"})

Then facet:然后方面:

fg = sns.FacetGrid(data=dat, col='database',aspect=0.7,height=4)
fg.map_dataframe(heat)

在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM