首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Python绘制hist直方图使用手册

Python绘制hist直方图使用手册

作者头像
阿黎逸阳
发布2021-12-07 14:25:15
发布2021-12-07 14:25:15
4.4K00
代码可运行
举报
运行总次数:0
代码可运行

对于初学python绘图的小伙伴来说,彻底弄清hist直方图绘制需要花费较多时间。

本文旨在让你花最少的时间,彻底弄懂hist函数原理和绘制方法。

本文目录

  1. 什么是直方图?
  2. matplotlib.pyplot.hist参数详解
  3. 实例理解

一、什么是直方图?

直方图分为频数直方图和频率直方图,为理解什么是直方图,大家可先熟悉如下专有名词。

频数分布直方图:在统计数据时,按照频数分布表,在平面直角坐标系中,横轴标出每个组的端点,纵轴表示频数,每个矩形的高代表对应的频数。

频率分布直方图:在统计数据时,按照频数分布表,在平面直角坐标系中,横轴标出每个组的端点,纵轴表示频率除以组距的值,每个矩形的高代表频率和组距的商。

频数:落在各组样本数据的个数。

频率:频数除以样本总个数。

组距:直方图中柱子的宽度,可自定义,也可用数据的最大值减去最小值再除以柱子的个数。

二、matplotlib.pyplot.hist参数详解

在python中用matplotlib.pyplot.hist函数绘制直方图,本小节详细阐述该函数的常用参数。

你可以大致浏览一遍,再结合第三个模块的案例彻底弄懂这些参数。

代码语言:javascript
代码运行次数:0
运行
复制
hist(x, bins=None, range=None, density=False, weights=None, cumulative=False, bottom=None, histtype='bar', align='mid', orientation='vertical', rwidth=None, log=False, color=None, label=None, stacked=False, *, data=None, **kwargs)

x:数组序列,待绘制直方图的原始数据。

bins:整数值或数组序列,默认为None。若为整数值,则为频数分布直方图柱子个数,且柱宽=(x.max()-x.min())/bins。

若为数值序列,则该序列给出每个柱子的范围值,除最后一个柱子外,其他柱子的取值范围均为左闭右开,若数值序列的最大值小于原始数据的最大值,存在数据丢失。

range:元组或None,默认为None。若为元组,则range用于剔除原始数据中较小和较大的离群值,给出绘制直方图的全局范围。若为None,则不剔除。

若bins取值为数组序列,则range无效。

density:布尔值,默认为False。若为True,则绘制频率分布直方图,若为False,则绘制频数分布直方图。

weights:与x形状相同的权重数组。将x中的每个元素乘以对应权重值再计数。如果normed或density取值为True,则会对权重进行归一化处理。这个参数可用于绘制已合并数据的直方图。

cumulative:布尔值,默认为False。若为True,当density为False时直方图显示累计频数,当density为True时直方图显示累计频率。

bottom:数值或数组序列,默认为None。若为数值,则直方图的柱子相对于y=0向上/向下偏移相同的量。若为数组序列,则根据数组元素取值每根柱子偏移相应的量。

histtype:{'bar', 'barstacked', 'step', 'stepfilled'},默认为'bar'。

'bar'是传统的条形直方图,'barstacked'是堆叠的条形直方图,'step'是未填充的阶梯直方图,只有外边框,'stepfilled'是有填充的阶梯直方图。

当histtype取值为'step'或'stepfilled'时,rwidth设置失效,即柱子中无间隔,默认连接在一起。

align:{'left', 'mid', 'right'},默认为'mid'。

'left'表示柱子的中心位于bins的左边缘, 'mid'表示柱子的中心位于bins的中间,'right'表示柱子的中心位于bins的右边缘。

orientation:{'horizontal', 'vertical'},默认为'vertical'。'horizontal'表示柱子水平排列, 'vertical'表示柱子垂直排列。

rwidth:数值,默认为None。表示柱子的宽度占bins对应宽的比例,比如取值为0.9时,柱子的宽度为bins对应宽乘以0.9,柱子之间有空隙。

