Matplotlib 直方图

Matplotlib 直方图(Histogram)完全指南

直方图是 分布分析、概率密度、数据探索 的核心工具。本教程带你从入门到 发表级,掌握 基础直方图、密度图、堆叠、分组、双峰检测、误差棒、累积直方图、2D 直方图、艺术风格、交互式 等全部技巧。


一、基本直方图

import matplotlib.pyplot as plt
import numpy as np

# 生成正态分布数据
data = np.random.randn(1000)

plt.hist(data)
plt.show()

二、核心参数详解

plt.hist(data,
         bins=30,              # 柱子数量或边界
         range=None,           # 数据范围
         density=False,        # 是否归一化为概率密度
         cumulative=False,     # 累积直方图
         color='skyblue',      # 颜色
         edgecolor='black',    # 边框
         alpha=0.7,            # 透明度
         histtype='bar',       # 类型:'bar', 'step', 'stepfilled'
         label='数据')

三、常用 bins 设置

类型代码说明
整数bins=3030个等宽柱
列表bins=[0, 1, 2, 3, 5]自定义边界
自动bins='auto'推荐,自动优化
Sturgesbins='sturges'小数据集
Scottbins='scott'理论最优
plt.hist(data, bins='auto', color='lightgreen', edgecolor='black')

四、概率密度图(归一化)

plt.hist(data, bins=30, density=True, alpha=0.7, color='steelblue', edgecolor='navy')
plt.ylabel('概率密度')
plt.title('归一化直方图')
plt.show()

density=True → 面积和为 1


五、叠加正态分布曲线

from scipy import stats

mu, sigma = np.mean(data), np.std(data)
x = np.linspace(data.min(), data.max(), 100)
normal_pdf = stats.norm.pdf(x, mu, sigma)

plt.hist(data, bins=30, density=True, alpha=0.7, color='skyblue', edgecolor='black', label='直方图')
plt.plot(x, normal_pdf, 'r-', linewidth=2, label=f'正态分布\nμ={mu:.2f}, σ={sigma:.2f}')
plt.legend()
plt.show()

六、堆叠直方图(Stacked)

data1 = np.random.normal(0, 1, 1000)
data2 = np.random.normal(2, 1.5, 1000)

plt.hist([data1, data2], bins=30, stacked=True, 
         color=['skyblue', 'lightcoral'], edgecolor='black',
         label=['组1', '组2'])
plt.legend()
plt.show()

七、分组直方图(并列)

plt.hist(data1, bins=30, alpha=0.7, color='skyblue', label='组1', edgecolor='black')
plt.hist(data2, bins=30, alpha=0.7, color='lightcoral', label='组2', edgecolor='black')
plt.legend()
plt.show()

八、水平直方图

plt.hist(data, bins=30, orientation='horizontal', color='purple', alpha=0.7)
plt.xlabel('频数')
plt.ylabel('值')
plt.show()

九、阶梯直方图(Step)

plt.hist(data, bins=30, histtype='step', linewidth=2, color='red')
plt.hist(data, bins=30, histtype='stepfilled', alpha=0.3, color='orange')
plt.show()

十、累积直方图

plt.hist(data, bins=30, cumulative=True, density=True, 
         color='green', edgecolor='darkgreen', linewidth=1.5)
plt.ylabel('累积概率')
plt.title('累积分布函数 (CDF)')
plt.show()

十一、2D 直方图(热力图)

x = np.random.randn(1000)
y = 1.5 * x + np.random.randn(1000)

plt.hist2d(x, y, bins=30, cmap='plasma')
plt.colorbar(label='频数')
plt.xlabel('X')
plt.ylabel('Y')
plt.title('2D 直方图')
plt.show()

十二、误差棒直方图(带置信区间)

# 模拟多组实验数据
experiments = [np.random.normal(0, 1, 100) for _ in range(10)]
means = [np.mean(exp) for exp in experiments]
stds = [np.std(exp) for exp in experiments]

x_pos = np.arange(len(means))

plt.bar(x_pos, means, yerr=stds, capsize=5, 
        color='lightblue', edgecolor='navy', alpha=0.8)
plt.xlabel('实验编号')
plt.ylabel('均值')
plt.title('多组实验均值 ± 标准差')
plt.show()

十三、完整专业示例(论文级)

import matplotlib.pyplot as plt
import numpy as np
from scipy import stats

plt.style.use('seaborn-v0_8')
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

# 生成双峰数据
np.random.seed(42)
data_bimodal = np.concatenate([
    np.random.normal(-2, 1, 600),
    np.random.normal(3, 1.5, 400)
])

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

# === 左图:密度直方图 + KDE ===
n, bins, patches = ax1.hist(data_bimodal, bins=50, density=True, 
                            alpha=0.6, color='#1f77b4', edgecolor='white', linewidth=0.5)

# 添加核密度估计(KDE)
from scipy.stats import gaussian_kde
kde = gaussian_kde(data_bimodal)
x_kde = np.linspace(data_bimodal.min(), data_bimodal.max(), 200)
ax1.plot(x_kde, kde(x_kde), 'r-', linewidth=2.5, label='KDE 估计')

