2010-02-09 22 views
40

Mi piacerebbe essere in grado di produrre un grafico a linee sovrapposte (simile al metodo utilizzato here) con Python (preferibilmente usando matplotlib, ma anche un'altra libreria andrebbe bene). Come posso fare questo?Come posso creare un grafico a linee sovrapposte con matplotlib?

Questo simile allo stacked bar graph example sul proprio sito Web, tranne che mi piacerebbe che la parte superiore della barra fosse connessa con un segmento di linea e che l'area sottostante fosse riempita. Potrei essere in grado di approssimare questo riducendo gli spazi tra le barre e usando molte barre (ma questo sembra un trucco, e inoltre non sono sicuro che sia possibile).

+5

Il collegamento nell'esempio (http://www.whitehouse.gov/omb/budget/fy2003/images/bud20c.jpg) è rotto. Hai un link migliore? –

+0

usa stackplot() dal pacchetto pyplot. – AjayKumarBasuthkar

+0

Questa è una vecchia domanda, ma per altre persone che trovano questa domanda in una ricerca come quella che ho fatto, c'è una nuova soluzione se si utilizzano i datafram pandas: 'df = pd.DataFrame (np.random.rand (10, 4), columns = ['a', 'b', 'c', 'd']) ' ' df.plot.area(); 'da http://pandas.pydata.org/pandas-docs/stable /visualization.html –

risposta

46

credo Superficie Totale è un termine comune per questo tipo di trama, e nel caso specifico recitato nel PO, pila Superficie Totale.

Matplotlib non dispone di una funzione di "out-of-the-box" che combina sia del trattamento dei dati e il disegno/rendering passaggi per creare un tale tipo di trama, ma è facile da rotolare il proprio da componenti forniti di Matplotlib e NumPy.

Il codice qui sotto prima pile i dati, quindi pareggi la trama.

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

Dato che stai cercando di essere molto completo perché non trasformarlo in 'stackplot (x, yn, colorlist)' e presentare un bug di richiesta di funzionalità a monte? –

+0

Se si desidera creare una legenda per questo tipo di grafico, penso che sia necessario utilizzare il proxy "Artists" http://matplotlib.sourceforge.net/users/legend_guide.html#using-proxy-artist –

+1

@honk In realtà, c'è già un [PR in sospeso] (https://github.com/matplotlib/matplotlib/pull/819) (che dovrebbe essere unito a breve) per una funzione 'stackplot'. –

7

Un modo leggermente meno accattivante sarebbe utilizzare un grafico a linee in primo luogo e matplotlib.pyplot.fill_between. Per emulare l'impilamento devi spostare i punti da solo.

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

puoi spiegare i parametri del metodo fill_between()? sembra che stiamo riempiendo del colore tra x e y ma qual è la terza variabile? – khan

+0

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

48

versioni più recenti di matplotlib contengono la funzione plt.stackplot, che consentono di diversi appezzamenti della zona "out-of-the-box" impilati:

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

Cosa significa "Y"? –

2

Se si dispone di un dataframe, è qui TE facile:

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

enter image description here

Da: pandas documentation

Problemi correlati