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

直方图分为频数直方图和频率直方图,为理解什么是直方图,大家可先熟悉如下专有名词。
频数分布直方图:在统计数据时,按照频数分布表,在平面直角坐标系中,横轴标出每个组的端点,纵轴表示频数,每个矩形的高代表对应的频数。
频率分布直方图:在统计数据时,按照频数分布表,在平面直角坐标系中,横轴标出每个组的端点,纵轴表示频率除以组距的值,每个矩形的高代表频率和组距的商。
频数:落在各组样本数据的个数。
频率:频数除以样本总个数。
组距:直方图中柱子的宽度,可自定义,也可用数据的最大值减去最小值再除以柱子的个数。

在python中用matplotlib.pyplot.hist函数绘制直方图,本小节详细阐述该函数的常用参数。
你可以大致浏览一遍,再结合第三个模块的案例彻底弄懂这些参数。
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)

本小节用一些模拟的公司薪资数据,建立直方图,方便大家理解上一章中常用参数。
1 bins参数理解
首先来看下只有薪资数据(x)和直方图分割区间(bins)两个参数的绘图代码。
import numpy as npimport pandas as pdfrom scipy import statsfrom matplotlib.pyplot import *import matplotlib.pyplot as pltplt.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,具体如下:
#rwidth参数理解import numpy as npimport pandas as pdfrom scipy import statsfrom matplotlib.pyplot import *import matplotlib.pyplot as pltplt.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,具体如下:
#density的值Trueimport numpy as npimport pandas as pdfrom scipy import statsfrom matplotlib.pyplot import *import matplotlib.pyplot as pltplt.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,具体如下:
#cumulative的值Trueimport numpy as npimport pandas as pdfrom scipy import statsfrom matplotlib.pyplot import *import matplotlib.pyplot as pltplt.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,具体如下:
#orientation值为horizontalimport numpy as npimport pandas as pdfrom scipy import statsfrom matplotlib.pyplot import *import matplotlib.pyplot as pltplt.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,具体如下:
#cumulative的值Trueimport numpy as npimport pandas as pdfrom scipy import statsfrom matplotlib.pyplot import *import matplotlib.pyplot as pltplt.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()
得到结果:

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


扫一扫关注我
13162366985
投稿微信号、手机号




