我想使用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从我预先计算的数据中生成直方图?
或者,如果最简单的条形图是预先装箱的数据,那么是否有一种方便的方法来推广""我的每个项目都计入分类计数?
答案 0 :(得分:20)
您可以使用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)
如果您想重新收集数据,请参阅Histogram with separate list denoting frequency
答案 1 :(得分:17)
我使用pyplot.hist的weights
选项按每个键的值加权,生成我想要的直方图:
pylab.hist(counted_data.keys(), weights=counted_data.values(), bins=range(50))
这使我可以依靠hist
重新收集数据。
答案 2 :(得分:2)
" bins"的长度数组应该长于"计数"。以下是完全重建直方图的方法:
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)
答案 3 :(得分:1)
您也可以使用seaborn绘制直方图:
import matplotlib.pyplot as plt
import seaborn as sns
sns.distplot(list(counted_data.keys()), hist_kws={"weights":list(counted_data.values())})
答案 4 :(得分:0)
添加到 tacaswell 的评论中,对于大量 bin (>1e4),plt.bar
在这里比 plt.hist
效率更高。特别是对于拥挤的随机图,您只需要绘制最高的条形图,因为查看它们所需的宽度将覆盖大多数邻居。您可以挑选出最高的条形并用
i, = np.where(vals > min_height)
plt.bar(i,vals[i],width=len(bins)//50)
其他统计趋势可能更喜欢每隔 100 个条形图或类似的东西绘制。
这里的技巧是 plt.hist
想要绘制所有的 bin,而 plt.bar
会让你只绘制一组稀疏的可见 bin。