pandas 是否基于分组创建层次聚类热图?

wz3gfoph  于 2023-01-04  发布在  其他
关注(0)|答案(1)|浏览(132)

我正在尝试创建热图,如下图所示,其中右侧颜色条分为4组:一个月一个月Ra > Control > Rv; Ra > Rv > Control热图是使用欧氏距离矩阵均值中心化和对数基2转换FPKM归一化执行的。如何创建看起来像是基于上述分组排列的热图?

FPKM表格示例;注意,数据实际上是85行× 3列
| 基因|对照组|拉|保留|
| - ------|- ------|- ------|- ------|
| Cyp27a1| 32 681 000美元|四点五二六一六|十三|
| 丝氨酸蛋白酶B2| 1.611980年|小行星513|二○七六九九|
| 兔7 b|一百一十八九十六万四千元|二○七八六九零|四十三|
| Ptgs2| 0.328475美元|371.33000美元|二十九零九四一|
| Mgat4a|六、六八零零七零|七十零九五三零|二十五九三一|
| 乙酰水杨酸1| 15.459900美元|小行星431.43400|小行星186.2550|
| 气体6|小行星82042200|八点三九一六九|十七点三二二〇|
| 凋亡相关因子2a 1a|四、十六万二千四百八十|395.83800美元|九十九点九四三九|
| 三羟甲基苯甲酸|七点四五四零一○| 43.01970|十八点七一六二|
| Bcl2a1d| 15.641200英镑|小行星440.349|小行星109.8670|
以下是我目前所做的工作:

df.set_index('gene', inplace=True)
df[['Control', 'Ra','Rv']] = df_deg[['Control', 'Ra','Rv']].add(1).apply(np.log2) # FPKM +1 and log transformed
df_cent = df.apply(lambda x:x-x.mean()) # mean centered

## Heatmap ##
map_plt= sns.clustermap(df_cent, metric="euclidean", cmap="RdBu_r", vmin=-8, vmax=6, 
               xticklabels=True, yticklabels=False)
map_plt.ax_col_dendrogram.set_visible(False)
plt.show()

我的是这样的:

我不得不扩大最小值和最大值,否则它看起来像一个巨大的红色方块。还有,我做的均值中心和log 2转换正确吗?谢谢。

mcvgt66p

mcvgt66p1#

row_colors需要以原始顺序给出。Seaborn将重新计算顺序以与树状图中的行重新排序一致。您可以通过迭代列来创建它们。
下面是一个示例,说明它在您的情况下如何工作。请检查条件是否需要使用df_centdf。您可能需要调整不同元素的位置。

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

df = pd.read_html('https://stackoverflow.com/questions/74980890')[0]

df = df.set_index('gene')
df[['Control', 'Ra', 'Rv']] = df[['Control', 'Ra', 'Rv']].add(1).apply(np.log2)  # FPKM +1 and log transformed
df_cent = df.apply(lambda x: x - x.mean())  # mean centered

legend_labels = ['Control > Rv, Ra', 'Rv > Ra > Control', 'Ra > Control > Rv', 'Ra > Rv > Control']
legend_colors = ['gold', 'crimson', 'limegreen', 'cornflowerblue', 'black']
row_colors = [legend_colors[0] if Control > Rv and Control > Ra else  # or maybe 'Control > Rv or Control > Ra' ????
              legend_colors[1] if Rv > Ra > Control else
              legend_colors[2] if Ra > Control > Rv else
              legend_colors[3] if Ra > Rv > Control else
              legend_colors[4]
              for Control, Ra, Rv in zip(df_cent['Control'], df_cent['Ra'], df_cent['Rv'])]

norm = TwoSlopeNorm(vcenter=0, vmin=-8, vmax=6)
g = sns.clustermap(df_cent, metric="euclidean", cmap="RdBu_r", norm=norm,
                   xticklabels=True, yticklabels=False,
                   dendrogram_ratio=(0.25, 0.15),  # fraction of the figure dedicated to row and column dendrograms
                   row_colors=row_colors,
                   col_cluster=False,
                   cbar_pos=[.4, .95, .5, .03],  # x, y, width, height in "figure coordinates"
                   cbar_kws={'orientation': "horizontal"})
# create a legend, use the row dendogram for positioning
legend_handles = [plt.Rectangle((0, 0), 0, 0, color=color, label=label)
                  for color, label in zip(legend_colors, legend_labels)]
g.ax_row_dendrogram.legend(title='Row Colors', handles=legend_handles, loc='lower left', bbox_to_anchor=(0, 1.02))
plt.show()

相关问题