有没有办法用 Matplotlib 绘制具有给定 bin 宽度的直方图?
Is there a way to plot a histogram with given bin widths with Mathplotlib?
我有两个列表。
一个名为“bin_edge”,用 25 个值表示 24 个 bin 的下边界和上边界。第二个名为“counts”,表示每个 bin 的相应计数(=值)。
我的目标是,如果可能的话,得到一个 Matplotlib 直方图,它应该看起来有点像:
所以,我面临的第一个困难是第一个bin是位于bin_edge
的前两个值之间的部分,第二个bin是[=11的第二个和第三个元素之间的部分=] 等等...
表示 counts
的一个值连接到 bin_edge
列表的两个边界(下限和上限)。
第二个症结:我想画对数的 x 轴和 y 轴。
我尝试的代码:
bin_edge = [0.36, 0.46, 0.66, 1.00, 1.30, 1.70, 2.20, 3.00, 4.00,
5.20, 6.50, 8.00, 10.00, 12.00, 14.00, 16.00, 18.00,
20.00, 22.00, 25.00, 28.00, 31.00, 34.00, 37.00, 40.00]
counts = [159746491, 9316595, 855578, 166092, 151198, 41293, 51051,
26098, 38536, 1172, 2.872e-12, 24598, 3.27097e-12, 3.86874e-12,
4.46613e-12, 5.06328e-12, 5.6602754e-12, 6.2571442e-12, 4.6652e-12,
5.26229e-12, 5.8592429e-12, 0, 7.052837e-12, 0]
plt.hist([counts], bins=bin_edge)
plt.xscale('log')
plt.yscale('log')
plt.xlabel('Size / µm')
plt.ylabel('counts')
plt.title('Histogram')
plt.show()
这会导致一个空的情节。
当然也欢迎除 Matplotlib 之外的任何其他解决方案,包括散景:-)
因为您已经有了每个 bin 的高度,所以您应该创建一个条形图。
x-values 应该是 bin 边缘,除了最后一个。默认情况下,条形图居中;您需要 align='edge'
将它们与垃圾箱边缘对齐。条形的宽度是 bin 边缘的差异。
from matplotlib import pyplot as plt
from matplotlib.ticker import FormatStrFormatter
import numpy as np
bin_edge = [0.36, 0.46, 0.66, 1.00, 1.30, 1.70, 2.20, 3.00, 4.00,
5.20, 6.50, 8.00, 10.00, 12.00, 14.00, 16.00, 18.00,
20.00, 22.00, 25.00, 28.00, 31.00, 34.00, 37.00, 40.00]
counts = [159746491, 9316595, 855578, 166092, 151198, 41293, 51051,
26098, 38536, 1172, 2.872e-12, 24598, 3.27097e-12, 3.86874e-12,
4.46613e-12, 5.06328e-12, 5.6602754e-12, 6.2571442e-12, 4.6652e-12,
5.26229e-12, 5.8592429e-12, 0, 7.052837e-12, 0]
fig, ax = plt.subplots(figsize=(12, 5))
ax.bar(x=bin_edge[:-1], height=counts, width=np.diff(bin_edge), align='edge', fc='MediumOrchid', ec='black')
ax.set_xscale('log')
ax.set_yscale('log')
ax.set_xlabel('Size / µm')
ax.set_ylabel('counts')
ax.set_title('Histogram')
ax.margins(x=0.01) # less margin left and right
ax.xaxis.set_major_formatter(FormatStrFormatter('%g'))
ax.xaxis.set_minor_formatter(FormatStrFormatter('%g'))
# "length" is the length of the tick mark, it also changes the text offset
# "labelsize" is the fontsize of the tick label
ax.tick_params(axis='x', which='minor', length=5, labelsize=8)
ax.tick_params(axis='x', which='major', length=10, labelsize=12)
plt.tight_layout()
plt.show()
我有两个列表。 一个名为“bin_edge”,用 25 个值表示 24 个 bin 的下边界和上边界。第二个名为“counts”,表示每个 bin 的相应计数(=值)。
我的目标是,如果可能的话,得到一个 Matplotlib 直方图,它应该看起来有点像:
所以,我面临的第一个困难是第一个bin是位于bin_edge
的前两个值之间的部分,第二个bin是[=11的第二个和第三个元素之间的部分=] 等等...
表示 counts
的一个值连接到 bin_edge
列表的两个边界(下限和上限)。
第二个症结:我想画对数的 x 轴和 y 轴。
我尝试的代码:
bin_edge = [0.36, 0.46, 0.66, 1.00, 1.30, 1.70, 2.20, 3.00, 4.00,
5.20, 6.50, 8.00, 10.00, 12.00, 14.00, 16.00, 18.00,
20.00, 22.00, 25.00, 28.00, 31.00, 34.00, 37.00, 40.00]
counts = [159746491, 9316595, 855578, 166092, 151198, 41293, 51051,
26098, 38536, 1172, 2.872e-12, 24598, 3.27097e-12, 3.86874e-12,
4.46613e-12, 5.06328e-12, 5.6602754e-12, 6.2571442e-12, 4.6652e-12,
5.26229e-12, 5.8592429e-12, 0, 7.052837e-12, 0]
plt.hist([counts], bins=bin_edge)
plt.xscale('log')
plt.yscale('log')
plt.xlabel('Size / µm')
plt.ylabel('counts')
plt.title('Histogram')
plt.show()
这会导致一个空的情节。
当然也欢迎除 Matplotlib 之外的任何其他解决方案,包括散景:-)
因为您已经有了每个 bin 的高度,所以您应该创建一个条形图。
x-values 应该是 bin 边缘,除了最后一个。默认情况下,条形图居中;您需要 align='edge'
将它们与垃圾箱边缘对齐。条形的宽度是 bin 边缘的差异。
from matplotlib import pyplot as plt
from matplotlib.ticker import FormatStrFormatter
import numpy as np
bin_edge = [0.36, 0.46, 0.66, 1.00, 1.30, 1.70, 2.20, 3.00, 4.00,
5.20, 6.50, 8.00, 10.00, 12.00, 14.00, 16.00, 18.00,
20.00, 22.00, 25.00, 28.00, 31.00, 34.00, 37.00, 40.00]
counts = [159746491, 9316595, 855578, 166092, 151198, 41293, 51051,
26098, 38536, 1172, 2.872e-12, 24598, 3.27097e-12, 3.86874e-12,
4.46613e-12, 5.06328e-12, 5.6602754e-12, 6.2571442e-12, 4.6652e-12,
5.26229e-12, 5.8592429e-12, 0, 7.052837e-12, 0]
fig, ax = plt.subplots(figsize=(12, 5))
ax.bar(x=bin_edge[:-1], height=counts, width=np.diff(bin_edge), align='edge', fc='MediumOrchid', ec='black')
ax.set_xscale('log')
ax.set_yscale('log')
ax.set_xlabel('Size / µm')
ax.set_ylabel('counts')
ax.set_title('Histogram')
ax.margins(x=0.01) # less margin left and right
ax.xaxis.set_major_formatter(FormatStrFormatter('%g'))
ax.xaxis.set_minor_formatter(FormatStrFormatter('%g'))
# "length" is the length of the tick mark, it also changes the text offset
# "labelsize" is the fontsize of the tick label
ax.tick_params(axis='x', which='minor', length=5, labelsize=8)
ax.tick_params(axis='x', which='major', length=10, labelsize=12)
plt.tight_layout()
plt.show()