pin_drop当前位置:知识文库 ❯ 图文

matplotlib直方图hist()函数详解 - Python数据分布可视化

概述

plt.hist()用于绘制直方图,通过将连续数据分组为若干区间(bin),统计每个区间内的数据频次或频率。直方图是探索数据分布的核心工具,可以直观地观察数据的集中趋势、离散程度和分布形态(正态、偏态等)。

在数据分析的探索性分析(EDA)阶段,直方图几乎是必用的图表类型。它能帮助我们快速了解数据的基本特征:数据是否对称?是否存在异常值?数据是否服从某种理论分布?这些都是直方图能够回答的问题。


语法与参数说明

基本语法

代码示例

plt.hist(x, bins=None, range=None, density=False, **kwargs)

核心参数

参数 类型 默认值 说明
x array_like 必填 输入数据
bins int/list/str 10 区间数量、边界列表或策略名
range tuple None 数据范围(最小值, 最大值)
density bool False True时显示频率密度(面积=1)
cumulative bool False 是否计算累积分布
histtype str 'bar' 直方图类型:'bar'/'step'/'stepfilled'
color str None 填充颜色
edgecolor str None 边框颜色
alpha float None 透明度
label str None 图例标签
weights array None 每个数据的权重
rwidth float None 柱子宽度比例

bins策略选择

策略名 说明
'auto' 自动选择(Sturges+FD)
'fd' Freedman-Diaconis规则
'sturges' Sturges公式
'scott' Scott规则
'stone' Stone规则
整数 指定区间数量
列表 指定区间边界

返回值

返回元组(n, bins, patches),其中:

  • n:频次数组,每个区间的计数值

  • bins:区间边界数组,长度为n+1

  • patches:Rectangle对象列表,可用于后续样式修改


代码示例

示例1:基本直方图

生成正态分布数据,绘制基本的直方图,设置bins数量为20,并添加白色边框使柱子更清晰。

代码示例

import matplotlib.pyplot as plt
import numpy as np

# 生成正态分布数据
np.random.seed(42)
data = np.random.normal(loc=170, scale=10, size=500)

# 绘制基本直方图
plt.figure(figsize=(8, 5))
n, bins, patches = plt.hist(data, bins=20, color='#2196F3',
                            edgecolor='white', alpha=0.8)

plt.title('Height Distribution')
plt.xlabel('Height (cm)')
plt.ylabel('Frequency')
plt.grid(axis='y', alpha=0.3)
plt.savefig('basic_hist.png', dpi=100, bbox_inches='tight')
print(f"区间数: {len(n)}, 频次范围: {n.min()}-{n.max()}")
print("基本直方图已保存")

输出:

代码示例

区间数: 20, 频次范围: 2-62
基本直方图已保存

示例2:多组数据对比与密度直方图

通过并排对比频次直方图和密度直方图,理解两者的区别。密度直方图的面积之和为1,适合比较不同样本量的数据。

代码示例

import matplotlib.pyplot as plt
import numpy as np

np.random.seed(42)
data_a = np.random.normal(70, 10, 300)
data_b = np.random.normal(80, 12, 300)

fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 5))

# 频次直方图(多组对比)
ax1.hist(data_a, bins=20, alpha=0.6, label='Class A', color='#2196F3', edgecolor='white')
ax1.hist(data_b, bins=20, alpha=0.6, label='Class B', color='#FF5722', edgecolor='white')
ax1.set_title('Frequency Histogram')
ax1.set_xlabel('Score')
ax1.set_ylabel('Frequency')
ax1.legend()
ax1.grid(axis='y', alpha=0.3)

# 密度直方图(面积=1,可比较不同样本量)
ax2.hist(data_a, bins=20, alpha=0.6, density=True, label='Class A', color='#2196F3', edgecolor='white')
ax2.hist(data_b, bins=20, alpha=0.6, density=True, label='Class B', color='#FF5722', edgecolor='white')
ax2.set_title('Density Histogram')
ax2.set_xlabel('Score')
ax2.set_ylabel('Density')
ax2.legend()
ax2.grid(axis='y', alpha=0.3)

plt.tight_layout()
plt.savefig('compare_hist.png', dpi=100, bbox_inches='tight')
print("对比直方图已保存")

输出:

代码示例

对比直方图已保存

示例3:累积直方图与步进直方图

