绘制频率分布直方图的三种方法,总结的很用心!

  • 2020 年 2 月 21 日
  • 筆記

直方图能帮助迅速了解数据的分布形态,将观测数据分组,并以柱状条表示各分组中观测数据的个数。简单而有效的可视化方法,可检测数据是否有问题,也可看出数据是否遵从某种已知分布。

本次案例通过生成深圳市疫情个案数据集中所有患者的年龄参数直方图。

分别使用Matplotlib、Pandas、Seaborn模块可视化Histogram。

其中,Matplotlib和Pandas样式简单,看上去吸引力不大。Seaborn可往单变量直方图上添加很多东西,更美观,pandas可成组生成直方图。

导入库/数据

import pandas as pd  import seaborn as sns  import matplotlib.pyplot as plt  import datetime  import time  df=pd.read_excel(r"szdata.xls")  df.head(5)  

Matplotlib模块

##注意原始数据集不能存在缺失值,绘制前必须对缺失数据删除或替换,否则无法绘制成功.  ##检查年龄是否有缺失  any(df.年龄.isnull()) #False  ##删除含有缺失年龄的数据  df.dropna(subset=["年龄"],inplace=True)  ##绘制直方图  plt.rcParams["font.sans-serif"]='SimHei'  plt.rcParams['axes.unicode_minus']=False  %config InlineBackend.figure_format='svg'    plt.hist(x=df.年龄,bins=20,          color="steelblue",          edgecolor="black")    #添加x轴和y轴标签  plt.xlabel("年龄")  plt.ylabel("病例数")    #添加标题  plt.title("患者年龄分布")    #显示图形  plt.show()  

Pandas模块

#注意直方图上添加核密度图,必须将直方图频数更改为频率,即normed参数设置成True  #直方图  df.年龄.plot(kind="hist",bins=20,color="steelblue",edgecolor="black",normed=True,label="直方图")    #加核密度图  df.年龄.plot(kind="kde",color="red",label="核密度图")    #添加x轴和y轴标签  plt.xlabel("年龄")  plt.ylabel("核密度值")    #添加标题  plt.title("患者年龄分布")    #显示图例  plt.legend()    #显示图形  plt.show()  
# pandas.cut() 也同样是一个方便的方法,用来将数据进行强制的分箱  # 将一系列数值分成若干份  #cut()方法,参数bin指明切分区间,左开右闭区间。  import numpy as np  from pandas import Series,DataFrame  ages=list(df.年龄)  bins=[0,29,39,49,50,np.inf]  #范围  labels=["少年","青年组","中青年组","中年组","中老年组"]  groups=pd.cut(ages,bins=bins,labels=labels)  data=groups.value_counts()  #qcut()方法,不需要事先指明切分区间,只需要指明切分个数。  # pd.qcut(ages,6).value_counts()  df1=DataFrame(data,columns=["病例数"])    plt.subplot(1,1,1)  x=labels  y=df1["病例数"].values  plt.bar(x,y,width=0.5,align="center")  plt.title("深圳市患者按年龄分组",loc="center")  for a,b in zip(x,y):       plt.text(a,b,b,ha="center",va="bottom",fontsize=12)#添加数据标签  plt.ylim(0,140)  plt.xlabel('分组',labelpad=10)  plt.ylabel('病例数')  plt.savefig(r"bar.jpg")    # 条形图  # 将柱形图x轴和y轴调换,barh方法  # plt.barh(y,width,height,align,color,edgecolor)  

pandas也提供了一个方便的.value_counts() 方法,用来计算一个非空值的直方图,并将之转变成一个pandas的series结构:df.年龄.value_counts()

Seaborn模块

# 上面表达了所有患者的年龄分布,如果按性别分组,  # 研究不同性别下年龄分布的差异,该如何实现叻?针对这个问题,推荐使用Seaborn模块中的distplot函数  #取出男性年龄  Age_Male=df.年龄[df.性别=="男性"]  #取出女性年龄  Age_Female=df.年龄[df.性别=="女性"]    #绘制男女患者年龄的直方图  sns.distplot(Age_Male,bins=20,kde=False,hist_kws={"color":"steelblue"},label="男性")    #绘制男女患者年龄的直方图  sns.distplot(Age_Female,bins=20,kde=False,hist_kws={"color":"purple"},label="女性")  #添加标题  plt.title("不同性别患者年龄分布直方图")    #显示图例  plt.legend()    #显示图形  plt.show()  
#绘制核密度函图  #绘制男女患者年龄的直方图  sns.distplot(Age_Male,hist=False,kde_kws={"color":"red","linestyle":"-"},norm_hist=True,label="男性")    #绘制男女患者年龄的直方图  sns.distplot(Age_Female,hist=False,kde_kws={"color":"blue","linestyle":"--"},norm_hist=True,label="女性")  #添加标题  plt.title("不同性别患者年龄核密度图")    #显示图例  plt.legend()    #显示图形  plt.show()  