# 正态分布对比
mu, sigma = np.mean(data_bimodal), np.std(data_bimodal)
x_norm = np.linspace(data_bimodal.min(), data_bimodal.max(), 200)
ax1.plot(x_norm, stats.norm.pdf(x_norm, mu, sigma), 'k--', linewidth=1.5, label=f'正态拟合\nμ={mu:.2f}, σ={sigma:.2f}')

ax1.set_title('双峰分布分析', fontsize=16, fontweight='bold', pad=15)
ax1.set_xlabel('测量值', fontsize=12)
ax1.set_ylabel('概率密度', fontsize=12)
ax1.legend(fontsize=10)
ax1.grid(True, alpha=0.3, linestyle='--')

# === 右图:累积分布 + 分位数标注 ===
ax2.hist(data_bimodal, bins=50, cumulative=True, density=True, 
         color='#ff7f0e', edgecolor='white', alpha=0.8, linewidth=0.5)

# 添加分位数线
q25, q50, q75 = np.percentile(data_bimodal, [25, 50, 75])
for q, label, color in zip([q25, q50, q75], ['Q1', '中位数', 'Q3'], ['green', 'red', 'purple']):
    ax2.axvline(q, color=color, linestyle='--', linewidth=2)
    ax2.text(q, 0.9, f'{label}: {q:.2f}', color=color, fontweight='bold',
             ha='center', va='bottom', bbox=dict(boxstyle="round", facecolor='white', alpha=0.8))

ax2.set_title('累积分布函数 (CDF)', fontsize=16, fontweight='bold', pad=15)
ax2.set_xlabel('测量值', fontsize=12)
ax2.set_ylabel('累积概率', fontsize=12)
ax2.grid(True, alpha=0.3, linestyle='--')

# 总标题
fig.suptitle('Matplotlib 直方图专业分析示例', fontsize=18, fontweight='bold', y=1.02)

plt.tight_layout()
plt.savefig('histogram_pro.png', dpi=300, bbox_inches='tight', facecolor='white')
plt.show()

十四、直方图速查表(收藏用)

# 基础
plt.hist(data, bins=30)

# 密度图
plt.hist(data, density=True, alpha=0.7)

# 堆叠
plt.hist([d1, d2], stacked=True)

# 并列
plt.hist(d1, alpha=0.7); plt.hist(d2, alpha=0.7)

# 阶梯
plt.hist(data, histtype='step', linewidth=2)

# 累积
plt.hist(data, cumulative=True, density=True)

# 2D
plt.hist2d(x, y, bins=30, cmap='hot')

# 自动bins
plt.hist(data, bins='auto')

十五、常见问题解决

问题解决方案
柱子太密/太稀bins='auto' 或手动设置
看不到分布形状density=True + 叠加 KDE
颜色重叠alpha=0.6 + edgecolor='white'
2D 颜色条太小plt.colorbar(shrink=0.8)
保存裁剪plt.savefig(..., bbox_inches='tight')

十六、推荐风格模板

场景推荐设置
论文密度图 + KDE + 白边
PPT彩色柱 + 透明度
探索分析bins='auto' + 阶梯线
双变量hist2d + plasma 热图

十七、添加统计信息框

mean = np.mean(data)
std = np.std(data)
text = f'均值: {mean:.2f}\n标准差: {std:.2f}\n样本数: {len(data)}'

plt.hist(data, bins=30, color='lightblue', edgecolor='black', alpha=0.7)
plt.text(0.95, 0.95, text, transform=plt.gca().transAxes,
         verticalalignment='top', horizontalalignment='right',
         bbox=dict(boxstyle="round", facecolor='wheat', alpha=0.8))
plt.show()

官方文档

  • Hist API:https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.hist.html
  • 2D Hist:https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.hist2d.html
  • 示例图库:https://matplotlib.org/stable/gallery/statistics/histogram_features.html

总结:三步打造专业直方图

# 1. 绘制密度直方图
n, bins, patches = plt.hist(data, bins='auto', density=True, alpha=0.7, edgecolor='white')

# 2. 叠加KDE曲线
kde = gaussian_kde(data)
x = np.linspace(min(data), max(data), 200)
plt.plot(x, kde(x), 'r-', linewidth=2)

# 3. 美化输出
plt.xlabel('值'); plt.ylabel('密度')
plt.title('分布分析')
plt.grid(True, alpha=0.3)
plt.savefig('hist.png', dpi=300, bbox_inches='tight')

一键生成密度直方图 + 正态曲线

data = np.random.randn(1000)
plt.hist(data, bins=30, density=True, alpha=0.7, color='skyblue', edgecolor='black')
x = np.linspace(-4, 4, 100)
plt.plot(x, stats.norm.pdf(x), 'r-', linewidth=2)
plt.show()

需要我为你:

  • 生成 10种经典直方图模板
  • 制作 Jupyter 直方图交互小工具(滑块调整 bins)?
  • 输出 LaTeX/PPT 可用代码

告诉我你的需求!

文章已创建 2481

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部