Построение гистограммы из предварительно подсчитанных данных в Matplotlib
Я хотел бы использовать Matplotlib для построения гистограммы над данными, которые были предварительно подсчитаны. Например, скажем, у меня есть необработанные данные
data = [1, 2, 2, 3, 4, 5, 5, 5, 5, 6, 10]
Учитывая эти данные, я могу использовать
pylab.hist(data, bins=[...])
для построения гистограммы.
В моем случае данные были предварительно подсчитаны и представлены в виде словаря:
counted_data = {1: 1, 2: 2, 3: 1, 4: 1, 5: 4, 6: 1, 10: 1}
В идеале, я бы хотел передать эти предварительно подсчитанные данные функции гистограммы, которая позволяет мне управлять шириной бина, диапазоном графика и т.д., как если бы я передал ему необработанные данные. В качестве обходного пути я расширяю свои счета до необработанных данных:
data = list(chain.from_iterable(repeat(value, count) for (value, count) in counted_data.iteritems()))
Это неэффективно, когда counted_data
содержит подсчеты для миллионов точек данных.
Существует ли более простой способ использования Matplotlib для создания гистограммы из моих предварительно подсчитанных данных?
В качестве альтернативы, если проще всего использовать данные штрихового графика, предварительно подготовленные, есть ли удобный метод для "свертывания" моих подсчетов по каждому элементу в подсчет числа?
Ответы
Ответ 1
Я использовал параметр pyplot.hist weights
для взвешивания каждой клавиши по ее значению, создавая гистограмму, которую я хотел:
pylab.hist(counted_data.keys(), weights=counted_data.values(), bins=range(50))
Это позволяет мне полагаться на hist
для повторной загрузки моих данных.
Ответ 2
Вы можете использовать аргумент ключевого слова weights
для np.histgram
(который plt.hist
вызывает под ним)
val, weight = zip(*[(k, v) for k,v in counted_data.items()])
plt.hist(val, weights=weight)
Предполагая, что у вас есть только целые числа, вы также можете напрямую использовать bar
:
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, ...)
где... это то, что вы хотите передать в bar
(doc)
Если вы хотите переустановить свои данные, см. Гистограмма с отдельной частотой обозначений в списке
Ответ 3
длина массива "бинов" должна быть длиннее длины "counts". Здесь можно полностью восстановить гистограмму:
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)