J'utilise matplotlib pour créer un histogramme.
Existe-t-il un moyen de définir manuellement la taille des bacs par opposition au nombre de bacs?
J'utilise matplotlib pour créer un histogramme.
Existe-t-il un moyen de définir manuellement la taille des bacs par opposition au nombre de bacs?
Réponses:
En fait, c'est assez simple: au lieu du nombre de bacs, vous pouvez donner une liste avec les limites des bacs. Ils peuvent également être inégalement répartis:
plt.hist(data, bins=[0, 10, 20, 30, 40, 50, 100])
Si vous souhaitez simplement les distribuer de manière égale, vous pouvez simplement utiliser range:
plt.hist(data, bins=range(min(data), max(data) + binwidth, binwidth))
Ajouté à la réponse d'origine
La ligne ci-dessus ne fonctionne que pour les data
nombres entiers. Comme le souligne macrocosme , pour les flotteurs, vous pouvez utiliser:
import numpy as np
plt.hist(data, bins=np.arange(min(data), max(data) + binwidth, binwidth))
(data.max() - data.min()) / number_of_bins_you_want
. Le + binwidth
pourrait être changé en juste 1
pour en faire un exemple plus facile à comprendre.
lw = 5, color = "white"
ou similaire insère des espaces blancs entre les barres
Pour N bacs, les bords de bac sont spécifiés par une liste de N + 1 valeurs où les N premiers donnent les bords de bac inférieurs et le +1 donne le bord supérieur du dernier bac.
Code:
from numpy import np; from pylab import *
bin_size = 0.1; min_edge = 0; max_edge = 2.5
N = (max_edge-min_edge)/bin_size; Nplus1 = N + 1
bin_list = np.linspace(min_edge, max_edge, Nplus1)
Notez que linspace produit un tableau de min_edge à max_edge divisé en N + 1 valeurs ou N bins
Je suppose que le moyen le plus simple serait de calculer le minimum et le maximum des données dont vous disposez, puis de calculer L = max - min
. Ensuite, vous divisez L
par la largeur de bac souhaitée (je suppose que c'est ce que vous entendez par taille de bac) et utilisez le plafond de cette valeur comme nombre de bacs.
J'aime que les choses se passent automatiquement et que les bacs retombent sur de «belles» valeurs. Ce qui suit semble très bien fonctionner.
import numpy as np
import numpy.random as random
import matplotlib.pyplot as plt
def compute_histogram_bins(data, desired_bin_size):
min_val = np.min(data)
max_val = np.max(data)
min_boundary = -1.0 * (min_val % desired_bin_size - min_val)
max_boundary = max_val - max_val % desired_bin_size + desired_bin_size
n_bins = int((max_boundary - min_boundary) / desired_bin_size) + 1
bins = np.linspace(min_boundary, max_boundary, n_bins)
return bins
if __name__ == '__main__':
data = np.random.random_sample(100) * 123.34 - 67.23
bins = compute_histogram_bins(data, 10.0)
print(bins)
plt.hist(data, bins=bins)
plt.xlabel('Value')
plt.ylabel('Counts')
plt.title('Compute Bins Example')
plt.grid(True)
plt.show()
Le résultat a des bacs sur de beaux intervalles de taille de bac.
[-70. -60. -50. -40. -30. -20. -10. 0. 10. 20. 30. 40. 50. 60.]
desired_bin_size=0.05
, min_boundary=0.850
, max_boundary=2.05
le calcul de n_bins
se int(23.999999999999993)
qui se traduit par 23 au lieu de 24 et donc un bac trop peu. Un arrondi avant la conversion entière a fonctionné pour moi:n_bins = int(round((max_boundary - min_boundary) / desired_bin_size, 0)) + 1
J'utilise des quantiles pour faire des bacs uniformes et ajustés pour échantillonner:
bins=df['Generosity'].quantile([0,.05,0.1,0.15,0.20,0.25,0.3,0.35,0.40,0.45,0.5,0.55,0.6,0.65,0.70,0.75,0.80,0.85,0.90,0.95,1]).to_list()
plt.hist(df['Generosity'], bins=bins, normed=True, alpha=0.5, histtype='stepfilled', color='steelblue', edgecolor='none')
np.arange(0, 1.01, 0.5)
ou np.linspace(0, 1, 21)
. Il n'y a pas d'arêtes, mais je comprends que les boîtes ont une surface égale, mais une largeur différente sur l'axe X?
J'ai eu le même problème que OP (je pense!), Mais je ne pouvais pas le faire fonctionner de la manière spécifiée par Lastalda. Je ne sais pas si j'ai bien interprété la question, mais j'ai trouvé une autre solution (c'est probablement une très mauvaise façon de le faire cependant).
Voici comment je l'ai fait:
plt.hist([1,11,21,31,41], bins=[0,10,20,30,40,50], weights=[10,1,40,33,6]);
Ce qui crée ceci:
Donc, le premier paramètre «initialise» fondamentalement le bac - je crée spécifiquement un nombre qui se situe entre la plage que j'ai définie dans le paramètre bins.
Pour le démontrer, regardez le tableau dans le premier paramètre ([1,11,21,31,41]) et le tableau 'bins' dans le deuxième paramètre ([0,10,20,30,40,50]) :
Ensuite, j'utilise le paramètre «poids» pour définir la taille de chaque bac. Il s'agit du tableau utilisé pour le paramètre poids: [10,1,40,33,6].
Ainsi, le bac 0 à 10 reçoit la valeur 10, le bac 11 à 20 a la valeur 1, le bac 21 à 30 a la valeur 40, etc.
Pour un histogramme avec des valeurs x entières, j'ai fini par utiliser
plt.hist(data, np.arange(min(data)-0.5, max(data)+0.5))
plt.xticks(range(min(data), max(data)))
Le décalage de 0,5 centre les cases sur les valeurs de l'axe des x. L' plt.xticks
appel ajoute une coche pour chaque entier.