log:布尔值,默认为False。若为True,则纵坐标用科学计数法表示。

color:字符串(具体颜色)或数组(元素为颜色),默认为None。

label:字符串,默认为None。有多个数据集时,用label做标注区分。

stacked:布尔值,默认为False。当图中有多个数据集时使用该参数,若取值为True,则输出数据集累计堆叠的结果,若取值为False,则多个数据集柱子并排排列。

三、实例理解

本小节用一些模拟的公司薪资数据,建立直方图,方便大家理解上一章中常用参数。

1 bins参数理解

首先来看下只有薪资数据(x)和直方图分割区间(bins)两个参数的绘图代码。

代码语言:javascript
代码运行次数:0
运行
复制
import numpy as np
import pandas as pd
from scipy import stats
from matplotlib.pyplot import *
import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = ['SimHei']  # 解决标题中文显示问题
plt.rcParams['axes.unicode_minus'] = False   # 解决标题中文显示问题

salary = [2500, 3100, 3300, 3500, 4000, 5400, 5600, 6700,  7600, 7800, 8700, 9800, 10400]
#公司员工薪资数据
fig = plt.figure()
ax = fig.add_subplot(111)
#创建图形框架
numBins = [0,4000,6000,10000]
#直方图的分割区间
ax.hist(salary, numBins)
plt.title(u'公司员工薪水直方图')
#绘制标题
plt.xlabel(u'薪资区间')
#横坐标标题
plt.ylabel(u'人数')
#纵坐标标题
plt.show()

从salary中知,总计有13个薪水数据,但是numBins的最大值为10000,所以salary中的10400取不到,绘图时只使用了前12个数值,这在绘图时需特别注意。

由于bins的取值是左闭右开,统计salary中[0, 4000)的个数为4,[4000, 6000)的个数为3,[6000, 10000)的个数为5。

得到结果:

2 rwidth参数理解

rwidth:柱子的宽度占bins对应宽的比例,比如取值为0.9时,柱子的宽度为bins对应宽乘以0.9,柱子之间有空隙。

只在第一小节代码的基础上调整rwidth的值为0.9,具体如下:

代码语言:javascript
代码运行次数:0
运行
复制
#rwidth参数理解
import numpy as np
import pandas as pd
from scipy import stats
from matplotlib.pyplot import *
import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = ['SimHei']  # 解决标题中文显示问题
plt.rcParams['axes.unicode_minus'] = False   # 解决标题中文显示问题

salary = [2500, 3100, 3300, 3500, 4000, 5400, 5600, 6700,  7600, 7800, 8700, 9800, 10400]
#公司员工薪资数据
fig = plt.figure()
ax = fig.add_subplot(111)
#创建图形
numBins = [0,4000,6000,10000]
#直方图的分割区间
ax.hist(salary, numBins, rwidth=0.9)
plt.title(u'公司员工薪水直方图')
#绘制标题
plt.xlabel(u'薪资区间')
#横坐标标题
plt.ylabel(u'人数')
#纵坐标标题
plt.show()

得到结果:

可以发现每个柱子由原来的满格画,变成了现在的留一点空隙,比如0到4000这个区间,前后都留了一点空隙。

3 density参数理解

density:布尔值,默认为False。若为True,则绘制频率分布直方图,若为False,则绘制频数分布直方图。

只在第二小节代码的基础上调整density的值True,具体如下:

代码语言:javascript
代码运行次数:0
运行
复制
#density的值True
import numpy as np
import pandas as pd
from scipy import stats
from matplotlib.pyplot import *
import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = ['SimHei']  # 解决标题中文显示问题
plt.rcParams['axes.unicode_minus'] = False   # 解决标题中文显示问题

salary = [2500, 3100, 3300, 3500, 4000, 5400, 5600, 6700,  7600, 7800, 8700, 9800, 10400]
#公司员工薪资数据
fig = plt.figure()
ax = fig.add_subplot(111)
#创建图形
numBins = [0,4000,6000,10000]
#直方图的分割区间
ax.hist(salary, numBins, rwidth=0.9, density=True)
plt.title(u'公司员工薪水直方图')
#绘制标题
plt.xlabel(u'薪资区间')
#横坐标标题
plt.ylabel(u'人数')
#纵坐标标题
plt.show()

