2010-02-09 8 views
40

Je voudrais être en mesure de produire un graphique linéaire empilé (similaire à la méthode utilisée here) avec Python (de préférence en utilisant matplotlib, mais une autre bibliothèque serait bien aussi). Comment puis-je faire ceci?Comment créer un graphique linéaire empilé avec matplotlib?

Ceci est similaire au stacked bar graph example sur leur site Web, sauf que je souhaite que le haut de la barre soit connecté à un segment de ligne et à la zone à remplir en dessous. Je pourrais peut-être me rapprocher de cela en diminuant les écarts entre les barres et en utilisant beaucoup de barres (mais cela ressemble à un hack, et d'ailleurs je ne suis pas sûr que ce soit possible).

+5

Le lien dans l'exemple (http://www.whitehouse.gov/omb/budget/fy2003/images/bud20c.jpg) est cassé. Avez-vous un meilleur lien? –

+0

utilise stackplot() du paquet pyplot. – AjayKumarBasuthkar

+0

Ceci est une vieille question, mais pour les autres personnes qui trouvent cette question dans une recherche comme je l'ai fait, il y a une nouvelle solution si vous utilisez des dataframes pandas: 'df = pd.DataFrame (np.random.rand (10, 4), colonnes = ['a', 'b', 'c', 'd']) ' ' df.plot.area(); 'à partir de http://pandas.pydata.org/pandas-docs/stable /visualization.html –

Répondre

46

Je crois Quartier Terrain est un terme commun pour ce type de terrain, et dans le cas précis récité dans l'OP, Stacked Terrain Zone.

Matplotlib ne dispose pas d'un « out-of-the-box » fonction qui combine à la fois le traitement et le dessin des données/rendu des mesures pour créer un ce type de terrain, mais il est facile de rouler vos propres à partir de composants fournis par Matplotlib et NumPy.

Le code ci-dessous les premiers piles les données, puis tire l'intrigue.

import numpy as NP 
from matplotlib import pyplot as PLT 

# just create some random data 
fnx = lambda : NP.random.randint(3, 10, 10) 
y = NP.row_stack((fnx(), fnx(), fnx())) 
# this call to 'cumsum' (cumulative sum), passing in your y data, 
# is necessary to avoid having to manually order the datasets 
x = NP.arange(10) 
y_stack = NP.cumsum(y, axis=0) # a 3x10 array 

fig = PLT.figure() 
ax1 = fig.add_subplot(111) 

ax1.fill_between(x, 0, y_stack[0,:], facecolor="#CC6666", alpha=.7) 
ax1.fill_between(x, y_stack[0,:], y_stack[1,:], facecolor="#1DACD6", alpha=.7) 
ax1.fill_between(x, y_stack[1,:], y_stack[2,:], facecolor="#6E5160") 

PLT.show() 

example of stacked area plot

+13

Puisque vous essayez d'être très complet pourquoi ne pas le transformer en 'stackplot (x, yn, colorlist)' et déposer un bug de demande de fonctionnalité en amont? –

+0

Si vous voulez créer une légende pour ce type de graphique, je pense que vous devez utiliser un proxy "Artistes" http://matplotlib.sourceforge.net/users/legend_guide.html#using-proxy-artist –

+1

@honk il y a déjà un [pending PR] (https://github.com/matplotlib/matplotlib/pull/819) (qui devrait être bientôt fusionné) pour une fonction 'stackplot'. –

7

Un moyen légèrement moins hackish serait d'utiliser un graphique linéaire en premier lieu et matplotlib.pyplot.fill_between. Pour émuler l'empilement, vous devez déplacer les points vous-même.

x = np.arange(0,4) 
y1 = np.array([1,2,4,3]) 
y2 = np.array([5,2,1,3]) 
# y2 should go on top, so shift them up 
y2s = y1+y2 

plot(x,y1) 
plot(x,y2s) 
fill_between(x,y1,0,color='blue') 
fill_between(x,y1,y2s,color='red') 
+0

pouvez-vous s'il vous plaît expliquer les paramètres de la méthode fill_between()? On dirait que nous remplissons une certaine couleur entre x et y, mais quelle est la troisième variable? – khan

+0

@khan: http://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes.fill_between –

48

Les nouvelles versions de matplotlib contiennent la fonction plt.stackplot, qui permettent plusieurs "out-of-the-box" parcelles de zones empilées:

import numpy as np 
import pylab as plt 

X = np.arange(0, 10, 1) 
Y = X + 5 * np.random.random((5, X.size)) 

baseline = ["zero", "sym", "wiggle", "weighted_wiggle"] 
for n, v in enumerate(baseline): 
    plt.subplot(2 ,2, n + 1) 
    plt.stackplot(X, *Y, baseline=v) 
    plt.title(v) 
    plt.axis('tight') 
plt.show() 

Stack Plot using plt.stackplot.

+0

Que signifie "Y"? –

2

Si vous avez un dataframe, c'est te facile:

df = pd.DataFrame(np.random.rand(10, 4), columns=['a', 'b', 'c', 'd']) 
df.plot.area(); 

enter image description here

De: pandas documentation

Questions connexes