How to draw 100% stacked bars with mixed +ve and -ve values in matplotlib?

喜你入骨 提交于 2020-01-06 03:54:04

问题


I have some data with mixed positive and negative values that the sum of the absolute values of each variable = 100% Here are some sample data:

Out01 = [79.069,-1.602,5.067,-4.241,-5.433,-4.590]
Out02 = [50.348,13.944,-15.373,6.554,5.541,8.240]
Out03 = [-8.053,0.819,-9.741,2.814,22.475,56.098]
Out04 = [-17.350,33.710,-18.510,-0.842,3.050,26.537]
Out05 = [-20.169,37.583,-20.785,-2.041,1.728,17.695]

I drew them as desired in Microsoft Excel as follows by the "100% stacked columns" chart: Now I want to draw similar chart in python through matplotlib library.

How can I do that?


回答1:


Finally, I got the answer, When I followed the example in matplotlib page, it includes the bottom keyword which specifies the rise of each sample data over the previous one.

p2 = plt.bar(ind, womenMeans, width, color='y', bottom=menMeans, yerr=womenStd)

For example, if we want to plot men and women data as in the example, we starts with men with score 20 (in series G1), then to draw women, they start plotting the value of 25 with bottom value of 20. To expand this, if we added another category, say children, with score 15, then it should be plotted with bottom = 20 + 25 = 45. etc.

With negative values, we have a problem, that they grew in the opposite direction of the positives ones. so it should start with bottom = 0, then with maximum value of the sum of either positive or negative values independently. To understand that with an example, if we want to plot a series like the following: (20, 25, -15, 30, -10, -5, 17, 3, -28) The bottoms of each value should be as follows (0, 20, 0, 45, -15, -25, 75, 92, -30) Why?

For the 20, we just initiate drawing, so, no bottom required. For the 25, we need to rise it by 20. For the -15, it is the first negative value, so it must be drawn below axis with no bottom value, so the bottom = 0 For the 30, it should be raised by 20 + 25 = 45 For the -10, it should start below the previous negative value which is -15 For the next -5, it should start below -10 + -15 = -25 And so on...

def bottoms_matrix(matrix):
    positives = []
    negatives = []
    for i, row_mat in enumerate(matrix):
        tmp_p = []
        tmp_n = []
        for j, cell in enumerate(row_mat):
            if cell >0:
                tmp_p.append(cell)
                tmp_n.append(0.)
            else:
                tmp_p.append(0.)
                tmp_n.append(cell)
        positives.append(tmp_p)
        negatives.append(tmp_n)

    # get cumulative sums
    positives = positives[:-1]
    negatives = negatives[:-1]
    positives.insert(0, [0.] * len (matrix[0]))
    negatives.insert(0, [0.] * len(matrix[0]))
    tmp = swap_matrix(positives)
    tmp = [list(np.cumsum(t)) for t in tmp]
    positives = swap_matrix(tmp)

    tmp = swap_matrix(negatives)
    tmp = [list(np.cumsum(t)) for t in tmp]
    negatives = swap_matrix(tmp)

    final_matrix =[]
    for i, row_mat in enumerate(matrix):
        tmp =[]
        for j, cell in enumerate(row_mat):
            tmp.append(positives[i][j] if cell > 0 else negatives[i][j])
        final_matrix.append(tmp)
    return final_matrix

A complete example with data and all auxiliary functions is uploaded on my Git page.



来源:https://stackoverflow.com/questions/36766245/how-to-draw-100-stacked-bars-with-mixed-ve-and-ve-values-in-matplotlib

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!