【问题标题】:seaborn barplot: vary color with x and hueseaborn barplot:用x和hue改变颜色
【发布时间】:2020-02-04 00:58:33
【问题描述】:

我的数据集包含有关决策支持模型的短期和长期影响的信息。我想在一个条形图中绘制它,有 4 个条形:

  • 模型,短期
  • 模型,长期
  • 模型关闭,短期
  • 模型,长期

这里是一些示例代码:

df = pd.DataFrame(columns=["model", "time", "value"])
df["model"] = ["on"]*2 + ["off"]*2
df["time"] = ["short", "long"] * 2
df["value"] = [1, 10, 2, 4]

sns.barplot(data=df, x="model", hue="time", y="value")
plt.show()

看起来像这样:

还有许多其他相关的图形,它们已经建立了颜色约定。模型开/关以颜色的色调编码。长期与短期是用颜色的饱和度编码的。所以让我们假设我已经给出了带有颜色值的变量。如何为条形图中的每个单独的条分配单独的颜色?

seaborn.barplot 的docs 仅显示color,它为所有元素指定一种颜色,palette 仅显示不同的色调值不同的颜色。

【问题讨论】:

  • hue in seaborn 对颜色很紧。如果你想为同一个hue 使用不同的颜色,你不能使用它。

标签: python pandas matplotlib seaborn


【解决方案1】:

Seaborn 让您可以方便地绘制简单的绘图,但如果您试图脱离它提供的选项,通常使用直接的 matplotlib 函数会更简单:

plt.bar(x='model',height='value',data=df.loc[df.time=='short'], width=-0.4, align='edge', color=['C0','C1'])
plt.bar(x='model',height='value',data=df.loc[df.time=='long'], width=0.4, align='edge', color=['C2','C3'])

【讨论】:

    【解决方案2】:

    现有答案显示了如何使用 pyplot 排列条形图的好方法。

    不幸的是,我的代码严重依赖于其他 seaborn 功能,例如误差线等。所以我希望能够保留 seaborn barplot 功能并只指定我自己的颜色。

    可以将 seaborn 条形图中的条形作为 matplotlib 补丁进行迭代。这允许设置颜色、阴影等:Is it possible to add hatches to each individual bar in seaborn.barplot?

    import numpy as np
    import pandas as pd
    import seaborn as sns
    import matplotlib.pyplot as plt
    import matplotlib.patches as mpatches
    
    df = pd.DataFrame(columns=["model", "time", "value"])
    df["model"] = ["on"]*2 + ["off"]*2
    df["time"] = ["short", "long"] * 2
    df["value"] = [1, 10, 2, 4]
    
    fig, ax = plt.subplots()
    bar = sns.barplot(data=df, x="model", hue="time", y="value", edgecolor="white")
    
    
    colors = ["red", "green", "blue", "black"]
    # Loop over the bars
    for i,thisbar in enumerate(bar.patches):
        # Set a different hatch for each bar
        thisbar.set_color(colors[i])
        thisbar.set_edgecolor("white")
    

    但是,如果您这样做,它不会更新图例。您可以使用以下代码创建自定义图例。这很复杂,因为我需要为每个图例条目提供多个色块。这显然很复杂:Python Matplotlib Multi-color Legend Entry

    # add custom legend
    ax.get_legend().remove()
    legend_pos = np.array([1, 10])
    patch_size = np.array([0.05, 0.3])
    patch_offset = np.array([0.06, 0])
    
    r2 = mpatches.Rectangle(legend_pos, *patch_size, fill=True, color='red')
    r3 = mpatches.Rectangle(legend_pos + patch_offset, *patch_size, fill=True, color='blue')
    ax.add_patch(r2)
    ax.add_patch(r3)
    ax.annotate('Foo', legend_pos + 3* patch_offset - [0, 0.1], fontsize='x-large')
    
    plt.show()
    

    【讨论】:

      猜你喜欢
      • 2020-07-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-14
      • 2020-10-10
      相关资源
      最近更新 更多