【问题标题】:Plotting multiple seaborn heatmaps with individual color bar使用单独的颜色条绘制多个 seaborn 热图
【发布时间】:2021-01-17 13:19:38
【问题描述】:

是否可以将多个 seaborn 热图绘制成一个图形,具有共享的 yticklabel 和单独的颜色条,如下图所示?

我可以做的是使用以下代码单独绘制热图:

#图一

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

【问题讨论】:

    标签: python seaborn heatmap subplot colorbar


    【解决方案1】:

    Seaborn 基于 matplotlib 构建,可用于进一步自定义绘图。 plt.subplots(ncols=3, sharey=True, ...) 创建三个具有共享 y 轴的子图。将 ax=ax1 添加到 sns.heatmap(..., ax=...) 会在所需的子图上创建热图。请注意sns.heatmap 的返回值与ax 相同。

    以下代码显示了一个示例。 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()
    

    【讨论】:

    • 非常非常感谢!! :D
    【解决方案2】:

    您可以连接两个数据框并将FacetGridFacetGrid.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.frames,并为每个数据帧的配色方案设置一个字典:

    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)
    

    【讨论】:

    • 非常非常感谢!! :D
    猜你喜欢
    • 2018-06-03
    • 1970-01-01
    • 2015-04-06
    • 1970-01-01
    • 2018-05-07
    • 2016-07-20
    • 2022-01-27
    • 2021-07-06
    • 2020-06-21
    相关资源
    最近更新 更多