如何在 Matplotlib 中同时绘制两个直方图?从基础到实践的完整指南

在数据分析和可视化的工作中,我们经常需要对比两组数据的分布情况。直方图作为一种展示数据频率分布的经典工具,能够让我们直观地看到数据的集中趋势、离散程度以及形态。然而,当我们面对两组数据并希望在一个图表中对比它们时,单纯的画图往往是不够的——我们需要它们重叠在一起,以便清晰地发现差异。

在本文中,我们将深入探讨如何使用 Python 的 Matplotlib 库在同一个坐标系中绘制两个直方图。我们将从最基本的语法开始,逐步深入到样式调整、透明度控制以及最佳实践,帮助你掌握这一必备技能。

直方图基础:为什么我们需要它?

直方图通过将数据分割成连续的区间(通常称为“箱子”或 bins),并统计每个区间内数据的数量,来展示数据的分布概貌。与柱状图不同,直方图展示的是定量数据的分布,而不是分类数据的计数。

当我们只有一组数据时,单一直方图就足够了。但现实生活中,数据往往需要比较。例如:

  • A/B 测试:对比两个不同版本的网页加载时间。
  • 实验组与对照组:对比药物组和安慰剂组的生理指标。
  • 不同时间段:对比今年与去年的销售额分布。

这时候,将两个直方图绘制在一起就显得尤为重要。我们可以很容易地通过重叠部分来观察两组数据的重合度或差异。

核心工具:Matplotlib 的 hist() 函数

在 Matplotlib 中,INLINECODE150c9a37 模块提供了 INLINECODE94663b12 函数,这是我们绘制直方图的核心工具。其基本用法非常灵活,允许我们通过参数精细控制图表的每一个细节。

基本语法解析

plt.hist() 的核心参数包括:

  • x: 你要传入的数据源(列表或数组)。
  • bins: 决定直方图的“柱子”数量或具体的分箱边界。
  • alpha: 透明度,对于重叠图至关重要(0为完全透明,1为不透明)。
  • color: 柱子的填充颜色。
  • edgecolor: 柱子边缘的颜色。
  • label: 图例标签,用于区分不同数据集。

入门实战:绘制第一个重叠直方图

让我们从一个最简单的例子开始。我们将使用 NumPy 生成两组随机数据,看看将它们直接绘制在一起会发生什么。

示例 1:基础叠加(注意默认行为)

在这个例子中,我们生成两组标准正态分布的随机数。为了演示,我们暂时不设置透明度,看看会发生什么。

# 导入必要的库
import matplotlib.pyplot as plt
import numpy as np

# 设置随机种子以保证结果可复现
np.random.seed(42)

# 使用 Numpy 生成两组随机数据
# group1: 500个数据点,标准正态分布
group1 = np.random.randn(500)
# group2: 400个数据点,标准正态分布
group2 = np.random.randn(400)

# 绘制第一个直方图(蓝色)
plt.hist(group1, label=‘Group 1‘)

# 绘制第二个直方图(橙色,默认覆盖在上面)
plt.hist(group2, label=‘Group 2‘)

# 显示图例
plt.legend()

# 展示图表
plt.show()

结果分析:

运行这段代码,你会发现一个问题:由于默认情况下柱子是不透明的,第二个直方图(Group 2)会直接覆盖在第一个直方图(Group 1)之上。这使得我们无法看到被遮挡的数据,也就失去了“对比”的意义。这显然不是我们想要的效果。

关键优化:让重叠部分可见

为了解决遮挡问题,我们需要引入 Alpha 通道(透明度)。这是绘制重叠直方图时最关键的一步。

示例 2:引入透明度和边缘颜色

现在,我们修改代码,给柱子设置一定的透明度,并给边缘加上颜色,这样即使重叠,我们也能通过颜色的混合效果看到背后的数据。

import matplotlib.pyplot as plt
import numpy as np

np.random.seed(42)

# 生成数据
group1 = np.random.randn(500)
group2 = np.random.randn(400) + 1.5 # 让 group2 的均值偏移一点,方便观察

# 绘制第一个直方图
# alpha=0.6 表示 60% 不透明度
# edgecolor=‘black‘ 给每个柱子加黑色边框
plt.hist(group1, label=‘Group 1 (Control)‘, alpha=0.6, edgecolor=‘black‘)

# 绘制第二个直方图
plt.hist(group2, label=‘Group 2 (Treatment)‘, alpha=0.6, edgecolor=‘black‘)

plt.legend()
plt.title("带透明度的重叠直方图")
plt.show()

实用见解:

通过设置 alpha=0.6(通常 0.5 到 0.7 之间效果最好),两组数据重叠的部分会呈现出颜色叠加的效果。这让我们一眼就能看出两组数据的分布中心(均值)是否一致,以及它们的离散程度(方差)有何不同。

进阶应用:自定义颜色与分箱

有时候,我们需要自定义颜色来匹配特定的主题,或者为了色盲友好。同时,调整 bins(箱数)可以改变直方图的精细度。

示例 3:自定义颜色和固定箱数

在这个例子中,我们对比两组特定年龄段的人群数据。我们使用红色和黄色作为对比色,并强制指定 bins=14,确保两个直方图的分割是完全一致的。

