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)

enter image description here

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!

16
demandé sur I am not George 2015-07-31 18:04:38

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

Countplot

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 --- )

35
répondu cphlewis 2017-01-28 14:58:03

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")

enter image description here

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.

0
répondu Lord Zsolt 2018-08-23 22:24:41