Seaborn: countplot() avec des fréquences
J'ai une Pandas DataFrame avec une colonne appelée "ESSIEUX", ce qui peut prendre une valeur entière entre 3-12. Je suis en train d'utiliser Seaborn de countplot option() pour obtenir les courbes ci-dessous:
- gauche de l'axe y indique les fréquences de ces valeurs se produisant dans les données. L'axe s'étend sont [0%-100%], les graduations à 10%.
- à droite de l'axe y indique le nombre de compte, les valeurs correspondent aux graduations déterminé par la gauche de l'axe y (marquées à 10%.)
- axe des x indique les catégories de la barre de parcelles [3, 4, 5, 6, 7, 8, 9, 10, 11, 12].
- Annotation sur le dessus des barres indiquent le pourcentage réel de cette catégorie.
Le code suivant me donne le graphique ci-dessous, avec la réalité des comptes, mais je ne pouvais pas trouver un moyen de les convertir en fréquences. Je peux obtenir les fréquences à l'aide de df.AXLES.value_counts()/len(df.index)
mais je ne suis pas sûr de savoir comment brancher cette information dans Seaborn de countplot()
.
J'ai aussi trouvé une solution de contournement pour les annotations, mais je ne suis pas sûr si c'est la meilleure mise en œuvre.
Toute aide serait appréciée!
Grâce
plt.figure(figsize=(12,8))
ax = sns.countplot(x="AXLES", data=dfWIM, order=[3,4,5,6,7,8,9,10,11,12])
plt.title('Distribution of Truck Configurations')
plt.xlabel('Number of Axles')
plt.ylabel('Frequency [%]')
for p in ax.patches:
ax.annotate('%{:.1f}'.format(p.get_height()), (p.get_x()+0.1, p.get_height()+50))
EDIT:
Je suis plus près de ce dont j'ai besoin avec le code suivant, en utilisant des Pandas bar de la parcelle, d'amerrissage Seaborn. Se sent comme je suis en utilisant donc beaucoup de solutions de contournement, et il y a un moyen plus facile de le faire. Le problème avec cette approche:
- Il n'y a pas de
order
mot-clé dans des Pandas de la barre de fonction plot comme Seaborn de countplot (), donc je ne peut pas tracer toutes les catégories de 3-12 comme je l'ai fait dans le countplot(). J'ai besoin de les avoir montré, même si il n'y a pas de données dans cette catégorie. -
L'axe y secondaire bousille les bars et l'annotation pour une raison quelconque (voir le blanc quadrillage dessiné sur le texte et les bars).
plt.figure(figsize=(12,8)) plt.title('Distribution of Truck Configurations') plt.xlabel('Number of Axles') plt.ylabel('Frequency [%]') ax = (dfWIM.AXLES.value_counts()/len(df)*100).sort_index().plot(kind="bar", rot=0) ax.set_yticks(np.arange(0, 110, 10)) ax2 = ax.twinx() ax2.set_yticks(np.arange(0, 110, 10)*len(df)/100) for p in ax.patches: ax.annotate('{:.2f}%'.format(p.get_height()), (p.get_x()+0.15, p.get_height()+1))
- Pourquoi ne pas diviser le ticklabels par le nombre total d'obtenir des fréquences?
- Je l'ai essayé à l'aide de
vals = ax.get_yticks()
etax.set_yticks(vals/len(df))
. Cependant, une fois que je le fais, toutes les étiquettes de la fin jusqu'au bas de l'écran près de l'origine, en raison de la y réelle à l'échelle de la parcelle. Évidemment, mon approche est erronée. Comment le feriez-vous?
Vous devez vous connecter pour publier un commentaire.
Vous pouvez le faire en faisant un
twinx
axes pour les fréquences. Vous pouvez passer les deux axes y autour de sorte que les fréquences rester sur la gauche et les chiffres sur la droite, mais sans avoir à recalculer le compte de l'axe (ici nous utilisonstick_left()
ettick_right()
pour déplacer les tiques et lesset_label_position
pour déplacer les étiquettes de l'axe desVous pouvez ensuite définir les tiques à l'aide de la
matplotlib.ticker
module, spécifiquementticker.MultipleLocator
etticker.LinearLocator
.Que pour vos annotations, vous pouvez obtenir les coordonnées x et y des emplacements pour tous les 4 coins de la barre avec
patch.get_bbox().get_points()
. Ceci, avec le réglage de l'alignement horizontal et vertical correctement, signifie que vous n'avez pas besoin d'ajouter de l'arbitraire, des compensations à l'annotation de l'emplacement.Enfin, vous devez activer la grille off pour le jumelage de l'axe, pour éviter les lignes de la grille montrant au-dessus des barres (
ax2.grille(Aucun)
)Ici est un travail de script:
# Fix the frequency range to 0-100 without changing axes zoom:
ax2.set_ylim(0,100*ax.get_ylim()[1]/ncount)
Je l'ai eu à travailler à l'aide de base
matplotlib
's bar de la parcelle. Je n'ai pas eu de vos données, évidemment, mais de l'adapter à la vôtre doit être simple.Approche
J'ai utilisé
matplotlib
jumeaux de l'axe et représenter graphiquement les données que les bars sur la deuxièmeAxes
objet. Le reste ist juste quelques fiddeling autour pour obtenir les tiques et de faire des annotations.Espère que cette aide.
Code
Je pense que vous pouvez commencer par définir l'axe des graduations principales manuellement, puis modifier chaque étiquette