Je voudrais pouvoir produire un graphique à lignes empilées (similaire à la méthode utilisée ici ) avec Python (de préférence en utilisant matplotlib, mais une autre bibliothèque serait bien aussi ). Comment puis-je faire ceci?
Cela ressemble à exemple de graphique à barres empilées sur leur site Web, sauf que je voudrais que le haut de la barre soit connecté à un segment de ligne et la zone en dessous à remplir. Je pourrais peut-être approximer cela en réduisant les écarts entre les barres et en utilisant beaucoup de barres (mais cela semble être un hack, et je ne suis d'ailleurs pas sûr que ce soit possible).
Je pense que ( Terrain Area est un terme courant pour ce type de terrain, et dans le cas spécifique cité dans le PO, - Tracé de la zone empilée .
Matplotlib n'a pas de fonction "prête à l'emploi" qui combine à la fois les étapes de traitement des données et de dessin/rendu pour créer ce type de tracer, mais il est facile de rouler le vôtre à partir des composants fournis par Matplotlib et NumPy.
Le code ci-dessous en premier empile les données, puis dessine 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()
Les nouvelles versions de matplotlib contiennent la fonction plt.stackplot
, qui permet plusieurs tracés de zone empilés "prêts à l'emploi" différents:
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()
Si vous avez une trame de données, c'est assez simple:
df = pd.DataFrame(np.random.Rand(10, 4), columns=['a', 'b', 'c', 'd'])
df.plot.area();
Une manière un peu moins hackée 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')