社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

手把手教你用Python画直方图:其实跟柱状图完全不同

数据派THU • 4 年前 • 316 次点击  


来源:大数据DT


本文约2000字,建议阅读5分钟

本文教你用Python画直方图。

[ 导读 ] 直方图和柱状图都是数据分析中非常常见、常用的图表,由于两者外观上看起来非常相似,也就难免造成一些混淆。今天我们来讲讲直方图。


01 概述

直方图(Histogram),形状类似柱状图却有着与柱状图完全不同的含义。直方图牵涉统计学概念,首先要对数据进行分组,然后统计每个分组内数据元的数量。在平面直角坐标系中,横轴标出每个组的端点,纵轴表示频数,每个矩形的高代表对应的频数,这样的统计图称为频数分布直方图。

频数分布直方图需要经过频数乘以组距的计算过程才能得出每个分组的数量,同一个直方图的组距是一个固定不变的值,所以如果直接用纵轴表示数量,每个矩形的高代表对应的数据元数量,既能保持分布状态不变,又能直观地看出每个分组的数量,如图2-58所示。

▲图2-58 直方图


通过直方图还可以观察和估计哪些数据比较集中,异常或者孤立的数据分布在何处。

首先,了解如下几个基本概念。

  • 组数:在统计数据时,我们把数据按照不同的范围分成几个组,分成的组的个数称为组数。

  • 组距:每一组两个端点的差。

  • 频数:分组内数据元的数量除以组距。


02 实例

直方图代码示例如下所示。

  • 代码示例 2-45




    
1plot = figure(plot_width=300, plot_height=300)  
2plot.quad(top=[234], bottom=[123], left=[123],  
3          right=[1.22.53.7], color="#B3DE69")  
4show(plot)


行结果如图2-59所示。


▲图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特有数据格式(类似于Pandas Dataframe)

  • legend (str) : 图元的图例

  • x_range_name (str) : x轴范围名称

  • y_range_name (str) : y轴范围名称

  • level (Enum) : 图元渲染级别

代码示例 2-46




    
 1import numpy as np  
2import scipy.special  
3from bokeh.layouts import gridplot  
4# 绘图函数  
5def make_plot(title, hist, edges, x, pdf, cdf):  
6    p = figure(title=title, tools='', background_fill_color="#fafafa")  
7    p.quad(top=hist, bottom=0, left=edges[:-1], right=edges[1:],  
8           fill_color="navy", line_color="white", alpha=0.5)  
9    p.line(x, pdf, line_color="#ff8888", line_width=4, alpha=0.7, legend="PDF")
10    p.line(x, cdf, line_color="orange", line_width=2, alpha=0.7, legend="CDF")
11
12    p.y_range.start = 0  
13    p.legend.location = "center_right"  
14    p.legend.background_fill_color = "#fefefe"  
15    p.xaxis.axis_label = 'x'  
16    p.yaxis.axis_label = 'Pr(x)'  
17    p.grid.grid_line_color="white"  
18    return p  
19# 正态分布  
20mu, sigma = 00.5  
21measured = np.random.normal(mu, sigma, 1000)  
22hist, edges = np.histogram(measured, density=True, bins=50)  
23x = np.linspace(-221000)  
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)))/2  
27p1 = make_plot("Normal Distribution (μ=0, σ=0.5)", hist, edges, x, pdf, cdf)
28# 对数正态分布  
29mu, sigma = 00.5  
30measured = np.random.lognormal(mu, sigma, 1000)  
31hist, edges = np.histogram(measured, density=True, bins=50)  
32x = np.linspace(0.00018.01000)  
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)))/2  
35p2 = make_plot("Log Normal Distribution (μ=0, σ=0.5)", hist, edges, x, pdf, cdf)
36# 伽玛分布  
37k, theta = 7.51.0  
38measured = np.random.gamma(k, theta, 1000)  
39hist, edges = np.histogram(measured, density=True, bins=50)  
40x = np.linspace(0.000120.01000)  
41pdf = x**(k-1) * np.exp(-x/theta) / (theta**k * scipy.special.gamma(k))  
42cdf = scipy.special.gammainc(k, x/theta)  
43p3 = make_plot("Gamma Distribution (k=7.5, θ=1)", hist, edges, x, pdf, cdf)  
44# 韦伯分布  
45lam, k = 11.25  
46measured = lam*(-np.log(np.random.uniform(011000)))**(1/k)  
47hist, edges = np.histogram(measured, density=True, bins=50)  
48x = np.linspace(0.000181000)  
49pdf = (k/lam)*(x/lam)**(k-1) * np.exp(-(x/lam)**k)  
50cdf = 1 - np.exp(-(x/lam)**k)  
51p4 = make_plot("Weibull Distribution (λ=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所示。


▲图2-60 代码示例2-46运行结果


代码示例2-46第5行自定义绘图函数make_plot (title, hist, edges, x, pdf, cdf),其中参数分别为图的标题、直方顶部边界、左右边界、拟合曲线的x坐标、方法通过定义矩形的四边边界,PDF为概率密度函数,CDF为累积分布函数。第53行通过gridplot()方法一次展示4张图(正态分布、对数正态分布、伽玛分布、韦伯分布)。

关于作者:

屈希峰,资深Python工程师,Bokeh领域的实践者和布道者,对Bokeh有深入的研究。擅长Flask、MongoDB、Sklearn等技术,实践经验丰富。知乎多个专栏(Python中文社区、Python程序员、大数据分析挖掘)作者,专栏累计关注用户十余万人。

本文摘编自《Python数据可视化:基于Bokeh的可视化绘图》,经出版方授权发布。


编辑:于腾凯
校对:林亦霖
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/56446
 
316 次点击