简体   繁体   中英

python matplotlib stacked barcharts grouped together

Explination of data: I have a program I am testing which has 3 parts which add to the ability of the program as a whole eg part1 works on 60% of data, part2 on an additional 10% and part3 on another 6%.

What I want to do is have stacked bars which show "out of the total amount of data the program worked on green indicates the amount part1 worked on, red part2 and yellow part3".

As I have tested the program on 3 sets of 5 files I want the graph to reflect this by grouping the 5 barcharts from each dataset together so in the end there are 3 parts to the graph which are an inch away from each other and then each barchart has the stacked effect stated above.

I am aiming for the Y axis to be the percentage the files worked and the Y the names of the groups the files are a part of.

As for some example data this is what I have been trying with:

meta_part1 = [5, 5.5, 4.67, 6.54, 4.4]
meta_part2 = [3.1, 3.3, 3.9, 3.5, 3.1]
meta_part3 = [1.3,1.4,1.7,2.4,0.89]

trans_part1 = [90,89.5,94.67,96.54,94.4]
trans_part2 = [11.1,11.3,10.9,11.5,12.1]
trans_part3 = [11.3,11.4,11.7,12.4,10.89]

s_part1 = [55,55.5,54.67,56.54,54.4]
s_part2 = [11.1,11.3,10.9,11.5,12.1]
s_part3 = [11.3,11.4,11.7,12.4,10.89]

meta,trans and s are all groups.

My failed code so far is here:

import matplotlib.pyplot as plt
import numpy as np
import numpy as np
from numpy.random import randn
import pandas as pd
from scipy import stats
import matplotlib as mpl
import seaborn as sns


meta_part1 = [5, 5.5, 4.67, 6.54, 4.4]
meta_part2 = [3.1, 3.3, 3.9, 3.5, 3.1]
meta_part3 = [1.3,1.4,1.7,2.4,0.89]

trans_part1 = [90,89.5,94.67,96.54,94.4]
trans_part2 = [11.1,11.3,10.9,11.5,12.1]
trans_part3 = [11.3,11.4,11.7,12.4,10.89]

s_part1 = [55,55.5,54.67,56.54,54.4]
s_part2 = [11.1,11.3,10.9,11.5,12.1]
s_part3 = [11.3,11.4,11.7,12.4,10.89]

N = 5

ind = np.arange(N)    # the x locations for the groups
width = 0.35       # the width of the bars: can also be len(x) sequence

p1 = plt.bar(ind, meta_part1,   width, color='y', bottom=meta_part2)
p2 = plt.bar(ind, meta_part2, width, color='r', bottom=meta_part3)
p3 = plt.bar(ind, meta_part3, width, color='g')



plt.ylabel('Scores')
plt.title('Difference between stitchers')
plt.xticks(ind+width/3., ('Test1', 'Test2', 'Test3', 'Test4', 'Test5') )
plt.yticks(np.arange(0,10,1))
plt.legend( (p1[0], p2[0], p3[0]), ('Part1', 'Part2', 'Part3') )
ax.autoscale(tight=True)

plt.show()

However this has been useless so far as it only produces bars with 2 stacking parts and the third is merging into the first and I havnt been able to work out how to combine merging into this code.

You don't define meta_second and meta_total in your snippet here so it's a bit hard to guess what's going on, but I'll take a stab. You may be adding lists with + to get meta_total , which will append the two lists not add the values together.

Here are modifications that work:

meta_second = meta_part1
meta_total = [meta_part1[i]+val for i, val in enumerate(meta_part2)]
p1 = plt.bar(ind, meta_part1, width, color='y')
p2 = plt.bar(ind, meta_part2, width, color='r', bottom=meta_second)
p3 = plt.bar(ind, meta_part3, width, color='g', bottom=meta_total)

Also, unrelated, but you try to use ax before it is defined. You should try to stick with one interface or the other (either pyplot or the object-oriented interface). They don't like being mixed. Personally, the OO-interface is more robust and reliable, I always use that.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM