Comment ajouter des pourcentages sur les barres en seaborn?
compte tenu de la courbe de comptage suivante, Comment dois-je placer les pourcentages sur les barres?
import seaborn as sns
sns.set(style="darkgrid")
titanic = sns.load_dataset("titanic")
ax = sns.countplot(x="class", hue="who", data=titanic)
par exemple Pour la "Première" je veux le nombre total d'hommes/nombre total d'Abord, le total des Premières femmes/total de la Première, et le nombre total d'enfants/total d'Abord sur la tête de leur des bars.
s'il vous Plaît laissez-moi savoir si mon explication n'est pas claire.
Merci!
2 réponses
sns.barplot
ne renvoie pas explicitement les valeurs de barplot de la façon patches dans les axes se trouvent vos valeurs. Vous pouvez alors utiliser les sous-totaux que la fonction barplot a calculés pour vous:
from matplotlib.pyplot import show
import seaborn as sns
sns.set(style="darkgrid")
titanic = sns.load_dataset("titanic")
total = float(len(titanic)) # one person per row
#ax = sns.barplot(x="class", hue="who", data=titanic)
ax = sns.countplot(x="class", hue="who", data=titanic) # for Seaborn version 0.7 and more
for p in ax.patches:
height = p.get_height()
ax.text(p.get_x()+p.get_width()/2.,
height + 3,
'{:1.2f}'.format(height/total),
ha="center")
show()
produit
une autre approche consiste à faire explicitement la sous-sommation, par exemple avec l'excellent pandas
, et avec terrain matplotlib
, et aussi faire le style vous-même. (Bien que vous pouvez obtenir beaucoup de style sns
même lors de l'utilisation de matplotlib
fonctions de pointage. Essayez --- )
Avec l'aide de cplewis's solution, j'ai réussi à mettre les pourcentages corrects en haut du tableau, donc les classes se résument à un.
for index, category in enumerate(categorical):
plt.subplot(plot_count, 1, index + 1)
order = sorted(data[category].unique())
ax = sns.countplot(category, data=data, hue="churn", order=order)
ax.set_ylabel('')
bars = ax.patches
half = int(len(bars)/2)
left_bars = bars[:half]
right_bars = bars[half:]
for left, right in zip(left_bars, right_bars):
height_l = left.get_height()
height_r = right.get_height()
total = height_l + height_r
ax.text(left.get_x() + left.get_width()/2., height_l + 40, '{0:.0%}'.format(height_l/total), ha="center")
ax.text(right.get_x() + right.get_width()/2., height_r + 40, '{0:.0%}'.format(height_r/total), ha="center")
cependant, la solution suppose qu'il y a 2 options (Homme, Femme) au lieu de 3 (Homme, Femme, Enfant).
Depuis Axes.patches
sont commandés de manière étrange (la première de toutes les barres bleues, toutes les barres vertes, puis toutes les barres rouges), vous auriez à les diviser et zip ensemble en conséquence.