Je voudrais utiliser Matplotlib pour tracer un histogramme sur des données qui ont été pré-comptées. Par exemple, disons que j'ai les données brutes
data = [1, 2, 2, 3, 4, 5, 5, 5, 5, 6, 10]
Compte tenu de ces données, je peux utiliser
pylab.hist(data, bins=[...])
pour tracer un histogramme.
Dans mon cas, les données ont été pré-comptées et sont représentées comme un dictionnaire:
counted_data = {1: 1, 2: 2, 3: 1, 4: 1, 5: 4, 6: 1, 10: 1}
Idéalement, j'aimerais transmettre ces données pré-comptées à une fonction d'histogramme qui me permet de contrôler les largeurs de bacs, la plage de tracé, etc., comme si je leur avais transmis les données brutes. Comme solution de contournement, j'étends mes comptes dans les données brutes:
data = list(chain.from_iterable(repeat(value, count)
for (value, count) in counted_data.iteritems()))
C'est inefficace lorsque counted_data
contient le nombre de millions de points de données.
Existe-t-il un moyen plus simple d'utiliser Matplotlib pour produire un histogramme à partir de mes données pré-comptées?
Sinon, s'il est plus facile de simplement tracer des données qui ont été pré-regroupées, existe-t-il une méthode pratique pour "cumuler" mes comptes par article en nombres regroupés?
J'ai utilisé pyplot.hist l'option weights
pour pondérer chaque clé par sa valeur, produisant l'histogramme que je voulais:
pylab.hist(counted_data.keys(), weights=counted_data.values(), bins=range(50))
Cela me permet de compter sur hist
pour regrouper mes données.
Vous pouvez utiliser l'argument de mot clé weights
pour np.histgram
(lequel plt.hist
appels en dessous)
val, weight = Zip(*[(k, v) for k,v in counted_data.items()])
plt.hist(val, weights=weight)
En supposant que vous seulement ayez des entiers comme clés, vous pouvez également utiliser bar
directement:
min_bin = np.min(counted_data.keys())
max_bin = np.max(counted_data.keys())
bins = np.arange(min_bin, max_bin + 1)
vals = np.zeros(max_bin - min_bin + 1)
for k,v in counted_data.items():
vals[k - min_bin] = v
plt.bar(bins, vals, ...)
où ... correspond aux arguments que vous souhaitez transmettre à bar
(doc)
Si vous souhaitez regrouper vos données, voir Histogramme avec liste séparée indiquant la fréquence
Vous pouvez également utiliser seaborn pour tracer l'histogramme:
import matplotlib.pyplot as plt
import seaborn as sns
sns.distplot(list(counted_data.keys()), hist_kws={"weights":list(counted_data.values())})
la longueur du tableau "bacs" doit être plus longue que la longueur des "comptes". Voici la façon de reconstruire entièrement l'histogramme:
import numpy as np
import matplotlib.pyplot as plt
bins = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9]).astype(float)
counts = np.array([5, 3, 4, 5, 6, 1, 3, 7]).astype(float)
centroids = (bins[1:] + bins[:-1]) / 2
counts_, bins_, _ = plt.hist(centroids, bins=len(counts),
weights=counts, range=(min(bins), max(bins)))
plt.show()
assert np.allclose(bins_, bins)
assert np.allclose(counts_, counts)