python - généralisation des limites de l'axe y pour la ligne moyenne dans les graphiques de densité
J'ai ce dataframe simple:
df = pd.DataFrame({"X": np.random.randint(50,53,size=100),
"Y": np.random.randint(200,300,size=100),
"Z": np.random.randint(400,800,size=100)})
Et comme j'ai beaucoup de colonnes (toutes numériques), j'ai fait cette boucle afin de faire un tracé spécifique:
for i in df.columns:
data = df[i]
data.plot(kind="kde")
plt.vlines(x=data.mean(),ymin=0, ymax=0.01, linestyles="dotted")
plt.show()
Cependant, j'ai du mal à essayer de généraliser l' ymax
argument de plt.vlines()
, car j'ai besoin d'obtenir la valeur maximale de l'axe y de chaque graphique de densité afin de tracer la vline moyenne de chaque graphique en conséquence. J'ai essayé avec np.argmax()
, mais cela ne semble pas fonctionner.
Aucune suggestion?
Réponses
pandas.DataFrame.plot()renvoie un matplotlib.axes.Axesobjet. Vous pouvez utiliser la get_ylim()fonction pour obtenir ymin et ymax.
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
df = pd.DataFrame({"X": np.random.randint(50,53,size=100),
"Y": np.random.randint(200,300,size=100),
"Z": np.random.randint(400,800,size=100)})
for i in df.columns:
data = df[i]
ax = data.plot(kind="kde")
ymin, ymax = ax.get_ylim()
plt.vlines(x=data.mean(),ymin=ymin, ymax=ymax, linestyles="dotted")
plt.show()
Pour obtenir la valeur du kde correspondant à la moyenne, vous pouvez extraire la courbe du graphique et l'interpoler à la position de la moyenne:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
df = pd.DataFrame({"X": 20 + np.random.randint(-1, 2, size=100).cumsum(),
"Y": 30 + np.random.randint(-1, 2, size=100).cumsum(),
"Z": 40 + np.random.randint(-1, 2, size=100).cumsum()})
fig, ax = plt.subplots()
for col in df.columns:
data = df[col]
data.plot(kind="kde", ax=ax)
x = data.mean()
kdeline = ax.lines[-1]
ymax = np.interp(x, kdeline.get_xdata(), kdeline.get_ydata())
ax.vlines(x=data.mean(), ymin=0, ymax=ymax, linestyles="dotted")
ax.set_ylim(ymin=0) # ax.vlines() moves the bottom ylim; set it back to 0
plt.show()
Utilisez plt.axvline. Vous spécifiez les limites sous forme de nombres compris dans la plage [0,1], 0 étant le bas du graphique, 1 le haut.
for i in df.columns:
data = df[i]
data.plot(kind="kde")
plt.axvline(data.mean(), 0, 1, linestyle='dotted', color='black')
plt.show()