Python 根据Matplotlib中的预计数数据绘制直方图
我想使用Matplotlib在预先计算的数据上绘制直方图。例如,假设我有原始数据Python 根据Matplotlib中的预计数数据绘制直方图,python,matplotlib,histogram,Python,Matplotlib,Histogram,我想使用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 = [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从预先计算的数据生成直方图
或者,如果最简单的方法是预先装箱的条形图数据,是否有一种方便的方法将我的每项计数“汇总”到装箱计数中?您可以使用
权重关键字参数来np.histgram
(下面调用plt.hist
)
假设只有整数作为键,也可以直接使用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
如果要重新存储数据,请参见我使用的
权重
选项根据每个关键点的值对其进行权重,生成我想要的直方图:
pylab.hist(counted_data.keys(),weights=counted_data.values(),bin=range(50))
这允许我依靠hist
重新存储数据。存储单元数组的长度应大于“计数”的长度。以下是完全重建直方图的方法:
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)
您还可以使用seaborn绘制直方图:
import seaborn as sns
sns.distplot(
list(
counted_data.keys()
),
hist_kws={
"weights": list(counted_data.values())
}
)
除了tacaswell的评论之外,
plt.bar
对于大量的垃圾箱(>1e4),比plt.hist
更有效。特别是对于拥挤的随机绘图,您只需要绘制最高的条形图,因为查看它们所需的宽度将覆盖它们的大部分邻居。您可以选择最高的条形图并用
i, = np.where(vals > min_height)
plt.bar(i,vals[i],width=len(bins)//50)
其他统计趋势可能更倾向于每100个条形图或类似的图
这里的诀窍是,
plt.hist
想要绘制所有的箱子,而plt.bar
只需要绘制更稀疏的可见箱子集。感谢指向权重
选项的指针;我忽略了它,但它完美地解决了我的问题(见我的答案)。我没有建立这种联系(直接使用bar
)。编辑以反映您的评论。您获取数据的方式比我的方式更有意义。如果你接受你自己的答案,我没问题。这是我需要的线索。在我的例子中,我有一个计数列表和箱子范围:plt.hist(箱子,箱子=len(箱子),重量=counts)
是我需要的调用警告:我注意到如果箱子大小不同,这会给出错误的结果,并且使用了density=True
。可能不是错误,而是pdf和cdf之间的数学差异。作为旁注:要将计数扩展为原始数据,您还可以使用计数器
类及其元素()方法:从集合导入计数器
c=计数器(计数的数据)数据=列表(c.元素())
i, = np.where(vals > min_height)
plt.bar(i,vals[i],width=len(bins)//50)