Python实现histogram方法

#生成直方图  # count_elements() 返回了一个字典,字典里的键值对:所有数值出现的频率次数。  # hist[i] = hist.get(i, 0) + 1 实现了每个数值次数的累积  a = tuple(df.年龄)  def count_elements(seq) -> dict:      hist = {}      for i in seq:          hist[i] = hist.get(i, 0) + 1      return hist  counted = count_elements(a)  counted  #或通过collection.Counter类库实现  # from collections import Counter  # counted = Counter(a)  # counted    #利用输出格式format来实现直方图的展示  def histogram(seq) -> None:      counted = count_elements(seq)      for k in sorted(counted):          print('{0:5d} {1}'.format(k, '@' * counted[k]))  histogram(a)  

附函数语法及参数含义

Matplotlib模块中hist函数

Plt.hist(x,bins=10,range=None,normed=False,weights=None,cumulative=False,bottom=None,histtype=’bar’,align=’mid’,orientation=’vertical’,rwidth=None,log=False,color=None,edgecolor=None,label=None,stacked=False) 1)、x:指定要绘制直方图的数据。 2)、bins:指定直方图条形的个数。 3)、range:指定直方图数据的上下界,默认包含绘图数据的最大值和最小值。 4)、normed:是否将直方图的频数转换成频率。 5)、weights:该参数可为每一个数据节点设置权重。 6)、cumulative:是否需要计算累积频数或频率。 7)、bottom:可以为直方图的每个条形添加基准线,默认为0. 8)、histtype:指定直方图的类型,默认bar,其他八日stacked、step和stepfilled。 9)、align:设置条形边界的对齐方式,默认mid,另外left和right。 10)、orientation:设置直方图的摆放方向,默认vertical垂直方向。 11)、rwidth:设置直方图条形的宽度。 12)、log:是否需要对绘图数据进行log变换。 13)、color:设置直方图的填充色。 14)、edgecolor:设置直方图边框色。 15)、label:设置直方图的标签,可通过legend展示图例。 16)、stacked:当有多个数据时,是否需要将直方图呈堆叠摆放,默认水平摆放。

Seaborn模块

Sns.distplot(x,bins=None,hist=True,kde=True,rug=False,fit=None,hist_kws=None,kde_kws=None,rug_kws=None,fit_kws=None,color=None,vertical=False,norm_hist=False,axlabel=None,label=None,ax=None)

1)、x:指定绘图数据,可以是序列、一维数组或列表。 2)、bins:指定直方图条形的个数。 3)、hist:bool类型的参数,是否绘制直方图,默认True。 4)、kde:bool类型的参数,是否绘制核密度图,默认True。 5)、rug:bool类型的参数,是否绘制须图,(如果数据比较密集,该参数比较有用)默认False。 6)、fit:指定一个随机分布对象,需调用scipy模块中随机分布函数,用于绘制随机分布概率密度曲线。 7)、hist_kws:以字典形式传递直方图的其他修饰属性,如填充色、边框色、宽度等。 8)、kde_kws:以字典形式传递核密度图的其他修饰属性,如线的颜色、线的类型等。

9)、rug_kws:以字典形式传递须图的其他修饰属性,如线的颜色、线的宽度等。 10)、fit_kws:以字典形式传递须图的其他修饰属性,如线的颜色、线的宽度等。 11)、color:指定图颜色,除了随机分布曲线的颜色。 12)、vertical:是否将图形垂直显示,默认True。 13)、norm_hist:是否将频数更改为频率,默认False。 14)、axlabel:用于显示轴标签。 15)、label:指定图形图例,需要结合plt.legend()一起使用。 16)、ax:指定子图的位置。

Python新手成长之路案例集锦,长按关注: