Afin de confirmer la distribution des données pour chaque étiquette, les histogrammes sont souvent superposés et tracés, mais il existe des cas où la différence de largeur de bac est perceptible en fonction des données. Cela ne se produit pas même si vous utilisez des outils BI tels que Tableau, mais matplotlib et seaborn ne l'ajustent pas seuls, vous devez donc le gérer vous-même.
Utilisez l'argument bins
.
bins : int or sequence or str, optional matplotlib.pyplot.hist
Puisque bins
peut recevoir non seulement des valeurs entières mais aussi des séquences
,
Il vous suffit de spécifier les valeurs maximum et minimum dans la fonction de plage et de définir le nombre de divisions souhaité.
import numpy as np
import matplotlib.pyplot as plt
#Préparer un DataFrame avec deux types d'étiquettes et une distribution de données différente
df_1st = pd.DataFrame(np.random.normal(loc=20, scale=10, size=100), columns=["val"])
df_1st["target"] = "class_1"
df_2nd = pd.DataFrame(np.random.normal(loc=15, scale=20, size=100), columns=["val"])
df_2nd["target"] = "class_2"
df = pd.concat([df_1st, df_2nd])
import matplotlib as plt
import seaborn as sns
#Tracer pour chaque cible
for val in df["target"].unique():
ax = sns.distplot(df.query('target == @val')["val"], kde=False, label=f"target is {val}")
ax.legend()
#valeur minimum
x_min = int(df["val"].min())
#Valeur maximum
x_max = int(df["val"].max())
#5 intervalles dans la plage allant de la valeur minimale à la valeur maximale
range_bin_width = range(x_min, x_max, 5)
#Tracer pour chaque cible
for val in df["target"].unique():
ax = sns.distplot(df.query('target == @val')["val"], bins=range_bin_width, kde=False, label=f"target is {val}")
ax.legend()
Si bins
n'est pas défini, le nombre de bins est déterminé par une méthode appelée ** règle de Freedman-Diaconis **.
Cette technique est raisonnablement bonne, et lors du traçage d'une seule donnée, elle trace généralement sans problème.
distributions.py
def _freedman_diaconis_bins(a):
"""Calculate number of hist bins using Freedman-Diaconis rule."""
# From https://stats.stackexchange.com/questions/798/
a = np.asarray(a)
if len(a) < 2:
return 1
h = 2 * iqr(a) / (len(a) ** (1 / 3))
# fall back to sqrt(a) bins if iqr is 0
if h == 0:
return int(np.sqrt(a.size))
else:
return int(np.ceil((a.max() - a.min()) / h))
https://github.com/mwaskom/seaborn/blob/master/seaborn/distributions.py#L24
L'intrigue n'est pas belle parce que l'intrigue est impolie envers la personne à qui vous la montrez Je pense qu'il est poli de le rendre au moins propre.
Recommended Posts