2014-06-11 15 views
7

Voglio creare un barilotto impilato con 3 barre una sopra l'altra. Sono riuscito a farlo per uno stacking da 2 bar, ma non riesco ad aggiungere il 3 °, qualche idea?Impilare 3 barre una sopra l'altra tramite Matplotlib di Python

vorrei aggiungere qualche semplice codice di esempio per mostrare quello che voglio dire:

from matplotlib import pyplot as plt 

data1 = [100,120,140] 
data2 = [150,120,190] 

f, (ax1, ax2) = plt.subplots(1, 2, figsize=(10,5)) 

## Absolute count 

ax1.bar(range(len(data1)), data1, label='data 1', alpha=0.5, color='b') 
ax1.bar(range(len(data2)), data2, bottom=data1, label='data 2', alpha=0.5, color='r') 
plt.sca(ax1) 
plt.xticks([0.4, 1.4, 2.4], ['category 1', 'category 2', 'category 3']) 
ax1.set_ylabel("Count") 
ax1.set_xlabel("") 
plt.legend(loc='upper left') 

## Percent 

totals = [i + j for i,j in zip(data1, data2)] 
data1_rel = [i/j * 100 for i,j in zip(data1, totals)] 
data2_rel = [i/j * 100 for i,j in zip(data2, totals)] 

ax2.bar(range(len(data1_rel)), data1_rel, alpha=0.5, color='b') 
ax2.bar(range(len(data2_rel)), data2_rel, bottom=data1_rel, alpha=0.5, color='r') 
plt.sca(ax2) 
plt.xticks([0.4, 1.4, 2.4], ['category 1', 'category 2', 'category 3']) 
ax2.set_ylabel("Percentage") 
ax2.set_xlabel("") 

plt.show() 

enter image description here

Ora, diciamo che voglio aggiungere, ad esempio, data3 = [100,150,130] Intuitivamente, lo farei come questo

ax1.bar(range(len(data3)), data3, bottom=data1+data2, label='data 3', alpha=0.5, color='g') 

Tuttavia, questo purtroppo non aggiunge la terza barra.

risposta

4

dovrebbe fare: ax1.bar(range(len(data3)), data3, bottom=np.array(data1)+np.array(data2), label='data 3', alpha=0.5, color='g'): enter image description here

E, può essere un modo preferito. Può essere molto elegante gestito da pandas in poche righe:

In [17]: 

import pandas as pd 
df=pd.DataFrame({'data1':data1, 'data2':data2, 'data3':data3}) 
df.plot(kind='bar', stacked=True) 
Out[17]: 
<matplotlib.axes.AxesSubplot at 0x108f2b050> 

enter image description here

+0

Certo, grazie, ho completamente perso questo punto, thx molto – Sebastian

+0

Nizza risposta panda ... – brechmos

1

Suppongo che si verifichi un errore quando si tenta di tracciare?

Attualmente, si sta utilizzando gli elenchi e così:

>>> data1 = [1, 2, 3] 
>>> data2 = [4, 5, 6] 

>>> data+data2 
>>> [1, 2, 3, 4, 5, 6] 

È possibile utilizzare per gli array ad esempio NumPy, che dovrebbe risolvere il problema.

>>> data1 = numpy.array([1, 2, 3]) 
>>> data2 = numpy.array([4, 5, 6]) 

>>> data1+data2 
>>> [5, 7, 9] 
1

ne dici di questo? Sembrava aver funzionato per me.

from __future__ import division 
from matplotlib import pyplot as plt 

data1 = [100,120,140] 
data2 = [150,120,190] 
data3 = [130,110,120] 

f, (ax1, ax2) = plt.subplots(1, 2, figsize=(10,5)) 

## Absolute count 

b = list(r_[data1] +r_[ data2]) 

ax1.bar(range(len(data1)), data1, label='data 1', alpha=0.5, color='b') 
ax1.bar(range(len(data2)), data2, bottom=data1, label='data 2', alpha=0.5, color='r') 
ax1.bar(range(len(data3)), data3, bottom=b, label='data 3', alpha=0.5, color='g') 
plt.sca(ax1) 
plt.xticks([0.4, 1.4, 2.4], ['category 1', 'category 2', 'category 3']) 
ax1.set_ylabel("Count") 
ax1.set_xlabel("") 
plt.legend(loc='upper left') 

## Percent 

totals = [i + j + k for i,j,k in zip(data1, data2, data3)] 
data1_rel = [i/j * 100 for i,j in zip(data1, totals)] 
data2_rel = [i/j * 100 for i,j in zip(data2, totals)] 
data3_rel = [i/j * 100 for i,j in zip(data3, totals)] 

b_rel = list(r_[data1_rel] +r_[ data2_rel]) 


ax2.bar(range(len(data1_rel)), data1_rel, alpha=0.5, color='b') 
ax2.bar(range(len(data2_rel)), data2_rel, bottom=data1_rel, alpha=0.5, color='r') 
ax2.bar(range(len(data3_rel)), data3_rel, bottom=b_rel, alpha=0.5, color='g') 
plt.sca(ax2) 
plt.xticks([0.4, 1.4, 2.4], ['category 1', 'category 2', 'category 3']) 
ax2.set_ylabel("Percentage") 
ax2.set_xlabel("") 

plt.show() 
0

un'opzione se si desidera utilizzare i panda tramando biblioteca invece di matplotlib:

import pandas 

column_names = ['cat1', 'cat2', 'cat3'] 
data1 = [100,120,140] 
data2 = [150,120,190] 
data3 = [100,150,130] 

df = pandas.DataFrame([data1, data2, data3], columns = column_names) 
df.plot.bar(stacked=True) 

stacked bar graph from pandas

Problemi correlati