使用matplotlib绘制不同颜色的堆积条形图

5

我是一名Python初学者。我正在尝试制作一个带有不同颜色排序的水平条形图。

我有一个数据集,就像下面这个:

dataset = [{'A':19, 'B':39, 'C':61, 'D':70},
           {'A':34, 'B':68, 'C':32, 'D':38},
           {'A':35, 'B':45, 'C':66, 'D':50},
           {'A':23, 'B':23, 'C':21, 'D':16}]
data_orders = [['A', 'B', 'C', 'D'], 
               ['B', 'A', 'C', 'D'], 
               ['A', 'B', 'D', 'C'], 
               ['B', 'A', 'C', 'D']]

第一个列表包含数字数据,第二个列表包含每个数据项的顺序。我需要第二个列表,因为在我的情况下,A、B、C和D的顺序对于数据集的呈现非常重要。
使用上述数据,我想制作一个堆积条形图,就像下面的图片一样。这是我手动用MS Excel制作的。现在,我希望使用Matplotlib以更自动化的方式使用上述数据集来制作此类型的条形图。如果可能的话,我还想向图表添加图例。
实际上,我已经完全迷失了自己尝试这个。任何帮助都将非常有帮助。 非常感谢您的关注!

请查看此链接:http://matplotlib.sourceforge.net/mpl_examples/pylab_examples/bar_stacked.py - Ashwini Chaudhary
亲爱的Ashwini,谢谢你提供这个信息。这是Matplotlib页面引用的例子吗?我把它当作“教科书”使用,但问题是似乎超出了我将这个模型应用于实际目的的能力。这就是为什么我发布了我的问题!但你提到的枚举建议对我来说是一个提示。非常感谢! - miyazaki_tara
2个回答

13

这是一个很长的程序,但它可以正常运行。我添加了一个虚拟数据来区分行数和列数:

import numpy as np
from matplotlib import pyplot as plt

dataset = [{'A':19, 'B':39, 'C':61, 'D':70},
           {'A':34, 'B':68, 'C':32, 'D':38},
           {'A':35, 'B':45, 'C':66, 'D':50},
           {'A':23, 'B':23, 'C':21, 'D':16},
           {'A':35, 'B':45, 'C':66, 'D':50}]
data_orders = [['A', 'B', 'C', 'D'], 
               ['B', 'A', 'C', 'D'], 
               ['A', 'B', 'D', 'C'], 
               ['B', 'A', 'C', 'D'],
               ['A', 'B', 'C', 'D']]
colors = ["r","g","b","y"]
names = sorted(dataset[0].keys())
values = np.array([[data[name] for name in order] for data,order in zip(dataset, data_orders)])
lefts = np.insert(np.cumsum(values, axis=1),0,0, axis=1)[:, :-1]
orders = np.array(data_orders)
bottoms = np.arange(len(data_orders))

for name, color in zip(names, colors):
    idx = np.where(orders == name)
    value = values[idx]
    left = lefts[idx]
    plt.bar(left=left, height=0.8, width=value, bottom=bottoms, 
            color=color, orientation="horizontal", label=name)
plt.yticks(bottoms+0.4, ["data %d" % (t+1) for t in bottoms])
plt.legend(loc="best", bbox_to_anchor=(1.0, 1.00))
plt.subplots_adjust(right=0.85)
plt.show()

结果图如下:

enter image description here


非常感谢您花费时间制作所有这些内容。这非常有帮助!我从您的脚本中学到了很多。 - miyazaki_tara
一个小的改进是使用 barh - guhur

1
>>> dataset = [{'A':19, 'B':39, 'C':61, 'D':70},
           {'A':34, 'B':68, 'C':32, 'D':38},
           {'A':35, 'B':45, 'C':66, 'D':50},
           {'A':23, 'B':23, 'C':21, 'D':16}]

>>> data_orders = [['A', 'B', 'C', 'D'], 
               ['B', 'A', 'C', 'D'], 
               ['A', 'B', 'D', 'C'], 
               ['B', 'A', 'C', 'D']]
>>> for i,x in enumerate(data_orders):
     for y in x:
        #do something here with dataset[i][y]  in matplotlib

亲爱的Ashwini,感谢您抽出时间回复我的问题。我会尽力弄清楚如何使用它来解决我的问题! - miyazaki_tara
@miyazaki_tara 另一种方法是创建一个新的列表,其中数据已按照 data_orders 排列。 - Ashwini Chaudhary
@miyazaki_tara [[dataset[i][y] for y in data_orders[i]] for i in range(len(data_orders))] 会返回 [[19, 39, 61, 70], [68, 34, 32, 38], [35, 45, 50, 66], [23, 23, 21, 16]] - Ashwini Chaudhary
问题在于我对matplotlib的工作原理缺乏理解,但是有了你的帮助,我可能已经掌握了!谢谢! - miyazaki_tara

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接