辛先森科技说@手把手教你用Python画直方图:其实跟柱状图完全不同

导读:直方图和柱状图都是数据分析中非常常见、常用的图表 , 由于两者外观上看起来非常相似 , 也就难免造成一些混淆 。 此前我们曾在《柱状图、堆叠柱状图、瀑布图有什么区别?怎样用Python绘制?》一文中带大家了解了柱状图 , 今天我们再来讲讲直方图 。
相关链接:柱状图、堆叠柱状图、瀑布图……有什么区别?怎样用Python绘制?
作者:屈希峰 , 资深Python工程师 , 知乎多个专栏作者
来源:华章科技
辛先森科技说@手把手教你用Python画直方图:其实跟柱状图完全不同
文章图片
01概述
直方图(Histogram) , 形状类似柱状图却有着与柱状图完全不同的含义 。 直方图牵涉统计学概念 , 首先要对数据进行分组 , 然后统计每个分组内数据元的数量 。 在平面直角坐标系中 , 横轴标出每个组的端点 , 纵轴表示频数 , 每个矩形的高代表对应的频数 , 这样的统计图称为频数分布直方图 。
频数分布直方图需要经过频数乘以组距的计算过程才能得出每个分组的数量 , 同一个直方图的组距是一个固定不变的值 , 所以如果直接用纵轴表示数量 , 每个矩形的高代表对应的数据元数量 , 既能保持分布状态不变 , 又能直观地看出每个分组的数量 , 如图2-58所示 。
辛先森科技说@手把手教你用Python画直方图:其实跟柱状图完全不同
文章图片
▲图2-58直方图
通过直方图还可以观察和估计哪些数据比较集中 , 异常或者孤立的数据分布在何处 。
首先 , 了解如下几个基本概念 。
组数:在统计数据时 , 我们把数据按照不同的范围分成几个组 , 分成的组的个数称为组数 。 组距:每一组两个端点的差 。 频数:分组内数据元的数量除以组距 。02实例
直方图代码示例如下所示 。
代码示例2-451plot=figure(plot_width=300,plot_height=300)2plot.quad(top=[2,3,4],bottom=[1,2,3],left=[1,2,3],3right=[1.2,2.5,3.7],color=''#B3DE69'')4show(plot)运行结果如图2-59所示 。
辛先森科技说@手把手教你用Python画直方图:其实跟柱状图完全不同
文章图片
▲图2-59代码示例2-45运行结果
代码示例2-45第2行使用quad()方法通过定义矩形的四边边界绘制直方图 , 具体参数说明如下 。
p.quad(left,right,top,bottom,**kwargs)参数说明 。
left(:class:`~bokeh.core.properties.NumberSpec`):直方x轴左侧边界right(:class:`~bokeh.core.properties.NumberSpec`):直方x轴右侧边界top(:class:`~bokeh.core.properties.NumberSpec`):直方y轴顶部边界bottom(:class:`~bokeh.core.properties.NumberSpec`):直方y轴底部边界其他参数(**kwargs)说明 。
alpha(float):一次性设置所有线条的透明度color(Color):一次性设置所有线条的颜色source(ColumnDataSource):Bokeh特有数据格式(类似于PandasDataframe)legend(str):图元的图例x_range_name(str):x轴范围名称y_range_name(str):y轴范围名称level(Enum):图元渲染级别代码示例2-461importnumpyasnp2importscipy.special3frombokeh.layoutsimportgridplot4#绘图函数5defmake_plot(title,hist,edges,x,pdf,cdf):6p=figure(title=title,tools='',background_fill_color=''#fafafa'')7p.quad(top=hist,bottom=0,left=edges[:-1],right=edges[1:],8fill_color=''navy'',line_color=''white'',alpha=0.5)9p.line(x,pdf,line_color=''#ff8888'',line_width=4,alpha=0.7,legend=''PDF'')10p.line(x,cdf,line_color=''orange'',line_width=2,alpha=0.7,legend=''CDF'')1112p.y_range.start=013p.legend.location=''center_right''14p.legend.background_fill_color=''#fefefe''15p.xaxis.axis_label='x'16p.yaxis.axis_label='Pr(x)'17p.grid.grid_line_color=''white''18returnp19#正态分布20mu,sigma=0,0.521measured=np.random.normal(mu,sigma,1000)22hist,edges=np.histogram(measured,density=True,bins=50)23x=np.linspace(-2,2,1000)24#拟合曲线25pdf=1/(sigma*np.sqrt(2*np.pi))*np.exp(-(x-mu)**2/(2*sigma**2))26cdf=(1+scipy.special.erf((x-mu)/np.sqrt(2*sigma**2)))/227p1=make_plot(''NormalDistribution(μ=0,σ=0.5)'',hist,edges,x,pdf,cdf)28#对数正态分布29mu,sigma=0,0.530measured=np.random.lognormal(mu,sigma,1000)31hist,edges=np.histogram(measured,density=True,bins=50)32x=np.linspace(0.0001,8.0,1000)33pdf=1/(x*sigma*np.sqrt(2*np.pi))*np.exp(-(np.log(x)-mu)**2/(2*sigma**2))34cdf=(1+scipy.special.erf((np.log(x)-mu)/(np.sqrt(2)*sigma)))/235p2=make_plot(''LogNormalDistribution(μ=0,σ=0.5)'',hist,edges,x,pdf,cdf)36#伽玛分布37k,theta=7.5,1.038measured=np.random.gamma(k,theta,1000)39hist,edges=np.histogram(measured,density=True,bins=50)40x=np.linspace(0.0001,20.0,1000)41pdf=x**(k-1)*np.exp(-x/theta)/(theta**k*scipy.special.gamma(k))42cdf=scipy.special.gammainc(k,x/theta)43p3=make_plot(''GammaDistribution(k=7.5,θ=1)'',hist,edges,x,pdf,cdf)44#韦伯分布45lam,k=1,1.2546measured=lam*(-np.log(np.random.uniform(0,1,1000)))**(1/k)47hist,edges=np.histogram(measured,density=True,bins=50)48x=np.linspace(0.0001,8,1000)49pdf=(k/lam)*(x/lam)**(k-1)*np.exp(-(x/lam)**k)50cdf=1-np.exp(-(x/lam)**k)51p4=make_plot(''WeibullDistribution(λ=1,k=1.25)'',hist,edges,x,pdf,cdf)52#显示53show(gridplot([p1,p2,p3,p4],ncols=2,plot_width=400,plot_height=400,toolbar_location=None))运行结果如图2-60所示 。