web-dev-qa-db-fra.com

Comment insérer des annotations statistiques (étoiles ou valeurs p) dans les graphiques matplotlib / seaborn?

Cela semble être une question banale, mais je cherche depuis un certain temps et je n'arrive pas à trouver de réponse. Cela semble également être quelque chose qui devrait être une partie standard de ces packages. Est-ce que quelqu'un sait s'il existe un moyen standard d'inclure des annotations statistiques entre les parcelles de distribution dans Seaborn?

Par exemple, entre deux boîtes ou parcelles d'essaim?

Example: the yellow distribution is significantly different than the others (by wilcoxon - how can i display that visually?

24
cancerconnector

Voici comment ajouter une annotation statistique à un diagramme en boîte Seaborn:

import seaborn as sns, matplotlib.pyplot as plt

tips = sns.load_dataset("tips")
sns.boxplot(x="day", y="total_bill", data=tips, palette="PRGn")

# statistical annotation
x1, x2 = 2, 3   # columns 'Sat' and 'Sun' (first column: 0, see plt.xticks())
y, h, col = tips['total_bill'].max() + 2, 2, 'k'
plt.plot([x1, x1, x2, x2], [y, y+h, y+h, y], lw=1.5, c=col)
plt.text((x1+x2)*.5, y+h, "ns", ha='center', va='bottom', color=col)

plt.show()

Et voici le résultat: box plot annotated

32
Ulrich Stern

On peut également souhaiter ajouter plusieurs annotations à différentes paires de cases. Dans ce cas, il peut être utile de gérer automatiquement le placement des différentes lignes et textes dans l'axe des y. Moi et d'autres contributeurs avons écrit une petite fonction pour gérer ces cas (voir Repo Github ), qui empile correctement les lignes les unes sur les autres sans se chevaucher. Les annotations peuvent être à l'intérieur ou à l'extérieur de la parcelle, et plusieurs tests statistiques sont implémentés: Mann-Whitney et t-test (indépendants et appariés). Voici un exemple minimal.

import matplotlib.pyplot as plt
import seaborn as sns
from statannot import add_stat_annotation

sns.set(style="whitegrid")
df = sns.load_dataset("tips")

x = "day"
y = "total_bill"
order = ['Sun', 'Thur', 'Fri', 'Sat']
ax = sns.boxplot(data=df, x=x, y=y, order=order)
add_stat_annotation(ax, data=df, x=x, y=y, order=order,
                    box_pairs=[("Thur", "Fri"), ("Thur", "Sat"), ("Fri", "Sun")],
                    test='Mann-Whitney', text_format='star', loc='outside', verbose=2)

example1

x = "day"
y = "total_bill"
hue = "smoker"
ax = sns.boxplot(data=df, x=x, y=y, hue=hue)
add_stat_annotation(ax, data=df, x=x, y=y, hue=hue,
                    box_pairs=[(("Thur", "No"), ("Fri", "No")),
                                 (("Sat", "Yes"), ("Sat", "No")),
                                 (("Sun", "No"), ("Thur", "Yes"))
                                ],
                    test='t-test_ind', text_format='full', loc='inside', verbose=2)
plt.legend(loc='upper left', bbox_to_anchor=(1.03, 1))

example2

14
fokkerplanck