是否可以将多个seaborn热图绘制到一个具有共享ytick标签和单个彩条的图形中,如下图所示?
我可以做的是使用以下代码分别绘制热图:
#图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')
#图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')
答案 0 :(得分:1)
Seaborn基于matplotlib构建,可用于进一步自定义图。 plt.subplots(ncols=3, sharey=True, ...)
创建三个共享y轴的子图。将ax=ax1
添加到sns.heatmap(..., ax=...)
会在所需子图上创建热图。请注意,sns.heatmap
的返回值还是相同的ax
。
以下代码显示了一个示例。为第一个热图显式设置了vmin
和vmax
,以确保两个值都将出现在颜色栏中(默认颜色条在遇到的最小值和最大值之间运行)。
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()
答案 1 :(得分:1)
您可以将两个数据帧连接起来,并将FacetGrid
与FacetGrid.map_dataframe一起使用,我想您可能需要稍微调整一下外观。没有您的数据,因此我尝试使用示例数据:
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)])
我们用一列为data.frame注释,表明与您一样的数据库,并为每个数据帧的配色方案设置字典:
df1['database'] = "database1"
df2['database'] = "database2"
dat = pd.concat([df1,df2])
cdict = {'database1':'rocket_r','database2':'coolwarm'}
并定义一个绘制热图的函数:
def heat(data,color):
sns.heatmap(data[['A','B']],cmap=cdict[data['database'][0]],
cbar_kws={"orientation": "horizontal"})
接下来的方面:
fg = sns.FacetGrid(data=dat, col='database',aspect=0.7,height=4)
fg.map_dataframe(heat)