【问题标题】:Multiple Bar Plot using Seaborn使用 Seaborn 的多条形图
【发布时间】:2021-05-02 03:36:43
【问题描述】:

我在 seaborn 中使用 3 个数据集制作了一个条形图,但是每个数据点都覆盖了前一个数据点,无论它现在是否隐藏了前一个图。例如:

sns.barplot(x="Portfolio", y="Factor", data=d2,
            label="Portfolio", color="g")

sns.barplot(x="Benchmark", y="Factor", data=d2,
            label="Benchmark", color="b")

sns.barplot(x="Active Exposure", y="Factor", data=d2,
            label="Active", color="r")

ax.legend(frameon=True)
ax.set(xlim=(-.1, .5), ylabel="", xlabel="Sector Decomposition")
sns.despine(left=True, bottom=True)

但是,我希望它显示为绿色,即使覆盖的蓝色更大。有什么想法吗?

【问题讨论】:

    标签: python matplotlib seaborn


    【解决方案1】:

    无法查看您的数据,我只能猜测您的数据框不是长格式。 seaborn tutorial 上有一个部分介绍 seaborn 期望的 DataFrames 的预期形状,我会在那里查看更多信息,特别是 messy data 部分。


    因为我看不到你的 DataFrame,所以我对它的形状做了一些假设:

    import numpy as np
    import pandas as pd
    import seaborn as sns
    
    df = pd.DataFrame({
        "Factor": list("ABC"),
        "Portfolio": np.random.random(3),
        "Benchmark": np.random.random(3),
        "Active Exposure": np.random.random(3),
    })
    #    Active Exposure  Benchmark Factor  Portfolio
    # 0         0.140177   0.112653      A   0.669687
    # 1         0.823740   0.078819      B   0.072474
    # 2         0.450814   0.702114      C   0.039068
    

    我们可以melt这个DataFrame来获取seaborn想要的长格式数据:

    d2 = df.melt(id_vars="Factor", var_name="exposure")
    #   Factor         exposure     value
    # 0      A  Active Exposure  0.140177
    # 1      B  Active Exposure  0.823740
    # 2      C  Active Exposure  0.450814
    # 3      A        Benchmark  0.112653
    # 4      B        Benchmark  0.078819
    # 5      C        Benchmark  0.702114
    # 6      A        Portfolio  0.669687
    # 7      B        Portfolio  0.072474
    # 8      C        Portfolio  0.039068
    

    然后,最后我们可以使用 seaborn 的内置聚合绘制箱线图:

    ax = sns.barplot(x="value", y="Factor", hue="exposure", data=d2)
    ax.set(ylabel="", xlabel="Sector Decomposition")
    ax.legend(loc='center left', bbox_to_anchor=(1, 0.5))
    

    产生:


    这是我用来制作此图表的绘图参数:

    import matplotlib as mpl
    
    # Plot configuration
    mpl.style.use("seaborn-pastel")
    mpl.rcParams.update(
        {
            "font.size": 14,
            "figure.facecolor": "w",
            "axes.facecolor": "w",
            "axes.spines.right": False,
            "axes.spines.top": False,
            "axes.spines.bottom": False,
            "xtick.top": False,
            "xtick.bottom": False,
            "ytick.right": False,
            "ytick.left": False,
        }
    )
    

    如果不使用 seaborn 也可以,可以使用 pandas plotting 创建堆叠水平条形图 (barh):

    import pandas as pd
    import matplotlib as mpl
    
    # Plot configuration
    mpl.style.use("seaborn-pastel")
    mpl.rcParams.update(
        {
            "font.size": 14,
            "figure.facecolor": "w",
            "axes.facecolor": "w",
            "axes.spines.right": False,
            "axes.spines.top": False,
            "axes.spines.bottom": False,
            "xtick.top": False,
            "xtick.bottom": False,
            "ytick.right": False,
            "ytick.left": False,
        }
    )
    
    df = pd.DataFrame({
        "Factor": list("ABC"),
        "Portfolio": [0.669687, 0.072474, 0.039068],
        "Benchmark": [0.112653, 0.078819, 0.702114],
        "Active Exposure": [0.140177, 0.823740, 0.450814],
    }).set_index("Factor")
    
    ax = df.plot.barh(stacked=True)
    ax.legend(loc='center left', bbox_to_anchor=(1, 0.5))
    ax.set_ylabel("")
    ax.set_xlabel("Sector Decomposition")
    

    注意上面代码中的索引设置为Factor,然后成为y轴。

    如果您不设置stacked=True,您将获得与 seaborn 制作的几乎相同的图表:

    ax = df.plot.barh(stacked=False)
    ax.legend(loc='center left', bbox_to_anchor=(1, 0.5))
    ax.set_ylabel("")
    ax.set_xlabel("Sector Decomposition")
    

    【讨论】:

    • 这真的很有用,我希望有一种方法可以保留只使用三个和叠加,但这是一个很好的解决方案。
    • 如果您不使用 seaborn,您可以使用堆积条形图(请参阅我更新的答案)。仅当您像this example 那样绘制总数的子集时,允许条形叠加才真正有用。如果您有任何其他问题,请告诉我。
    猜你喜欢
    • 2016-12-12
    • 2018-09-05
    • 2021-07-28
    • 2015-07-09
    • 2015-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多