【问题标题】:Color matplotlib bar chart based on value基于值的彩色matplotlib条形图
【发布时间】:2015-11-02 11:19:07
【问题描述】:

有没有办法根据条形图的值对条形图的条形进行着色。例如:

- values below -0.5: red
- values between -0.5 to 0: green
- values between 0 to 08: blue
- etc

我找到了一些条形着色的基本示例,但没有什么可以满足值范围的要求,例如上面的示例。

更新:

感谢 kikocorreoso 的建议。根据您的示例,当两个轴都是数字时,这非常有用。但是在我的情况下,我的原始数据结构是熊猫数据框。然后我使用 df.stack() 并绘制结果。这意味着数据框行/列成为绘图的 x 轴,数据框单元格是 Y 轴(条形)。

我已尝试按照您的示例进行屏蔽,但是当 Y 轴是数字而 X 轴是名称时,它似乎不起作用。例如:

     col1    col2   col3   col4
 row1 1       2      3      4
 row2 5       6      7      8
 row3 9       10     11     12
 row4 13      14     15     16

上述数据框需要绘制为条形图,其中行/列组合形成 x 轴。每个单元格值将是一个条形图。最终,根据原始问题为条形着色。谢谢

【问题讨论】:

    标签: python matplotlib


    【解决方案1】:

    您可以为数据集使用掩码。一个基本的例子如下:

    import numpy as np
    import matplotlib.pyplot as plt
    
    x = np.arange(10)
    y = np.arange(10) * 0.1
    
    mask1 = y < 0.5
    mask2 = y >= 0.5
    
    plt.bar(x[mask1], y[mask1], color = 'red')
    plt.bar(x[mask2], y[mask2], color = 'blue')
    plt.show()
    

    结果应该是:

    更新:

    当您更新问题时,我会更新代码。对于您的简单情况,如果我理解正确,您可以执行以下(丑陋的)hack:

    import pandas as pd
    
    df = pd.DataFrame({'col1':[1,2,3], 'col2':[4,5,6]}, 
                      index = ['row1','row2','row3'])
    
    dfstacked = df.stack()
    
    mask = dfstacked <= 3
    
    colors = np.array(['b']*len(dfstacked))
    colors[mask.values] = 'r'
    
    dfstacked.plot(kind = 'bar', rot = 45, color = colors)
    plt.show()
    

    或者使用更多OO solution。

    代码简要说明:

    • 我为我的红色列创建了一个蒙版
    • 我创建了一个颜色数组
    • 更改颜色数组以便为我的蒙版值使用其他颜色
    • 由于dfstacked 数据框有一个MultiIndex,所以我使用rot 关键字来旋转它们。如果你想自动化它以获得一个漂亮的情节,你可以在plt.show()之前使用plt.tight_layout()。

    希望对你有帮助。

    【讨论】:

    • 抱歉回复晚了。这看起来很棒,但是当一个轴是名称列表而不是数字时,我似乎无法让它工作。我已经更详细地编辑了最初的问题。如果您有解决方案,请发布更新
    【解决方案2】:

    我看到很久以前就有人问过这个问题,但以防万一它可以帮助某人,这对我有用:

    迭代所有值并根据自定义条件将颜色附加到列表中,这样您就可以得到一个包含与值一样多的颜色规范的列表;然后使用plt.bar()中的颜色列表:

    import numpy as np
    import matplotlib.pyplot as plt
    
    x = np.arange(10)
    y = np.arange(10) * 0.1
    
    col = []
    for val in y:
        if val < 0.4:
            col.append('blue')
        elif val >= 0.7:
            col.append('green')
        else:
            col.append('red')
    
    # col looks like this: ['blue', 'blue', 'blue', 'blue', 'red', 'red', 'red', 'green', 'green', 'green']
    
    plt.bar(x, y, color = col)
    
    

    【讨论】:

      【解决方案3】:
      import numpy as np
      import matplotlib.pyplot as plt
      
      x = np.arange(4)
      y = np.array([-2,3,-1,2])
      cc=['colors']*len(y)
      for n,val in enumerate(y):
          if val<0:
              cc[n]='red'
          elif val>=0
              cc[n]='blue'
      
      plt.bar(x, y, color = cc)
      plt.show()
      

      【讨论】:

      • 这感觉是一种非常直接易懂的方法,我可以反复使用。它非常pythonic吗?如果没有,有没有人有我可以学习的pythonic方法?
      【解决方案4】:

      对上述答案的小改进

      
      x = np.arange(4)
      
      y = np.array([-2,3,-1,2])
      
      cc=list(map(lambda x: 'red' if x <= 0 else 'blue', y))
      
      plt.bar(x, y, color = cc)
      plt.show()
      

      【讨论】:

      • 如果您想添加到答案中,请考虑评论答案。
      猜你喜欢
      • 2020-03-04
      • 2018-10-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-26
      • 2015-09-27
      • 2016-10-17
      相关资源
      最近更新 更多