演示cumulative参数生成累积分布图,以及histtype='step'和'stepfilled'的步进样式。

代码示例

import matplotlib.pyplot as plt
import numpy as np

np.random.seed(42)
data = np.random.exponential(scale=2, size=500)

fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 5))

# 累积直方图
ax1.hist(data, bins=30, cumulative=True, color='#4CAF50',
         edgecolor='white', alpha=0.8)
ax1.set_title('Cumulative Histogram')
ax1.set_xlabel('Value')
ax1.set_ylabel('Cumulative Frequency')
ax1.grid(axis='y', alpha=0.3)

# 步进直方图
ax2.hist(data, bins=30, histtype='step', color='#FF5722',
         linewidth=2, label='Step')
ax2.hist(data, bins=30, histtype='stepfilled', color='#2196F3',
         alpha=0.3, label='Step Filled')
ax2.set_title('Step Histogram')
ax2.set_xlabel('Value')
ax2.set_ylabel('Frequency')
ax2.legend()
ax2.grid(axis='y', alpha=0.3)

plt.tight_layout()
plt.savefig('cumulative_step_hist.png', dpi=100, bbox_inches='tight')
print("累积与步进直方图已保存")

输出:

代码示例

累积与步进直方图已保存

实际应用场景

  • 数据探索:使用直方图检查数据是否服从正态分布,判断是否存在偏态或异常值

  • 图像处理:使用直方图分析图像的亮度分布,为图像增强和直方图均衡化提供依据

  • 质量控制:使用直方图监控产品尺寸的分布情况,判断生产过程是否稳定


注意事项

注意:bins的选择对直方图形态影响很大,建议尝试不同值或使用'auto'策略

注意:density=True时Y轴为频率密度(频率/组距),面积之和为1,不是百分比

注意:直方图与柱状图不同,直方图的X轴是连续区间,柱状图的X轴是离散类别


直方图与柱状图对比

特性 直方图hist 柱状图bar
X轴 连续区间 离散类别
柱子间距 无间距 有间距
数据类型 连续数值 分类数据
目的 展示分布 对比大小
柱宽含义 区间宽度 无特殊含义

小结

  • hist()通过分组统计展示数据分布,bins参数控制区间数量

  • density=True显示频率密度,适合不同样本量的对比

  • cumulative=True显示累积分布,histtype='step'显示步进样式

  • 直方图适合连续数据的分布分析,柱状图适合分类数据的对比


练习题

练习1

生成1000个正态分布随机数,绘制直方图,分别使用bins=10、30、50,对比效果

练习2

生成两组不同均值和标准差的正态分布数据,绘制密度直方图进行对比

练习3

生成指数分布数据,绘制累积直方图,观察累积分布曲线

常见问题

hist()和bar()的区别是什么?

hist()用于连续数据的分布展示,自动将数据分组并统计频次,柱子之间无间距;bar()用于离散类别数据的对比,需要手动指定每个柱子的高度,柱子之间有间距。

如何选择合适的bins数量?

bins太少会掩盖数据特征,太多会引入噪声。建议使用bins='auto'让matplotlib自动选择,或使用Sturges、FD等统计规则。也可以根据数据量手动尝试不同值,找到最能展示数据分布的bins数。

density=True和normed有什么区别?

normed是旧版参数,已在matplotlib 2.1中废弃,统一使用density。当density=True时,Y轴显示的是频率密度(频率/组距),直方图的总面积为1,这样可以与概率密度函数进行比较。

如何在直方图上叠加正态分布曲线?

先使用density=True绘制直方图,然后用scipy.stats.norm.pdf()或手动计算正态分布的PDF值,在同一个Axes上用plot()叠加绘制。注意X轴范围应与直方图的bins范围一致。

如何设置直方图柱子的边框颜色和宽度?

使用edgecolor参数设置边框颜色(如edgecolor='white'),使用linewidth参数设置边框宽度。添加白色边框可以让相邻的柱子更加清晰可辨,推荐使用alpha参数设置透明度使重叠部分可见。

标签: matplotlib 直方图 数据分布 数据可视化 Python教程 hist函数

本文涉及AI创作

内容由AI创作,请仔细甄别

list快速访问

上一篇: matplotlib饼图pie教程 - 环形图突出显示百分比标注 下一篇: matplotlib子图subplot()函数详解 - Python多图布局绘制

poll相关推荐