我有两个组学数据集,我想比较它们。为此,我将一个绘制为聚类图,并从中提取顺序并将完全相同的基因绘制为热图,以便我可以在两个数据集之间进行直接比较。但是,我想显示两者的颜色条,但我似乎无法让它工作。
我使用 this 来组合两个图,并使用 this 来调整聚类图的颜色条,但这不能用作热图的函数。我正在玩 cbar_kws 但我不认为这能让我做我想做的事,尽管我不完全理解我认为的潜力。
在 VScode 中使用 python;
import matplotlib.gridspec
#clustermap from averaged protein data!
g = sns.clustermap(hmprot, figsize=(8,12), col_cluster=False, yticklabels=True, cmap = 'viridis')
labels = [t.get_text() for t in g.ax_heatmap.yaxis.get_majorticklabels()]
g.gs.update(left=0.05, right=0.49)
#create new gridspec for the right part
gs2 = matplotlib.gridspec.GridSpec(1,1)
hmrna = hmrna.reindex(index=labels)
# create axes within this new gridspec
ax2 = g.fig.add_subplot(gs2[0])
# get position of heatmap
heatmap_bbox = g.ax_heatmap.get_position()
ax2.set_position([0.5, heatmap_bbox.y0, .35, heatmap_bbox.height])
# plot heatmap in the new axes
sns.heatmap(hmrna, ax=ax2, cmap = 'viridis', cbar=True, yticklabels=True,
cbar_kws= dict(use_gridspec=False,location = 'right', shrink= 0.5))
#change font size for the genes on the y-axis
g.tick_params(axis='y', labelsize=6, labelright = False, right=False)
g.tick_params(axis='x', labelbottom = True, bottom=False)
ax2.tick_params(axis='y', labelsize=8, labelright=True, left=False, labelleft=False, labelrotation = 0)
ax2.tick_params(axis='x', labelbottom = True, bottom=False)
#then adjusting the labels for each axis individually
# g.set_xlabel(' ') -> Doesn't work
ax2.set_xlabel(' ')
ax2.set_title('RNAseq', weight="bold")
# ax2.set_title('Proteomics(C)', weight="bold") -> Doesn't work
x0, _y0, _w, _h = g.cbar_pos
g.ax_cbar.set_position([0.01, 0.04, 0.02, 0.1])
g.ax_cbar.set_title('Z-score')
g.ax_cbar.tick_params(axis='x', length=10)
title = "Clustermap of Protein (left) & RNA (right) " + str(GO_term)
plt.suptitle(title, weight="bold", fontsize=20, y=0.85)
fig.tight_layout()
plt.show()
我也尝试过here提到的建议,使用以下代码;
cbar_2_ax = fig.add_axes([0.95, 0.04, 0.02, 0.1])
cbar_2 = mp.colorbar(ax2, cax=cbar_2_ax)
然后我收到错误:'Axes' 对象没有属性 'get_array' 我不知道现在如何继续,我可能没有使用正确的函数来改变这个,但我还没有找到有效的东西。
此外,我还设法使用自己的标题“配置”热图,并删除了 x 轴上的“组”标签。我无法弄清楚如何对聚类图执行相同的操作,为其赋予自己的标题,并删除此“组”标签。热图的相同功能在这里不起作用。
我的代码的虚拟版本,可以为我复制问题。 如何修复正确的颜色条?
我的代码的一些虚拟版本复制了这个问题:
df = pd.DataFrame(np.random.randint(0,100,size=(100, 4)), columns=list('ABCD'))
df2 = pd.DataFrame(np.random.randint(0,100,size=(100, 4)), columns=list('ABCD'))
#clustermap from df1
g = sns.clustermap(df, figsize=(12,18), col_cluster=False, yticklabels=True, cmap = 'viridis')
g.gs.update(left=0.05, right=0.49)
#create new gridspec for the right part
gs2 = matplotlib.gridspec.GridSpec(1,1)
# create axes within this new gridspec
ax2 = g.fig.add_subplot(gs2[0])
# get position of heatmap
heatmap_bbox = g.ax_heatmap.get_position()
ax2.set_position([0.5, heatmap_bbox.y0, .35, heatmap_bbox.height])
# plot boxplot in the new axes
sns.heatmap(df2, ax=ax2, cmap = 'viridis', cbar=True, yticklabels=True,
cbar_kws= dict(use_gridspec=False,location = 'right', shrink= 0.5)
)
g.tick_params(axis='y', labelsize=6, labelright = False, right=False)
g.tick_params(axis='x', labelbottom = True, bottom=False)
ax2.tick_params(axis='y', labelsize=8, labelright=True, left=False, labelleft=False, labelrotation = 0)
ax2.tick_params(axis='x', labelbottom = True, bottom=False)
ax2.set_title('title', weight="bold") # Set a custom title
x0, _y0, _w, _h = g.cbar_pos
g.ax_cbar.set_position([0.01, 0.04, 0.02, 0.1])
g.ax_cbar.set_title('Z-score')
g.ax_cbar.tick_params(axis='x', length=10)
title = "Clustermap (left) & heatmap (right) "
plt.suptitle(title, weight="bold", fontsize=20, y=0.85)
fig.tight_layout()
plt.show()
下面您可以找到一些示例代码来调整布局并添加颜色条。
一些备注:
sns.clustermap
有一个参数cbar_pos
可以直接设置colobar的位置sns.clustermap
还有一个参数 dendrogram_ratio
定义行树状图和列树状图的空间(本例中没有使用列树状图,因此间距可以设置得更小)g.tick_params
更改所有子图的刻度。这可能会导致颜色条缺少刻度。要仅更改 clustermap 热图的刻度,您可以使用 g.ax_heatmap.tick_params()
g.ax_heatmap.set_title()
设置聚类图的标题g.ax_heatmap.set_xlabel('')
删除聚类图的标签(在原始图像中明显标记为“组”)相当不清楚的是,聚类图改变了行的顺序(它将“相似”的行放置得更近)。但右侧的热图及其行标签似乎仍然使用其原始顺序。
要将热图的行重新排序为与聚类图相同的顺序,可以提取聚类图的 y 刻度标签。然后,
df2.reindex(...)
对热图的行重新排序。由于刻度标签是字符串,因此下面的示例代码假设数据帧的索引是字符串。
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
import numpy as np
index = [f'r{i:02}' for i in range(50)]
df = pd.DataFrame(np.random.randint(0, 100, size=(50, 4)), columns=list('ABCD'), index=index)
df2 = pd.DataFrame(np.random.randint(0, 100, size=(50, 4)), columns=list('ABCD'), index=index)
# clustermap from df1
g = sns.clustermap(df, figsize=(12, 18), col_cluster=False, yticklabels=True, cmap='viridis',
dendrogram_ratio=(0.12, 0.04), # space for the left and top dendograms
cbar_pos=[0.02, 0.04, 0.02, 0.1])
g.ax_cbar.set_title('Z-score')
g.ax_heatmap.set_xlabel('') # remove possible xlabel
g.ax_heatmap.set_title('clustermap title', weight="bold", fontsize=16) # Set a custom title
# extract the order of the y tick labels of the clustermap (before removing the ticks)
new_index = [t.get_text() for t in g.ax_heatmap.get_yticklabels()]
# remove right ticks and tick labels of the clustermap
g.ax_heatmap.tick_params(axis='y', right=False, labelright=False)
g.ax_heatmap.tick_params(axis='x', labelbottom=True, bottom=False)
# get position of heatmap
heatmap_bbox = g.ax_heatmap.get_position()
# make space for the right heatmap by reducing the size of the clustermap's heatmap
g.ax_heatmap.set_position([heatmap_bbox.x0, heatmap_bbox.y0, 0.49 - heatmap_bbox.x0, heatmap_bbox.height])
ax2 = plt.axes([0.50, heatmap_bbox.y0, 0.38, heatmap_bbox.height])
cbar_2_ax = plt.axes([0.94, 0.04, 0.02, 0.1])
# plot heatmap in the new axes, reordering the rows similar as in the clustermap
sns.heatmap(df2.reindex(new_index), cmap='viridis', cbar=True, yticklabels=True, ax=ax2, cbar_ax=cbar_2_ax)
ax2.tick_params(axis='y', labelsize=8, labelright=True, left=False, labelleft=False, labelrotation=0)
ax2.tick_params(axis='x', labelbottom=True, bottom=False)
ax2.set_title('heatmap title', weight="bold", fontsize=16) # Set a custom title
cbar_2_ax.set_title('Z-score')
# title = "Clustermap (left) & heatmap (right)"
# plt.suptitle(title, weight="bold", fontsize=20)
plt.show()