如何使用Python中的Matplotlib和数据列表绘制直方图?
我正在尝试使用如何使用Python中的Matplotlib和数据列表绘制直方图?,python,matplotlib,visualization,data-visualization,Python,Matplotlib,Visualization,Data Visualization,我正在尝试使用matplotlib.hist()函数绘制直方图,但我不确定如何绘制 我有一张单子 probability = [0.3602150537634409, 0.42028985507246375, 0.373117033603708, 0.36813186813186816, 0.32517482517482516, 0.4175257731958763, 0.41025641025641024, 0.39408866995073893, 0.41432225063
matplotlib.hist()函数绘制直方图,但我不确定如何绘制
我有一张单子
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]
和名称(字符串)列表
如何将概率作为每个条的y值,并将名称作为x值 如果需要柱状图,则无需将任何“名称”附加到x值,因为在x轴上会有数据箱:
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');
注意,料仓数量=30
是任意选择的,选择“正确”的料仓宽度有更科学的规则:
,其中,IQR
是,而n
是要绘制的数据点总数
因此,根据这条规则,可以将箱的数量计算为:
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);
最后,您可以使用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");
但是,如果数据点的数量有限,如在OP中,条形图表示数据更为合理。然后,可以将标签附着到x轴:
x = np.arange(3)
plt.bar(x, height=[1,2,3])
plt.xticks(x, ['a','b','c'])
这是一种非常全面的方法,但是如果您想制作一个直方图,其中您已经知道bin值,但没有源数据,您可以使用np.random.randint
函数在每个bin的范围内为hist函数生成正确数量的值,例如:
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
库导入
直方图数据:
显示直方图
输出如下所示:
尽管问题似乎要求使用matplotlib.hist()
函数绘制柱状图,但可以说,如果使用问题的后半部分要求使用给定概率作为条形图的y值,使用给定名称(字符串)作为x值,则无法使用相同的方法绘制柱状图
我假设一个与给定概率对应的名字样本列表来绘制图。对于给定的问题,一个简单的条形图在这里起作用。可以使用以下代码:
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,这些概率是不正确的,在这种情况下,使用条形图作为“直方图”是错误的,因为出于某种原因(可能是类重叠,观察值被多次计数?)它没有说明单变量分布的情况,这种图在这种情况下不应称为直方图
根据定义,直方图是一种单变量分布的图形表示(见&),通过绘制表示感兴趣变量选定类别中观察计数或频率的大小条来创建。如果变量是在连续刻度上测量的,则这些类别为箱(间隔)。直方图创建过程的重要部分是选择如何对分类变量的响应类别进行分组(或保持不分组),或如何将可能值的域划分为连续类型变量的间隔(放置bin边界的位置)。所有观察结果都应表示出来,并且每个观察结果在绘图中只显示一次。这意味着棒尺寸的总和应等于观察的总计数(或宽度可变时的面积,这是一种不太常见的方法)。或者,如果直方图被归一化,那么所有概率的总和必须为1
如果数据本身是作为响应的“概率”列表,即观察值是每个研究对象(某物)的概率值,那么最好的答案就是plt.hist(probability)
,可能带有binning选项,并且使用已经可用的x标签是可疑的
然后,条形图不应用作直方图,而应简单地使用
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>)
或者,例如,对于3个箱子(我的判断需要13个观察值),一个会得到这个直方图
plt.hist(probability, bins=3)
将打印数据“隐藏”在
问题的作者需要澄清“概率”值列表的含义——“概率”只是响应变量的名称吗(那么为什么直方图中有x标签,这毫无意义),或者列表值是根据数据计算的概率(那么,它们加起来不等于1的事实毫无意义).记住,python中的行尾没有分号!@toad2222这是Ipython notebook cell的摘录。试着不使用分号执行它,看看区别。我发布的所有代码片段在我的计算机上运行得非常好。如果你想知道Sergey使用的分号,请参阅和了解分号在Jupyte中的用法r笔记本电脑(以前称为IPython笔记本电脑)在打印时使用单元格来抑制打印对象的文本。如果出现溢出错误:无法将浮点无穷大转换为整数,只需将plot.axis([50,110,0,0.06])更改为.25到25和.75到75即可对于这个例子来说,线条是无用的。此外,由于它对要显示的绘图区域进行了硬编码,如果您的数据不完全在其中,您将
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')
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()
(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>)
x = plt.hist(probability)[1]
for left, right in zip(x[:-1], x[1:]):
print(left, right, right-left)
plt.hist(probability, bins=3)