【问题标题】:How to make a horizontal color track underneath a vertical bar plot in python如何在python中的垂直条形图下方制作水平颜色轨迹
【发布时间】:2021-08-07 15:18:52
【问题描述】:

我正在尝试制作一个如下所示的条形图:vertical stacked barplot with a horizontal bar underneath

我使用以下代码在 python 中制作了实际的垂直条形图:

fig, ax = plt.subplots(figsize=[15, 5])
width = 0.75   
ax.bar(labels, my_order["relapse"], width, label=SAMPLE[0], color = "r")
ax.bar(labels, my_order['remission'], width, bottom=my_order['relapse'], label=SAMPLE[1], color = "orange")
ax.set_title('Ratio of cells by patient in each cluster')
ax.legend(bbox_to_anchor=(1.01,0.5), loc='center left') 

my_order 是一个数据框,其中包含一个包含复发数字的列和一个缓解数字的列。我无法创建的部分是下面的单杠。这将根据不同条的其他属性进行着色(每个条代表一个集群,在这种情况下,如果集群具有一个属性,我希望将水平图着色为蓝色,如果它具有另一个属性,则将其着色为黄色)。有谁知道这是否可以在 python 中完成?或者如果我必须手动执行此操作?在完整的数据集中,整个图中大约有 50 个条形图,因此找到一种不手动执行此操作的方法会很棒。

【问题讨论】:

    标签: python matplotlib plot graph


    【解决方案1】:

    您可以遍历每个条形位置,并创建一个与条形宽度相同但略低于绘图的彩色矩形。

    rectangle 有以下参数:

    • (x, y), width, height
    • transform=ax.get_xaxis_transform():在 x 方向上,值以 "data coordinates" 测量,这里是 0, 1, 2, ... 用于柱位置;在 y 方向上使用“轴坐标”,从顶部的 1 到绘图区域底部的 0,并在下方的位置使用负数
    • clip_on=False:通常情况下,当某些东西放在绘图区域之外时,它会被剪掉; clip_on=False 会覆盖该行为
    • facecolor=...:内饰颜色
    • edgecolor='black':黑色边框
    from matplotlib import pyplot as plt
    import pandas as pd
    import numpy as np
    
    labels = [*'abcdefghijklmnopqrst']
    my_order = pd.DataFrame({'relapse': np.random.randint(11, 51, 20),
                             'remission': np.random.randint(11, 51, 20),
                             'cluster': np.random.randint(1, 3, 20)})
    fig, ax = plt.subplots(figsize=[15, 5])
    width = 0.75
    ax.bar(labels, my_order['relapse'], width, label='SAMPLE[0]', color='crimson')
    ax.bar(labels, my_order['remission'], width, bottom=my_order['relapse'], label='SAMPLE[1]', color='orange')
    ax.set_title('Ratio of cells by patient in each cluster')
    legend1 = ax.legend(title='Samples', bbox_to_anchor=(1.01, 0.5), loc='center left')
    ax.margins(x=0.01)
    color_for_cluster = {1: 'skyblue', 2: 'yellow'}
    for i, cluster in enumerate(my_order['cluster']):
        ax.add_patch(plt.Rectangle((i - width / 2, -0.1), width, 0.02,
                                   facecolor=color_for_cluster[cluster], edgecolor='black',
                                   transform=ax.get_xaxis_transform(), clip_on=False))
    handles = [plt.Rectangle((0, 0), 0, 0, facecolor=color_for_cluster[cluster], edgecolor='black', label=cluster)
               for cluster in color_for_cluster]
    legend2 = ax.legend(handles=handles, title='Clusters', bbox_to_anchor=(1.01, -0.01), loc='lower left')
    ax.add_artist(legend1)  # add the legend again, because the second call to ax.legend removes the first legend
    fig.tight_layout()
    plt.show()
    

    您也可以使用plt.Rectangle((i - 1/2, -0.1), 1, 0.02, ...) 使矩形占据整个宽度。

    【讨论】:

    • 谢谢!!效果很好!你知道如何为补丁颜色添加单独的图例吗??
    • 我真的想出了第二个图例——谢谢你的帮助!
    猜你喜欢
    • 2021-05-03
    • 2015-03-06
    • 2011-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-24
    • 2019-07-02
    相关资源
    最近更新 更多