Matplotlib中创建累积直方图:全面指南与实例
参考:Create a cumulative histogram in Matplotlib
累积直方图是数据可视化中的一个重要工具,它能够直观地展示数据的分布和累积趋势。在Python的Matplotlib库中,我们可以轻松创建各种类型的累积直方图,以满足不同的数据分析需求。本文将详细介绍如何在Matplotlib中创建累积直方图,包括基本概念、实现方法、常见应用场景以及进阶技巧。
1. 累积直方图的基本概念
累积直方图是普通直方图的一种变体,它显示了数据值小于或等于某个特定值的观测数量或比例。与普通直方图相比,累积直方图能够更好地展示数据的整体分布趋势和累积特性。
在Matplotlib中创建累积直方图主要有两种方法:
1. 使用plt.hist()
函数并设置cumulative=True
参数
2. 使用np.cumsum()
函数手动计算累积值,然后使用plt.plot()
绘制
下面我们将通过具体的示例来详细说明这两种方法。
2. 使用plt.hist()函数创建累积直方图
2.1 基本用法
最简单的创建累积直方图的方法是使用plt.hist()
函数,并设置cumulative=True
参数。以下是一个基本示例:
import matplotlib.pyplot as plt
import numpy as np
# 生成示例数据
data = np.random.normal(0, 1, 1000)
# 创建累积直方图
plt.hist(data, bins=30, cumulative=True, density=True, label='Cumulative')
# 设置图表标题和标签
plt.title('Cumulative Histogram - how2matplotlib.com')
plt.xlabel('Value')
plt.ylabel('Cumulative Frequency')
plt.legend()
# 显示图表
plt.show()
Output:
在这个示例中,我们首先生成了1000个服从标准正态分布的随机数。然后使用plt.hist()
函数创建累积直方图,设置cumulative=True
来启用累积模式,density=True
来归一化频率。
2.2 自定义累积直方图的外观
我们可以通过调整各种参数来自定义累积直方图的外观:
import matplotlib.pyplot as plt
import numpy as np
# 生成示例数据
data = np.random.exponential(scale=2, size=1000)
# 创建累积直方图
plt.hist(data, bins=50, cumulative=True, density=True,
histtype='step', linewidth=2, color='blue',
label='Cumulative - how2matplotlib.com')
# 设置图表标题和标签
plt.title('Customized Cumulative Histogram')
plt.xlabel('Value')
plt.ylabel('Cumulative Frequency')
plt.legend()
# 设置x轴和y轴的范围
plt.xlim(0, 15)
plt.ylim(0, 1.1)
# 添加网格线
plt.grid(True, linestyle='--', alpha=0.7)
# 显示图表
plt.show()
Output:
在这个示例中,我们使用了指数分布的数据,并通过设置histtype='step'
来绘制阶梯式的累积直方图。我们还自定义了线宽、颜色,并设置了坐标轴范围和网格线。
3. 手动计算累积值并绘制
有时我们可能需要更灵活地控制累积值的计算和绘制过程。在这种情况下,我们可以手动计算累积值,然后使用plt.plot()
函数绘制。
3.1 基本手动累积直方图
以下是一个基本的手动累积直方图示例:
import matplotlib.pyplot as plt
import numpy as np
# 生成示例数据
data = np.random.normal(0, 1, 1000)
# 计算直方图数据
counts, bin_edges = np.histogram(data, bins=30)
# 计算累积值
cumulative = np.cumsum(counts)
# 绘制累积直方图
plt.plot(bin_edges[1:], cumulative, label='Cumulative - how2matplotlib.com')
# 设置图表标题和标签
plt.title('Manual Cumulative Histogram')
plt.xlabel('Value')
plt.ylabel('Cumulative Count')
plt.legend()
# 显示图表
plt.show()
Output:
在这个示例中,我们首先使用np.histogram()
计算直方图数据,然后使用np.cumsum()
计算累积值。最后,我们使用plt.plot()
函数绘制累积直方图。
3.2 归一化的手动累积直方图
如果我们想要绘制归一化的累积直方图,可以对累积值进行归一化处理:
import matplotlib.pyplot as plt
import numpy as np
# 生成示例数据
data = np.random.gamma(2, 2, 1000)
# 计算直方图数据
counts, bin_edges = np.histogram(data, bins=50)
# 计算累积值并归一化
cumulative = np.cumsum(counts)
cumulative_normalized = cumulative / cumulative[-1]
# 绘制归一化的累积直方图
plt.plot(bin_edges[1:], cumulative_normalized,
label='Normalized Cumulative - how2matplotlib.com')
# 设置图表标题和标签
plt.title('Normalized Manual Cumulative Histogram')
plt.xlabel('Value')
plt.ylabel('Cumulative Frequency')
plt.legend()
# 设置y轴范围
plt.ylim(0, 1.1)
# 显示图表
plt.show()
Output:
在这个示例中,我们使用了gamma分布的数据,并通过除以最后一个累积值来归一化累积频率。
4. 比较多个累积直方图
在某些情况下,我们可能需要在同一图表中比较多个累积直方图。这可以通过多次调用plt.hist()
或plt.plot()
函数来实现。
import matplotlib.pyplot as plt
import numpy as np
# 生成示例数据
data1 = np.random.normal(0, 1, 1000)
data2 = np.random.normal(2, 1.5, 1000)
# 创建累积直方图
plt.hist(data1, bins=30, cumulative=True, density=True,
histtype='step', label='Data 1 - how2matplotlib.com')
plt.hist(data2, bins=30, cumulative=True, density=True,
histtype='step', label='Data 2 - how2matplotlib.com')
# 设置图表标题和标签
plt.title('Comparison of Cumulative Histograms')
plt.xlabel('Value')
plt.ylabel('Cumulative Frequency')
plt.legend()
# 显示图表
plt.show()
Output:
这个示例展示了如何在同一图表中比较两个不同正态分布的累积直方图。
5. 累积直方图与概率密度函数的结合
累积直方图可以与概率密度函数(PDF)结合使用,以提供更全面的数据分布视图。
import matplotlib.pyplot as plt
import numpy as np
from scipy import stats
# 生成示例数据
data = np.random.normal(0, 1, 1000)
# 创建子图
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(8, 10))
# 绘制概率密度函数
x = np.linspace(-4, 4, 100)
pdf = stats.norm.pdf(x, 0, 1)
ax1.plot(x, pdf, label='PDF - how2matplotlib.com')
ax1.hist(data, bins=30, density=True, alpha=0.7, label='Histogram')
ax1.set_title('Probability Density Function')
ax1.set_xlabel('Value')
ax1.set_ylabel('Density')
ax1.legend()
# 绘制累积直方图
ax2.hist(data, bins=30, cumulative=True, density=True,
histtype='step', label='Cumulative - how2matplotlib.com')
ax2.set_title('Cumulative Histogram')
ax2.set_xlabel('Value')
ax2.set_ylabel('Cumulative Frequency')
ax2.legend()
# 调整子图间距
plt.tight_layout()
# 显示图表
plt.show()
Output:
这个示例展示了如何将概率密度函数和累积直方图结合在一起,以提供数据分布的完整视图。
6. 累积直方图的应用场景
累积直方图在多个领域都有广泛的应用,以下是一些常见的应用场景:
6.1 金融分析
在金融分析中,累积直方图可以用来分析投资回报的分布。以下是一个简单的示例:
import matplotlib.pyplot as plt
import numpy as np
# 生成示例数据:模拟每日投资回报率
returns = np.random.normal(0.001, 0.02, 252) # 252个交易日
# 计算累积回报
cumulative_returns = np.cumprod(1 + returns) - 1
# 创建累积直方图
plt.hist(cumulative_returns, bins=30, cumulative=True, density=True,
histtype='step', label='Cumulative Returns - how2matplotlib.com')
# 设置图表标题和标签
plt.title('Cumulative Distribution of Investment Returns')
plt.xlabel('Cumulative Return')
plt.ylabel('Probability')
plt.legend()
# 显示图表
plt.show()
Output:
这个示例展示了如何使用累积直方图来分析投资回报的分布情况。
6.2 质量控制
在制造业中,累积直方图可以用于质量控制,分析产品尺寸或重量的分布。以下是一个示例:
import matplotlib.pyplot as plt
import numpy as np
# 生成示例数据:模拟产品重量
weights = np.random.normal(100, 2, 1000) # 平均100克,标准差2克
# 创建累积直方图
plt.hist(weights, bins=30, cumulative=True, density=True,
histtype='step', label='Product Weights - how2matplotlib.com')
# 添加规格限制线
plt.axvline(98, color='r', linestyle='--', label='Lower Limit')
plt.axvline(102, color='r', linestyle='--', label='Upper Limit')
# 设置图表标题和标签
plt.title('Cumulative Distribution of Product Weights')
plt.xlabel('Weight (g)')
plt.ylabel('Cumulative Probability')
plt.legend()
# 显示图表
plt.show()
Output:
这个示例展示了如何使用累积直方图来分析产品重量的分布,并添加规格限制线。
7. 累积直方图的进阶技巧
7.1 添加百分位线
在某些情况下,我们可能需要在累积直方图上添加百分位线,以便更好地理解数据分布。
import matplotlib.pyplot as plt
import numpy as np
# 生成示例数据
data = np.random.lognormal(0, 0.5, 1000)
# 计算百分位数
percentiles = [25, 50, 75]
percentile_values = np.percentile(data, percentiles)
# 创建累积直方图
plt.hist(data, bins=50, cumulative=True, density=True,
histtype='step', label='Cumulative - how2matplotlib.com')
# 添加百分位线
for p, v in zip(percentiles, percentile_values):
plt.axvline(v, color='r', linestyle='--',
label=f'{p}th Percentile - how2matplotlib.com')
# 设置图表标题和标签
plt.title('Cumulative Histogram with Percentile Lines')
plt.xlabel('Value')
plt.ylabel('Cumulative Frequency')
plt.legend()
# 显示图表
plt.show()
Output:
这个示例展示了如何在累积直方图上添加25%、50%和75%的百分位线。
7.2 对数刻度
对于跨越多个数量级的数据,使用对数刻度可能会更有帮助:
import matplotlib.pyplot as plt
import numpy as np
# 生成示例数据
data = np.random.lognormal(0, 1, 10000)
# 创建累积直方图
plt.hist(data, bins=100, cumulative=True, density=True,
histtype='step', label='Cumulative - how2matplotlib.com')
# 设置对数刻度
plt.xscale('log')
# 设置图表标题和标签
plt.title('Cumulative Histogram with Log Scale')
plt.xlabel('Value (log scale)')
plt.ylabel('Cumulative Frequency')
plt.legend()
# 显示图表
plt.show()
Output:
这个示例展示了如何在x轴使用对数刻度来展示跨越多个数量级的数据分布。
7.3 双y轴累积直方图
有时我们可能需要同时显示累积频率和原始频率,这可以通过创建双y轴图表来实现:
import matplotlib.pyplot as plt
import numpy as np
# 生成示例数据
data = np.random.normal(0, 1, 1000)
# 创建图表和主y轴
fig, ax1 = plt.subplots()
# 绘制原始直方图
n, bins, patches = ax1.hist(data, bins=30, density=True, alpha=0.7,
label='Histogram - how2matplotlib.com')
# 创建次y轴
ax2 = ax1.twinx()
# 绘制累积直方图
ax2.hist(data, bins=30, cumulative=True, density=True,
histtype='step', color='r', label='Cumulative - how2matplotlib.com')
# 设置图表标题和标签
ax1.set_title('Histogram and Cumulative Histogram')
ax1.set_xlabel('Value')
ax1.set_ylabel('Frequency')
ax2.set_ylabel('Cumulative Frequency')
# 添加图例
ax1.legend(loc='upper left')
ax2.legend(loc='lower right')
# 显示图表
plt.show()
Output:
这个示例展示了如何创建一个双y轴图表,同时显示原始直方图和累积直方图。
8. 累积直方图的性能优化
当处理大量数据时,创建累积直方图可能会变得计算密集。以下是一些优化技巧:
8.1 使用numpy的累积和函数
对于大型数据集,使用numpy的累积和函数可能比matplotlib的内置方法更快:
import matplotlib.pyplot as plt
import numpy as np
# 生成大量示例数据
data = np.random.normal(0, 1, 1000000)
# 计算直方图数据
counts, bin_edges = np.histogram(data, bins=100)
# 计算累积和
cumulative = np.cumsum(counts)
# 绘制累积直方图
plt.plot(bin_edges[1:], cumulative / len(data),
label='Optimized Cumulative - how2matplotlib.com')
# 设置图表标题和标签
plt.title('Optimized Cumulative Histogram for Large Datasets')
plt.xlabel('Value')
plt.ylabel('Cumulative Frequency')
plt.legend()
# 显示图表
plt.show()
Output:
这个方法通过手动计算累积和来优化大型数据集的处理。
8.2 数据降采样
对于非常大的数据集,可以考虑在绘图之前进行降采样:
import matplotlib.pyplot as plt
import numpy as np
# 生成大量示例数据
data = np.random.normal(0, 1, 10000000)
# 降采样
sample_size = 100000
sampled_data = np.random.choice(data, sample_size, replace=False)
# 创建累积直方图
plt.hist(sampled_data, bins=100, cumulative=True, density=True,
histtype='step', label='Sampled Cumulative - how2matplotlib.com')
# 设置图表标题和标签
plt.title('Cumulative Histogram with Data Sampling')
plt.xlabel('Value')
plt.ylabel('Cumulative Frequency')
plt.legend()
# 显示图表
plt.show()
Output:
这个示例展示了如何通过随机抽样来减少数据量,从而提高绘图性能。
9. 累积直方图的美化和定制
为了使累积直方图更具可读性和吸引力,我们可以进行一些美化和定制:
9.1 使用自定义颜色和样式
import matplotlib.pyplot as plt
import numpy as np
# 生成示例数据
data = np.random.normal(0, 1, 1000)
# 创建累积直方图
plt.hist(data, bins=30, cumulative=True, density=True,
histtype='step', linewidth=2, color='#FF5733',
label='Cumulative - how2matplotlib.com')
# 设置图表样式
plt.style.use('seaborn')
# 设置图表标题和标签
plt.title('Stylized Cumulative Histogram', fontsize=16, fontweight='bold')
plt.xlabel('Value', fontsize=12)
plt.ylabel('Cumulative Frequency', fontsize=12)
plt.legend(fontsize=10)
# 自定义背景和网格
plt.gca().set_facecolor('#F0F0F0')
plt.grid(True, linestyle='--', alpha=0.7)
# 显示图表
plt.show()
这个示例展示了如何使用自定义颜色、线条样式和背景来美化累积直方图。
9.2 添加注释和标记
在某些情况下,我们可能想要在图表上添加注释或标记特定点:
import matplotlib.pyplot as plt
import numpy as np
# 生成示例数据
data = np.random.normal(0, 1, 1000)
# 创建累积直方图
n, bins, patches = plt.hist(data, bins=30, cumulative=True, density=True,
histtype='step', label='Cumulative - how2matplotlib.com')
# 找到中位数
median_index = np.searchsorted(n, 0.5)
median_value = bins[median_index]
# 添加中位数标记
plt.axvline(median_value, color='r', linestyle='--', label='Median')
plt.annotate(f'Median: {median_value:.2f}',
xy=(median_value, 0.5), xytext=(median_value+0.5, 0.6),
arrowprops=dict(facecolor='black', shrink=0.05))
# 设置图表标题和标签
plt.title('Cumulative Histogram with Annotations')
plt.xlabel('Value')
plt.ylabel('Cumulative Frequency')
plt.legend()
# 显示图表
plt.show()
Output:
这个示例展示了如何在累积直方图上添加中位数线和注释。
10. 累积直方图在数据分析中的应用
累积直方图在数据分析中有多种应用,以下是一些具体的例子:
10.1 分析响应时间分布
在Web性能分析中,累积直方图可以用来分析页面加载时间的分布:
import matplotlib.pyplot as plt
import numpy as np
# 模拟页面加载时间数据(单位:秒)
load_times = np.random.lognormal(0, 0.5, 1000)
# 创建累积直方图
plt.hist(load_times, bins=50, cumulative=True, density=True,
histtype='step', label='Load Times - how2matplotlib.com')
# 添加性能目标线
plt.axhline(0.9, color='r', linestyle='--', label='90% Target')
plt.axvline(3, color='g', linestyle='--', label='3s Threshold')
# 设置图表标题和标签
plt.title('Cumulative Distribution of Page Load Times')
plt.xlabel('Load Time (seconds)')
plt.ylabel('Cumulative Probability')
plt.legend()
# 显示图表
plt.show()
Output:
这个示例展示了如何使用累积直方图来分析页面加载时间的分布,并添加性能目标线。
10.2 比较不同组的数据分布
累积直方图也可以用来比较不同组或类别的数据分布:
import matplotlib.pyplot as plt
import numpy as np
# 生成两组示例数据
group1 = np.random.normal(0, 1, 1000)
group2 = np.random.normal(0.5, 1.2, 1000)
# 创建累积直方图
plt.hist(group1, bins=30, cumulative=True, density=True,
histtype='step', label='Group 1 - how2matplotlib.com')
plt.hist(group2, bins=30, cumulative=True, density=True,
histtype='step', label='Group 2 - how2matplotlib.com')
# 设置图表标题和标签
plt.title('Comparison of Data Distributions')
plt.xlabel('Value')
plt.ylabel('Cumulative Frequency')
plt.legend()
# 显示图表
plt.show()
Output:
这个示例展示了如何使用累积直方图来比较两个不同组的数据分布。
结论
累积直方图是一种强大的数据可视化工具,可以帮助我们更好地理解数据的分布和累积特性。通过Matplotlib库,我们可以轻松创建各种类型的累积直方图,并进行自定义和优化。无论是在金融分析、质量控制还是性能评估等领域,累积直方图都能提供有价值的洞察。
本文详细介绍了如何在Matplotlib中创建累积直方图,包括基本用法、手动计算方法、多图比较、与其他图表的结合、应用场景、进阶技巧以及性能优化等方面。通过掌握这些技巧,你将能够更有效地利用累积直方图进行数据分析和可视化。