Skip to content

Matplotlib - 直方图

直方图是一种强大的图形表示,用于展示数值数据的分布。它将数据点分组到指定的范围(分箱,bins)中,并绘制条形,其高度表示落入每个分箱中的数据点的频率(计数)。

直方图有助于可视化:

  • 集中趋势 (例如,数据聚集在哪里)。
  • 数据的分散度或变异性。
  • 分布的形状 (例如,对称的、偏斜的)。
  • 是否存在间隙或异常值。

ax.hist() 方法(面向对象 API)计算并绘制直方图。

Parameter描述
x输入数据 (1D 数组或用于绘制多个直方图的数组序列)。
bins定义分箱。可以是:整数 (相等宽度的分箱数量)、序列 (定义分箱边缘)、字符串 (例如,‘auto’, ‘fd’, ‘sqrt’ 用于自动分箱策略)。
range一个元组 (min, max),指定分箱的下限和上限范围。超出此范围的值将被忽略。
density如果为 True,结果是该分箱处概率密度函数的值,并进行归一化,使得直方图的面积 (而非高度) 积分等于 1。这对于比较不同样本大小的分布很有用。
cumulative如果为 True,计算累积直方图,其中每个分箱显示该分箱中的计数加上所有值较小的分箱中的计数。
histtype直方图类型:‘bar’ (默认,传统的条形)、‘barstacked’ (堆叠多个数据集)、‘step’ (生成未填充的折线图)、‘stepfilled’ (生成填充的折线图)。
color条形/阶梯线的颜色。
edgecolor条形边缘的颜色。
alpha透明度级别 (0=完全透明, 1=完全不透明)。
label数据集的标签,用于创建图例。

我们来绘制一个模拟考试成绩的直方图,以可视化其分布。

import matplotlib.pyplot as plt
import numpy as np
# 模拟一些考试成绩数据 (例如,均值为 75 的正态分布)
rng = np.random.default_rng(seed=123)
scores = rng.normal(loc=75, scale=15, size=200)
# 确保成绩在合理的范围 (例如,0-100)
scores = np.clip(scores, 0, 100)
# 创建图和坐标轴
fig, ax = plt.subplots(figsize=(8, 5))
# 明确定义分箱
bins = [0, 50, 60, 70, 80, 90, 100]
# 替代方案:让 Matplotlib 自动决定分箱:bins=10 或 bins='auto'
# 绘制直方图
counts, bin_edges, patches = ax.hist(
scores,
bins=bins,
color='skyblue',
edgecolor='black',
alpha=0.8,
label='Student Scores'
)
# 自定义图表
ax.set_title('Distribution of Exam Scores')
ax.set_xlabel('Score Range')
ax.set_ylabel('Number of Students (Frequency)')
# 将 x 轴刻度设置为与分箱边缘一致,以便更清晰
ax.set_xticks(bin_edges)
ax.tick_params(axis='x', rotation=45)
# (可选) 在每个条形上方添加显示计数文本标签
for count, patch in zip(counts, patches):
height = patch.get_height()
if height > 0: # 只标注非空条形
ax.annotate(f'{int(count)}',
xy=(patch.get_x() + patch.get_width() / 2, height),
xytext=(0, 5), # 垂直偏移 5 个点
textcoords='offset points',
ha='center', va='bottom')
ax.legend()
ax.grid(axis='y', linestyle='--', alpha=0.6)
plt.tight_layout()
plt.show()
# 输出计算出的计数和分箱边缘 (ax.hist 的返回值)
print("Counts per bin:", counts)
print("Bin edges:", bin_edges)

这段代码生成了一个直方图,显示了落入预定义分箱(0-50、50-60 等)中的学生人数。条形经过样式设置,添加了标签和标题,并明确将 x 轴刻度设置为分箱边缘。可选的标注在每个条形上方显示了确切的计数。ax.hist 函数方便地返回计算出的计数、分箱边缘以及条形块对象。

将 density=True 设置为 True 会将 y 轴更改为表示概率密度,而不是原始频率。此时,每个条形的面积对应于数据点落入该分箱的概率。这对于比较不同大小的数据集或叠加理论概率密度函数 (PDF) 很有用。