import matplotlib.pyplot as plt

# 定义两个年龄段的数据列表
age_g1 = [1, 3, 5, 10, 15, 17, 18, 16, 19, 21, 23, 28, 30, 31, 33, 38, 32, 
          40, 45, 43, 49, 55, 53, 63, 66, 85, 80, 57, 75, 93, 95]

age_g2 = [6, 4, 15, 17, 19, 21, 28, 23, 31, 36, 39, 32, 50, 56, 59, 74, 79, 34, 
          98, 97, 95, 67, 69, 92, 45, 55, 77, 76, 85]

# 绘图
# bins=14: 将数据分为14个区间
# alpha=.7: 设置透明度
# edgecolor: 设置边缘颜色
plt.hist(age_g1, label=‘年龄段 A‘, bins=14, alpha=.7, edgecolor=‘red‘)
plt.hist(age_g2, label="年龄段 B", bins=14, alpha=.7, edgecolor=‘black‘)

plt.legend()
plt.xlabel("年龄")
plt.ylabel("频数")
plt.title("两个不同年龄组的分布对比")
plt.show()

注意: 当对比两组数据时,确保两组直方图使用相同的 bins 参数是非常重要的。如果一组用10个箱子,另一组用20个,那么它们的宽度就不一样,对比就会失去意义。

示例 4:完全自定义美学风格

为了让你拥有完全的控制权,我们可以把填充色和边缘色都设置为自定义值,甚至完全移除边缘颜色,只保留纯色的半透明效果。

import matplotlib.pyplot as plt

# 使用之前的年龄数据
age_g1 = [1, 3, 5, 10, 15, 17, 18, 16, 19, 21, 23, 28, 30, 31, 33, 38, 32, 
          40, 45, 43, 49, 55, 53, 63, 66, 85, 80, 57, 75, 93, 95]
age_g2 = [6, 4, 15, 17, 19, 21, 28, 23, 31, 36, 39, 32, 50, 56, 59, 74, 79, 34, 
          98, 97, 95, 67, 69, 92, 45, 55, 77, 76, 85]

# 绘图:使用现代风格配色
# Group 1: 红色系,高透明度
plt.hist(age_g1, label=‘年龄段 A‘, alpha=0.5, color=‘red‘, edgecolor=‘black‘)

# Group 2: 黄色系,带边缘色
plt.hist(age_g2, label="年龄段 B", alpha=0.5, color=‘yellow‘, edgecolor=‘black‘)

plt.legend(loc=‘upper right‘) # 指定图例位置
plt.grid(True, linestyle=‘--‘, alpha=0.3) # 添加网格线增加可读性
plt.show()

常见陷阱与解决方案

在实际开发中,你可能会遇到以下问题,这里我们提供解决方案:

1. 数据量级差异巨大怎么办?

如果 Group A 有 10,000 个数据点,而 Group B 只有 100 个,那么 Group A 的直方图会非常巨大,导致 Group B 被压缩到看不见。

解决方案: 使用 density=True 参数。这会将直方图归一化为概率密度(面积总和为1),而不是显示原始计数。

plt.hist(group1, alpha=0.5, label=‘Group 1‘, density=True)
plt.hist(group2, alpha=0.5, label=‘Group 2‘, density=True)

这样,你对比的是“形状”和“分布比例”,而不是绝对数量,非常适合数据量不一致的情况。

2. 箱子宽度不一致怎么办?

最稳健的方法不是指定 INLINECODE1221e74e 的数量(整数),而是指定 INLINECODEd94688e7 的边界(一个序列)。

# 定义统一的边界,例如从 0 到 100,每 10 一个单位
import numpy as np
bins_boundary = np.arange(0, 101, 10)

plt.hist(group1, bins=bins_boundary, alpha=0.5, label=‘Group 1‘)
plt.hist(group2, bins=bins_boundary, alpha=0.5, label=‘Group 2‘)

这样可以确保两组数据严格在相同的区间内进行统计。

总结与最佳实践

在这篇文章中,我们一起探索了如何使用 Matplotlib 绘制双直方图。从最基础的代码到样式的精细调整,这些技巧能够帮助你更好地展示数据对比。

关键要点回顾:

  • 一定要使用 alpha 参数:这是区分重叠直方图最简单、最有效的方法。建议值在 0.5 到 0.7 之间。
  • 统一 bins 设置:对比的前提是标准一致,确保两组数据使用相同的分箱策略。
  • 善用图例 (INLINECODE2a2b52ef 和 INLINECODEe858852d):不要让读者猜哪条线是哪个数据,清晰的标注是专业图表的基础。
  • 数据归一化 (density=True):当数据量级不同时,记得开启此选项以对比分布形态。

接下来,我鼓励你尝试在自己的数据集上应用这些技巧。你可以尝试调整颜色、透明度和箱数,看看不同的设置如何影响数据的解读。掌握这些基础后,你将能更自信地进行数据探索和汇报。

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。如需转载,请注明文章出处豆丁博客和来源网址。https://shluqu.cn/18682.html
点赞
0.00 平均评分 (0% 分数) - 0