如何使用 matplotlib.pyplot.hist绘制直方图?
matplotlib.pyplot.hist
我有一个对应于条形高度的 y 值列表和一个 x 值字符串列表。
相关阅读: matplotlib.pyplot.bar。
matplotlib.pyplot.bar
如果你想要一个直方图,你不需要在 x 值上附加任何“名字”,因为:
x
y
density=True
import matplotlib.pyplot as plt import numpy as np %matplotlib inline np.random.seed(42) x = np.random.normal(size=1000) plt.hist(x, density=True, bins=30) # density=False would make counts plt.ylabel('Probability') plt.xlabel('Data');
注意,bins=30的数量是任意选择的,在选择“正确的”容器宽度时,有一个更科学的 Freedman-Diaconis规则:
bins=30
,其中 IQR是 四分差,n是要绘制的数据点总数
IQR
n
因此,根据这条规则,我们可以计算出 bins的数目:
bins
q25, q75 = np.percentile(x, [25, 75]) bin_width = 2 * (q75 - q25) * len(x) ** (-1/3) bins = round((x.max() - x.min()) / bin_width) print("Freedman–Diaconis number of bins:", bins) plt.hist(x, bins=bins);
Freedman–Diaconis number of bins: 82
最后,你可以用 PDF线、标题和图例使你的直方图看起来更精致一些:
PDF
import scipy.stats as st plt.hist(x, density=True, bins=82, label="Data") mn, mx = plt.xlim() plt.xlim(mn, mx) kde_xs = np.linspace(mn, mx, 300) kde = st.gaussian_kde(x) plt.plot(kde_xs, kde.pdf(kde_xs), label="PDF") plt.legend(loc="upper left") plt.ylabel("Probability") plt.xlabel("Data") plt.title("Histogram");
如果你愿意探索其他的机会,seaborn有一条捷径:
seaborn
# !pip install seaborn import seaborn as sns sns.displot(x, bins=82, kde=True);
现在回到指挥所。
如果您的数据点数量有限,条形图将更有意义地表示您的数据。然后你可以在 x 轴上贴上标签:
x = np.arange(3) plt.bar(x, height=[1,2,3]) plt.xticks(x, ['a','b','c']);
这是一个非常迂回的方法,但是如果你想制作一个你已经知道 bin 值但是没有源数据的直方图,你可以使用 np.random.randint函数在每个 bin 的范围内为 hist 函数生成正确的数值,例如:
np.random.randint
import numpy as np import matplotlib.pyplot as plt data = [np.random.randint(0, 9, *desired y value*), np.random.randint(10, 19, *desired y value*), etc..] plt.hist(data, histtype='stepfilled', bins=[0, 10, etc..])
至于标签,你可以把 x 的标签和垃圾桶对齐,得到这样的东西:
#The following will align labels to the center of each bar with bin intervals of 10 plt.xticks([5, 15, etc.. ], ['Label 1', 'Label 2', etc.. ])
如果您还没有安装 matplotlib,请尝试下面的命令。
> pip install matplotlib
import matplotlib.pyplot as plot
plot.hist(weightList,density=1, bins=20) plot.axis([50, 110, 0, 0.06]) #axis([xmin,xmax,ymin,ymax]) plot.xlabel('Weight') plot.ylabel('Probability')
plot.show()
虽然这个问题似乎要求使用 matplotlib.hist()函数绘制直方图,但是可以说,使用后半部分的问题要求使用给定的概率作为条形图的 y 值,使用给定的名称(字符串)作为 x 值,这是不可能完成的。
matplotlib.hist()
我假设一个名字的样本列表对应给定的概率绘制的图。对于给定的问题,这里使用一个简单的条形图。可使用以下代码:
import matplotlib.pyplot as plt probability = [0.3602150537634409, 0.42028985507246375, 0.373117033603708, 0.36813186813186816, 0.32517482517482516, 0.4175257731958763, 0.41025641025641024, 0.39408866995073893, 0.4143222506393862, 0.34, 0.391025641025641, 0.3130841121495327, 0.35398230088495575] names = ['name1', 'name2', 'name3', 'name4', 'name5', 'name6', 'name7', 'name8', 'name9', 'name10', 'name11', 'name12', 'name13'] #sample names plt.bar(names, probability) plt.xticks(names) plt.yticks(probability) #This may be included or excluded as per need plt.xlabel('Names') plt.ylabel('Probability')
这是一个古老的问题,但以前的答案都没有涉及到真正的问题,也就是说,问题在于问题本身。
首先,如果概率已经计算出来了,即直方图聚合数据以规范化的方式可用,那么概率加起来应该是1。他们显然没有,这意味着这里有问题,无论是术语或数据或问题的方式。
其次,标签被提供的事实(而不是间隔)通常意味着概率是分类响应变量——使用条形图绘制直方图是最好的(或者一些黑客的 pyplot 的 hist 方法) ,Shayan Shafiq 的答案提供了代码。
然而,参见问题1,这些概率是不正确的,在这种情况下使用柱状图作为“直方图”将是错误的,因为它没有告诉单变量分布的故事,出于某种原因(也许类是重叠的,观察值被计算多次在这种情况下,这样的图不应该称为直方图。
根据定义,直方图是单变量分布的图形表示(参见 直方图 | NIST/SEMATECH 电子统计方法手册和 直方图 | 维基百科) ,通过绘制代表感兴趣变量的选定类别中的观察计数或观察频率的大小条形来创建。如果变量是在一个连续的尺度上度量的,那么这些类就是箱(间隔)。直方图创建过程的重要部分是选择如何对分类变量的响应类别进行分组(或不进行分组) ,或者如何将连续类型变量的可能值域分割为区间(在哪里放置 bin 边界)。所有的观察都应该被表示出来,而且每个观察只能在情节中表示一次。这意味着条形尺寸的总和应该等于观察的总数(或者在宽度可变的情况下它们的面积,这是一种不太常见的方法)。或者,如果直方图是标准化的,那么所有的概率必须加起来为1。
如果数据本身是一个“概率”列表作为一个响应,即观察值是每个研究对象的概率值,那么最好的答案是简单的 plt.hist(probability)可能装箱选项,使用 x 标签已经是可疑的。
plt.hist(probability)
条形图不应该用作直方图,而应该用作简单的直方图
import matplotlib.pyplot as plt probability = [0.3602150537634409, 0.42028985507246375, 0.373117033603708, 0.36813186813186816, 0.32517482517482516, 0.4175257731958763, 0.41025641025641024, 0.39408866995073893, 0.4143222506393862, 0.34, 0.391025641025641, 0.3130841121495327, 0.35398230088495575] plt.hist(probability) plt.show()
结果
在这种情况下,matplotlib 默认带有以下直方图值
(array([1., 1., 1., 1., 1., 2., 0., 2., 0., 4.]), array([0.31308411, 0.32380469, 0.33452526, 0.34524584, 0.35596641, 0.36668698, 0.37740756, 0.38812813, 0.39884871, 0.40956928, 0.42028986]), <a list of 10 Patch objects>)
结果是一个数组元组,第一个数组包含观测计数,即什么将显示对图的 y 轴(他们加起来为13,观测总数)和第二个数组是 x 轴的区间边界。
我们可以检查它们的间距是否相等,
x = plt.hist(probability)[1] for left, right in zip(x[:-1], x[1:]): print(left, right, right-left)
或者,例如对于3个箱子(我的判断需要13个观察值) ,一个可以得到这个直方图
plt.hist(probability, bins=3)
“监狱后面”的情节数据
这个问题的作者需要澄清“概率”值列表的含义——“概率”只是响应变量的名称(那么为什么有 x 标签准备直方图,它是没有意义的) ,或者列表值是从数据计算出来的概率(然后事实上他们没有加起来1是没有意义的)。