pin_drop当前位置:知识文库 ❯ 图文
matplotlib直方图hist()函数详解 - Python数据分布可视化
概述
plt.hist()用于绘制直方图,通过将连续数据分组为若干区间(bin),统计每个区间内的数据频次或频率。直方图是探索数据分布的核心工具,可以直观地观察数据的集中趋势、离散程度和分布形态(正态、偏态等)。
在数据分析的探索性分析(EDA)阶段,直方图几乎是必用的图表类型。它能帮助我们快速了解数据的基本特征:数据是否对称?是否存在异常值?数据是否服从某种理论分布?这些都是直方图能够回答的问题。
语法与参数说明
基本语法
代码示例
plt.hist(x, bins=None, range=None, density=False, **kwargs)核心参数
bins策略选择
返回值
返回元组(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()通过分组统计展示数据分布,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参数设置透明度使重叠部分可见。
本文涉及AI创作
内容由AI创作,请仔细甄别