【问题标题】:How can I change the column colors of a stacked pyplot chart to indicate whether another column is true or false?如何更改堆叠 pyplot 图表的列颜色以指示另一列是真还是假?
【发布时间】:2021-03-16 19:11:51
【问题描述】:

这是数据框中的一些示例数据

Country      restricted  V1%      V2%
0   Algeria  True    39.575812    60.424188
1   Angola   True    56.931682    43.068318
2   Argent   False    15.555556   84.4444

我使用堆积条形图来显示 3 个值。 V1 和 V2 已被归一化为 %ges,因此创建这样的基本图表很简单:

xx=df.plot(kind="bar", x='Country',stacked=True,figsize=(20,10);

之前已经订购了数据框

df=conjoint_ag_df.sort_values(['restricted',.Country'], ascending=[False,True])

以便同时按国家和真/假值显示。

这给了我一个像这样的基本显示。

我想要做的是安排所有具有 true 值的列在限制中具有一个颜色对,而那些具有 false 的列具有另一个颜色对 - 因为我首先按限制进行排序,这意味着颜色将沿着图形的 x 轴从前者变为后者。我可以按照这个示例对简单的条形图执行此操作

Color matplotlib bar chart based on value

以及使用这个的一对颜色

xx=_df.plot(kind="bar", x='Country',stacked=True,figsize=(20,10),color=['r','b'])

(Hideous)但我不知道如何将微分器应用于列以根据 True False 值将两个颜色值更改为两个不同的值。

【问题讨论】:

    标签: python pandas matplotlib colors bar-chart


    【解决方案1】:

    可能有更好的方法,但这里是使用循环的方法:

    for idx, row in df.iterrows():
        color = ['tab:blue', 'tab:orange'] if row['restricted'] else ['tab:blue', 'tab:red']
        plt.bar(row['Country'], row['V1%'], color=color[0])
        plt.bar(row['Country'], row['V2%'], bottom=row['V1%'], color=color[1])
    

    输出:

    【讨论】:

      【解决方案2】:

      这可能不是最漂亮的方法,但它确实有效。我正在使用来自plot 方法的关键字参数color。作为参数,我们可以根据'restricted' 条件为您提供字典。我使用了一些在 matplotlib 颜色图中定义的内置颜色,但您当然可以使用您选择的颜色:

      from matplotlib import cm
      
      palette1 = cm.get_cmap('autumn', 2)
      palette2 = cm.get_cmap('winter', 2)
      
      colors = {
          'V1': [palette1(0) if restricted else palette2(0) for restricted in df['restricted']],
          'V2': [palette1(1) if restricted else palette2(1) for restricted in df['restricted']]
      }
      
      xx = df.plot(kind="bar", x='Country', stacked=True, color=colors, legend=False, figsize=(20, 10))
      

      由于这弄乱了默认图例,我尝试制作一个(虽然不是最漂亮的):

      from matplotlib.lines import Line2D
      
      custom_legend = [
          Line2D([0], [0], color=palette1(0), lw=3),
          Line2D([0], [0], color=palette1(1), lw=3),
          Line2D([0], [0], color=palette2(0), lw=3),
          Line2D([0], [0], color=palette2(1), lw=3),
      ]
      
      plt.legend(custom_legend, ['V1 (Restricted)', 
                                 'V2 (Restricted)', 
                                 'V1 (Non-Restricted)', 
                                 'V2 (Non-Restricted'])
      
      plt.show()
      

      这为我们提供了以下图作为输出:

      【讨论】:

      • 我实际上使用了您的代码作为图例 - 以及自定义标签,但原始答案使用我的代码更方便,因此解决方案打勾。
      • 很高兴它以某种方式帮助了您! :)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-25
      • 2023-03-28
      • 1970-01-01
      • 2016-08-21
      相关资源
      最近更新 更多