多个堆积图

时间:2018-06-28 07:10:50

标签: python-3.x matplotlib charts

我正在尝试复制这种图表:

target bar

条形图包含一些堆叠的条形图和一些非堆叠的条形图。

我最接近的是以下代码:

import matplotlib.pyplot as plt

fooMeans = (20, 35, 30, 35, 27)
barMeans = (25, 32, 34, 20, 25)

ind = list(range(len(fooMeans)))

p1 = plt.bar(ind, barMeans, align='edge', width= 0.4)
p2 = plt.bar(ind, fooMeans, align='edge', width= 0.2)
p3 = plt.bar(ind, barMeans, bottom=fooMeans, align='edge', width= 0.2)
p4 = plt.bar(ind, fooMeans, align='edge', width= -0.2)

plt.xticks(ind, ('G1', 'G2', 'G3', 'G4', 'G5'))
plt.yticks(range(0, 81, 10))


plt.legend((p1[0], p2[0], p3[0], p4[0]), ('Foo', 'Bar','Fii', 'Fuu'))


plt.savefig('foo.png', bbox_inches='tight')

哪个画的:

closest bar

还不错,但是x刻度未对齐(可能是由于条的align ='edge')和我用来显示条并排显示的宽度技巧(而不是绘制所有条)一种在另一种之上)看起来像黑客一样,通过书籍的方式可以做到这一点吗?

1 个答案:

答案 0 :(得分:0)

好的,所以我找到了一种更清洁的方法。

最好的选择似乎是x位置列表(在我之前的代码示例中)。 因此,我想出了一个可以为我处理的小功能:

def make_indice_list(indices, bar_number, bar_width, spacing_ratio=0):

    # "Center" the bar number around 0, not clear but if you have 3 bar, 
    # bar_number_indices = [-1, 0, 1]
    bar_number_indices = [i - int(bar_number/2) for i in range(bar_number)]

    indices_list = []
    for number in bar_number_indices:

        indices_list.append([ ( ((number* bar_width) + (spacing_ratio*bar_width) * number) + ind) for ind in indices])

    return indices_list

我这样做是为了使用它:

indice_list = make_indice_list(ind, 3, 0.2, 0.1)
p1 = plt.bar(indice_list[0], barMeans, width= 0.2)
p2 = plt.bar(indice_list[1], fooMeans, width= 0.2)
p3 = plt.bar(indice_list[1], barMeans, bottom=fooMeans, width= 0.2)
p4 = plt.bar(indice_list[2], fooMeans, width= -0.2)

没有更多的中心,也没有奇怪的宽度,您只需要对堆叠的条使用相同的索引(并在调用函数时将它们视为一个)。

最后,画出这个:

enter image description here

您可能可以对make_indice_list函数进行一些改进,主要是删除理解列表并使用numpy列表,但我认为这对我来说是一个很好的解决方案。