Compte tenu du tracé de comptage suivant, comment puis-je placer des pourcentages au-dessus des 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 "First", je veux que le total First Men/total First, le total First Women/total First et le total First Children/total First soient affichés en haut de leurs barres respectives.
Veuillez me faire savoir si mon explication n'est pas claire.
Merci!
sns.barplot
ne renvoie pas explicitement les valeurs du diagramme à barres comme matplotlib.pyplot.bar
le fait (voir le dernier paragraphe), mais si vous n'avez rien tracé d'autre, vous pouvez risquer de supposer que tous les patches
dans les axes sont vos valeurs. Ensuite, vous pouvez utiliser les sous-totaux que la fonction de graphique à barres a calculé 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 à effectuer la sous-sommation explicitement, par exemple avec l'excellent pandas
, et tracer avec matplotlib
, et faire le style vous-même. (Bien que vous puissiez obtenir beaucoup de style à partir du contexte sns
même en utilisant les fonctions de traçage matplotlib
. Essayez-le -)
Avec l'aide de la solution cphlewis , 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) contre 3 (homme, femme, enfant).
Puisque Axes.patches
sont classés de manière étrange (d'abord toutes les barres bleues, puis toutes les barres vertes, puis toutes les barres rouges), vous devez les diviser et les recompresser en conséquence.