在前面关于 matploblib 的文章中,笔者分别介绍了:
本篇介绍 matplotlib 绘制直方图的方法。直方图(Histogram)又称质量分布图,是一种条形图,由一系列纵向线段来表示数据分布的情况。 其横轴表示数据区间,纵轴表示区间内分布情况(频数或频率)。它与柱状图的区别是:直方图统计了指定的各个区间内的数量分布或频率分布;而柱状图则用于展示各个类别的数据。因此,绘制直方图,关键是指定划分区间。
Matplotlib 提供了 hist() 函数来绘制直方图,它可以应用在 MATLAB 样式以及面向对象的绘图方法中。当它与 axes 对象一起使用时,其语法格式如下:
axes.hist(x, bins, range, density=False, weights, cumulative=False, bottom, histtype='bar', align='mid', orientation='vertical', rwidth, log=False, color, label, stacked=False, **kwargs)
该函数返回元组 (n_arr, bins_arr, patches),n_arr 是一个元素为频数/频率的 numpy 数组;bins_arr 也是 numpy 数组,元素为直方图的各个分界点;patches 是一个 BarContainer 对象,包含每个直方图。
示例一:
import numpy as np
import matplotlib.pyplot as plt
fig = plt.figure('Hist example1', figsize=(9.5, 6.8))
x = np.random.randn(1000) # 创建数据
ax1 = fig.add_subplot(221)
ax1.hist(x, bins=5, range=(-3.5, 0)) # 仅统计-3.5到0之间的数据
ax2 = fig.add_subplot(222)
bins=[0, 0.5, 1.1, 1.6, 2.5, 3]
ax2.hist(x, bins, color='g') # 直接指定分界点,实现非等分划分
ax2.set_xticks(bins)
ax3 = fig.add_subplot(223)
xmin, xmax, bins = x.min(), x.max(), 7
interval = (xmax - xmin) / bins
xticks = np.arange(xmin, xmax+interval/2, interval, dtype=np.float64)
ax3.hist(x, bins, color='y')
ax3.set_xticks(xticks) # 把分界点作为 x 轴刻度
ax4 = fig.add_subplot(224)
bins = range(-4, 5)
ax4.hist(x, bins, color='r', density=True) # 在指定范围内统计各区间频率
ax4.set_xticks(bins)
plt.show()
示例二:
import numpy as np
import matplotlib.pyplot as plt
fig = plt.figure('Hist example2', figsize=(8.5, 6.8))
x = np.random.randn(1000) # 创建数据
ax1 = fig.add_subplot(221)
ax1.hist(x, bins=7, orientation='horizontal') # 绘制横向直方图
ax2 = fig.add_subplot(222)
n_arr, bin_arr, _ = ax2.hist(x, bins=7, color='c') # 对函数返回值进行拆包,获得各区间统计值和各分界点
bin_list = bin_arr.tolist()
dx = (bin_list[1] - bin_list[0]) / 2
for i,j in zip(bin_list[:-1], n_arr):
ax2.text(i+dx, j+0.1, "%d"%j, ha="center", va="bottom") # 把统计数据加到直方图上方
ax2.set_xticks(bin_list) # 把各分界点作为 x 轴刻度
ax2.grid(axis='x')
ax3 = fig.add_subplot(223)
bins = range(-3, 4)
ht = ax3.hist(x, bins, density=True, cumulative=True, histtype='step') # 绘制频率累积直方图,类型为阶梯形
for i, j in zip(bins[:-1], ht[0]):
ax3.text(i, j+0.01, '%.1f%%'%(j*100)) # 把频率数据加到直方图上方
ax4 = fig.add_subplot(224)
ax4.hist(x, bins=20, density=True, rwidth=0.8, label='a1', color='r') # 指定直方图每个矩形相对于默认值的宽度
plt.show()
以上。