Python 更高效的matplotlib堆叠条形图-如何计算底部值

Python 更高效的matplotlib堆叠条形图-如何计算底部值,python,numpy,matplotlib,stackedbarseries,Python,Numpy,Matplotlib,Stackedbarseries,我需要一些帮助,使用matlibplot在python中创建一组堆叠条形图。我的基本代码如下,但我的问题是如何高效地为第二个元素之外的任何元素生成底部的值。我可以让示例图正确地堆叠(始终是从下到上的a、b、c、d) 我的最后一段代码可能有很多条,不断扩展的函数bottom=[…]不是最好的解决方案。如果你也能解释一下我需要如何得出这个值,那就太好了。有一个numpy函数 非常感谢!!! PS我一直在寻找答案,但我不明白我能找到什么 [sum(values) for values in zip(a

我需要一些帮助,使用matlibplot在python中创建一组堆叠条形图。我的基本代码如下,但我的问题是如何高效地为第二个元素之外的任何元素生成底部的值。我可以让示例图正确地堆叠(始终是从下到上的a、b、c、d)

我的最后一段代码可能有很多条,不断扩展的函数bottom=[…]不是最好的解决方案。如果你也能解释一下我需要如何得出这个值,那就太好了。有一个numpy函数

非常感谢!!! PS我一直在寻找答案,但我不明白我能找到什么

[sum(values) for values in zip(a, b, c)]
在Python2中,您还可以

map(sum, zip(a, b, c))
但是Python3需要

list(map(sum, zip(a, b, c)))
这不太好


您可以封装以下内容:

def sumzip(*items):
    return [sum(values) for values in zip(*items)]
然后呢

p1 = plt.bar(ind, a, 1, color='#ff3333')
p2 = plt.bar(ind, b, 1, color='#33ff33', bottom=sumzip(a))
p3 = plt.bar(ind, c, 1, color='#3333ff', bottom=sumzip(a, b))
p4 = plt.bar(ind, d, 1, color='#33ffff', bottom=sumzip(a, b, c))
也是


如果
a
b
c
d
是numpy数组,您也可以执行
求和([a,b,c])


将值转换为numpy数组将使您的生活更轻松:

data = np.array([a, b, c, d])
bottom = np.cumsum(data, axis=0)
colors = ('#ff3333', '#33ff33', '#3333ff', '#33ffff')

plt.bar(ind, data[0], color=colors[0])
for j in xrange(1, data.shape[0]):
    plt.bar(ind, data[1], color=colors[j], bottom=bottom[i-1])
或者,为了摆脱第一个酒吧中令人讨厌的特殊情况:

data = np.array([a, b, c, d])
bottom = np.vstack((np.zeros((data.shape[1],), dtype=data.dtype),
                    np.cumsum(data, axis=0)[:-1]))
colors = ('#ff3333', '#33ff33', '#3333ff', '#33ffff')
for dat, col, bot in zip(data, colors, bottom):
    plt.bar(ind, dat, color=col, bottom=bot)

我最近也遇到了同样的问题。后来,我决定用一门好课来结束这一切。对于任何感兴趣的人,您可以在此处获得堆叠条形图类的实现:

它允许缩放堆叠图形以及设置条形宽度和高度(使用缩放内部)

给定如下数据集:

    d = np.array([[101.,0.,0.,0.,0.,0.,0.],
                  [92.,3.,0.,4.,5.,6.,0.],
                  [56.,7.,8.,9.,23.,4.,5.],
                  [81.,2.,4.,5.,32.,33.,4.],
                  [0.,45.,2.,3.,45.,67.,8.],
                  [99.,5.,0.,0.,0.,43.,56.]])

    d_heights = [1.,2.,3.,4.,5.,6.]
    d_widths = [.5,1.,3.,2.,1.,2.]
    d_labels = ["fred","julie","sam","peter","rob","baz"]
    d_colors = ['#2166ac',
                '#fee090',
                '#fdbb84',
                '#fc8d59',
                '#e34a33',
                '#b30000',
                '#777777']
import numpy as np

dates = # somehow get a list of dates
labels = # a list of various labels
colors = # somehow get a list of colors

margin_bottom = np.zeros(dates)

for index, label in enumerate(labels):
    values = # get your values for the label at index-th position from somewhere
    ax.bar(
        dates, values, 
        align='center', label=label, color=colors[index], bottom=margin_bottom
    )
    margin_bottom += values # here you simply add it to the previous margin
    # margin_bottom is a numpy array, adding a list will not change that
它可以制作如下图像:

    d = np.array([[101.,0.,0.,0.,0.,0.,0.],
                  [92.,3.,0.,4.,5.,6.,0.],
                  [56.,7.,8.,9.,23.,4.,5.],
                  [81.,2.,4.,5.,32.,33.,4.],
                  [0.,45.,2.,3.,45.,67.,8.],
                  [99.,5.,0.,0.,0.,43.,56.]])

    d_heights = [1.,2.,3.,4.,5.,6.]
    d_widths = [.5,1.,3.,2.,1.,2.]
    d_labels = ["fred","julie","sam","peter","rob","baz"]
    d_colors = ['#2166ac',
                '#fee090',
                '#fdbb84',
                '#fc8d59',
                '#e34a33',
                '#b30000',
                '#777777']
import numpy as np

dates = # somehow get a list of dates
labels = # a list of various labels
colors = # somehow get a list of colors

margin_bottom = np.zeros(dates)

for index, label in enumerate(labels):
    values = # get your values for the label at index-th position from somewhere
    ax.bar(
        dates, values, 
        align='center', label=label, color=colors[index], bottom=margin_bottom
    )
    margin_bottom += values # here you simply add it to the previous margin
    # margin_bottom is a numpy array, adding a list will not change that

带着爱的GPLv3。

我这样解决它:

    d = np.array([[101.,0.,0.,0.,0.,0.,0.],
                  [92.,3.,0.,4.,5.,6.,0.],
                  [56.,7.,8.,9.,23.,4.,5.],
                  [81.,2.,4.,5.,32.,33.,4.],
                  [0.,45.,2.,3.,45.,67.,8.],
                  [99.,5.,0.,0.,0.,43.,56.]])

    d_heights = [1.,2.,3.,4.,5.,6.]
    d_widths = [.5,1.,3.,2.,1.,2.]
    d_labels = ["fred","julie","sam","peter","rob","baz"]
    d_colors = ['#2166ac',
                '#fee090',
                '#fdbb84',
                '#fc8d59',
                '#e34a33',
                '#b30000',
                '#777777']
import numpy as np

dates = # somehow get a list of dates
labels = # a list of various labels
colors = # somehow get a list of colors

margin_bottom = np.zeros(dates)

for index, label in enumerate(labels):
    values = # get your values for the label at index-th position from somewhere
    ax.bar(
        dates, values, 
        align='center', label=label, color=colors[index], bottom=margin_bottom
    )
    margin_bottom += values # here you simply add it to the previous margin
    # margin_bottom is a numpy array, adding a list will not change that

它与其他一些解决方案类似,但并不要求在任何时候都存储所有的边距。相反,它从下到上“构建”堆栈,每次迭代都会增加越来越多的边距。

如果使用matplotlib,所有内容都会在下面作为一个数据数组。还不如让你的生活愉快;)谢谢,我怎样才能添加标签呢?我有一个标签/名称列表,用于我正在堆叠的每个系列,但尽管我已经尝试过,但我无法将它们正确地显示出来。我也试着运行一个简单的图例,如下面所示,但它并没有真正起作用。
code
plt.legend((pl[0],pm[0],ph[0],pa[0]),('L','M','H','At'),bbox_to_anchor=[1.05,0.5],loc='center')谢谢-我如何在条之间获得空格?我更新了代码以允许出现空格。这其实很简单,如果你从钢筋的宽度中扣除一个固定的数量,那么它就会有效地收缩钢筋。之后,就只需要玩XLIM了。主函数调用现在有两个新参数gap和endGaps,下面两张图片显示了这些参数的示例。感觉太容易了。要添加图例,如果使用数组设置颜色,例如
stacked_colors=[''2166ac'、''fee090'、'#fdbb84']
cols=stacked_colors
,则很容易将图例添加到由pandas数据框制作的绘图中:
legends=[]i=0,用于df.columns:legends.append(mpatches.Patch(颜色=堆叠的颜色[i],标签=列)i+=1 plt.图例(手柄=图例)