如何使用Python中的Matplotlib和数据列表绘制直方图?

Dat*_*uys 73 python visualization data-visualization matplotlib

我试图使用该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]
Run Code Online (Sandbox Code Playgroud)

和名单(字符串)列表.

如何将概率作为每个条形的y值和名称作为x值?

Ser*_*nov 118

如果你想要一个直方图,你不需要将任何"名称"附加到x值,就像在x轴上你会有二进制数:

import matplotlib.pyplot as plt
import numpy as np
%matplotlib inline
x = np.random.normal(size = 1000)
plt.hist(x, normed=True, bins=30)
plt.ylabel('Probability');
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

但是,如果数据点数量有限,并且需要条形图,则可以将标签附加到x轴:

x = np.arange(3)
plt.bar(x, height= [1,2,3])
plt.xticks(x+.5, ['a','b','c'])
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

如果这可以解决您的问题,请告诉我.

编辑2018年11月26日

根据下面的评论,从Matplotlib 3.0.2开始,以下代码就足够了:

x = np.arange(3)
plt.bar(x, height= [1,2,3]) 
plt.xticks(x, ['a','b','c']) # no need to add .5 anymore
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

  • @ Toad22222这是Ipython笔记本电脑的摘录.尝试不使用分号执行它,看看差异.我在SO上发布的所有代码片段都在我的电脑上完美运行. (8认同)
  • 如果你使用了他的对象,即`概率',你会更好地解决OP的问题. (7认同)
  • 如果您收到 **OverflowError:无法将浮点无穷大转换为整数**,只需将 .25 更改为 25,将 .75 更改为 75 (3认同)
  • 记住,在python行的末尾没有分号! (2认同)
  • 如果您想知道Sergey使用的分号,请参阅[here](/sf/ask/1805304371/)和[ #16此处](https://www.dataquest.io/blog/jupyter-notebook-tips-tricks-shortcuts/)了解如何在Jupyter笔记本(以前是IPython笔记本)单元格中使用分号来抑制文本关于绘图对象。 (2认同)

小智 14

如果你还没有安装matplotlib,那就试试吧.

> pip install matplotlib
Run Code Online (Sandbox Code Playgroud)

图书馆进口

import matplotlib.pyplot as plot
Run Code Online (Sandbox Code Playgroud)

直方图数据:

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')
Run Code Online (Sandbox Code Playgroud)

显示直方图

plot.show()
Run Code Online (Sandbox Code Playgroud)

输出如下:

在此输入图像描述

  • 该plot.axis([50, 110, 0, 0.06])'行对于该示例来说是无用的。此外,由于它对要显示的绘图区域进行了硬编码,如果您的数据不完全适合其中,您可能会感到困惑为什么它无法正确显示。 (4认同)

Sha*_*fiq 10

尽管该问题似乎要求使用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')
Run Code Online (Sandbox Code Playgroud)


小智 5

这是一种非常迂回的方法,但如果您想制作一个直方图,其中您已经知道 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..])
Run Code Online (Sandbox Code Playgroud)

至于标签,您可以将 x 刻度线与 bin 对齐以获得如下所示的内容:

#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.. ])
Run Code Online (Sandbox Code Playgroud)


pre*_*mod 5

这是一个老问题,但之前的答案都没有解决真正的问题,即问题出在问题本身这一事实。

首先,如果已经计算了概率,即直方图聚合数据以归一化的方式可用,那么概率加起来应该是 1。他们显然没有,这意味着这里有问题,无论是术语还是数据或以提问的方式。

其次,提供标签(而不是间隔)的事实通常意味着概率是分类响应变量 - 并且最好使用条形图绘制直方图(或对 pyplot 的 hist 方法进行一些黑客攻击), Shayan Shafiq 的回答提供了代码。

但是,请参阅问题 1,这些概率是不正确的,在这种情况下使用条形图作为“直方图”是错误的,因为它没有讲述单变量分布的故事,出于某种原因(也许类是重叠的,并且观察值被多次计算)次?),在这种情况下,不应将此类图称为直方图。

根据定义,直方图是单变量变量分布的图形表示(参见直方图 | NIST/SEMATECH 统计方法直方图电子手册| 维基百科) 并通过绘制表示感兴趣变量的选定类别中观察的计数或频率的大小的条来创建。如果变量是在连续尺度上测量的,那么这些类就是箱(区间)。直方图创建过程的重要部分是选择如何对分类变量的响应类别进行分组(或保持不分组),或者如何将可能值的域拆分为区间(放置 bin 边界的位置)以获得连续类型变量。应表示所有观察值,并且每个观察值在图中仅表示一次。这意味着条形尺寸的总和应等于观察的总数(或在可变宽度的情况下它们的面积,这是一种不太常见的方法)。或者,如果直方图被归一化,那么所有概率之和必须为 1。

如果数据本身是作为响应的“概率”列表,即观察值是每个研究对象的(某事物的)概率值,那么最好的答案就是plt.hist(probability)可能带有分箱选项,并且使用已经可用的 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()
Run Code Online (Sandbox Code Playgroud)

结果

在此处输入图片说明

在这种情况下,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>)
Run Code Online (Sandbox Code Playgroud)

结果是一个数组元组,第一个数组包含观察计数,即将针对绘图的 y 轴显示的内容(它们加起来为 13,观察总数),第二个数组是 x 的区间边界-轴。

人们可以检查它们是否等距,

x = plt.hist(probability)[1]
for left, right in zip(x[:-1], x[1:]):
  print(left, right, right-left)
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

或者,例如对于 3 个 bin(我的判断需要 13 个观察值),一个人会得到这个直方图

plt.hist(probability, bins=3)
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

情节数据“在酒吧后面”是

在此处输入图片说明

问题的作者需要澄清“概率”值列表的含义是什么-“概率”只是响应变量的名称(那么为什么要为直方图准备 x 标签,这是没有意义的) ),或者是根据数据计算出的概率的列表值(那么它们加起来不等于 1 的事实是没有意义的)。