得到结果:

可以发现纵坐标由原来的频数变成了频率。

4 cumulative参数理解

cumulative:布尔值,默认为False。若为True,当density为False时直方图显示累计频数,当density为True时直方图显示累计频率。

只在第二小节代码的基础上调整cumulative的值为True,具体如下:

代码语言:javascript
代码运行次数:0
运行
复制
#cumulative的值True
import numpy as np
import pandas as pd
from scipy import stats
from matplotlib.pyplot import *
import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = ['SimHei']  # 解决标题中文显示问题
plt.rcParams['axes.unicode_minus'] = False   # 解决标题中文显示问题

salary = [2500, 3100, 3300, 3500, 4000, 5400, 5600, 6700,  7600, 7800, 8700, 9800, 10400]
#公司员工薪资数据
fig = plt.figure()
ax = fig.add_subplot(111)
#创建图形
numBins = [0,4000,6000,10000]
#直方图的分割区间
ax.hist(salary, numBins, rwidth=0.9, cumulative=True)
plt.title(u'公司员工薪水直方图')
#绘制标题
plt.xlabel(u'薪资区间')
#横坐标标题
plt.ylabel(u'人数')
#纵坐标标题
plt.show()

得到结果:

可以发现直方图绘制的是每个区间对应累计的薪资人数。

5 orientation参数理解

orientation:{'horizontal', 'vertical'},默认为'vertical'。'horizontal'表示柱子水平排列, 'vertical'表示柱子垂直排列。

只在上小节代码的基础上调整orientation的值为horizontal,具体如下:

代码语言:javascript
代码运行次数:0
运行
复制
#orientation值为horizontal
import numpy as np
import pandas as pd
from scipy import stats
from matplotlib.pyplot import *
import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = ['SimHei']  # 解决标题中文显示问题
plt.rcParams['axes.unicode_minus'] = False   # 解决标题中文显示问题

salary = [2500, 3100, 3300, 3500, 4000, 5400, 5600, 6700,  7600, 7800, 8700, 9800, 10400]
#公司员工薪资数据
fig = plt.figure()
ax = fig.add_subplot(111)
#创建图形
numBins = [0,4000,6000,10000]
#直方图的分割区间
ax.hist(salary, numBins, rwidth=0.9, cumulative=True, orientation='horizontal')
plt.title(u'公司员工薪水直方图')
#绘制标题
plt.xlabel(u'薪资区间')
#横坐标标题
plt.ylabel(u'人数')
#纵坐标标题
plt.show()

得到结果:

可以发现直方图柱子呈水平排列。

6 color参数理解

color:字符串(具体颜色)或数组(元素为颜色),默认为None。

只在第四小节代码的基础上调整color值为yellow,具体如下:

代码语言:javascript
代码运行次数:0
运行
复制
#cumulative的值True
import numpy as np
import pandas as pd
from scipy import stats
from matplotlib.pyplot import *
import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = ['SimHei']  # 解决标题中文显示问题
plt.rcParams['axes.unicode_minus'] = False   # 解决标题中文显示问题

salary = [2500, 3100, 3300, 3500, 4000, 5400, 5600, 6700,  7600, 7800, 8700, 9800, 10400]
#公司员工薪资数据
fig = plt.figure()
ax = fig.add_subplot(111)
#创建图形
numBins = [0,4000,6000,10000]
#直方图的分割区间
ax.hist(salary, numBins, rwidth=0.9, color='yellow')
plt.title(u'公司员工薪水直方图')
#绘制标题
plt.xlabel(u'薪资区间')
#横坐标标题
plt.ylabel(u'人数')
#纵坐标标题
plt.show()

得到结果:

可以发现直方图柱子由原来的蓝色变成了现在的黄色。

以上为直方图中常用参数的理解,如果小伙伴对于直方图中其它参数也想了解,可根据第二章的说明自行调试代码进行理解。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-12-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 阿黎逸阳的代码 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档