Matplotlib绘制总高度为1的直方图:完整教程与实例

Matplotlib绘制总高度为1的直方图:完整教程与实例

参考:Plotting a Histogram with Total Height Equal to 1

在数据可视化中,直方图是一种常用的图表类型,用于展示数据的分布情况。通常情况下,直方图的高度表示频数或频率,但有时我们需要将直方图的总高度标准化为1,这种做法在概率密度函数的可视化中特别有用。本文将详细介绍如何使用Matplotlib库绘制总高度为1的直方图,并提供多个实用示例。

1. 为什么要绘制总高度为1的直方图?

在统计学和数据分析中,将直方图的总高度标准化为1有几个重要原因:

  1. 概率密度函数表示:标准化后的直方图可以直观地表示概率密度函数,使得不同样本量的数据集更容易比较。

  2. 数据归一化:当处理不同尺度或单位的数据时,标准化可以使结果更具可比性。

  3. 相对频率表示:总高度为1的直方图可以直接反映每个区间的相对频率。

  4. 理论分布拟合:在拟合理论分布时,标准化的直方图更容易与理论密度函数进行比较。

让我们通过一个简单的例子来说明如何绘制总高度为1的直方图:

import numpy as np
import matplotlib.pyplot as plt

# 生成示例数据
data = np.random.normal(0, 1, 1000)

# 绘制总高度为1的直方图
plt.hist(data, bins=30, density=True)
plt.title('How2matplotlib.com: Total Height = 1 Histogram')
plt.xlabel('Value')
plt.ylabel('Density')
plt.show()

Output:

Matplotlib绘制总高度为1的直方图:完整教程与实例

在这个例子中,我们使用density=True参数来绘制总高度为1的直方图。这个参数告诉Matplotlib将直方图的高度标准化,使得所有柱子的总面积等于1。

2. 使用Matplotlib绘制总高度为1的直方图的基本步骤

要使用Matplotlib绘制总高度为1的直方图,主要有以下几个步骤:

  1. 导入必要的库(numpy和matplotlib.pyplot)
  2. 准备数据
  3. 使用plt.hist()函数绘制直方图,设置density=True
  4. 设置图表标题、坐标轴标签等
  5. 显示或保存图表

让我们通过一个更详细的例子来说明这些步骤:

import numpy as np
import matplotlib.pyplot as plt

# 准备数据
np.random.seed(42)
data = np.random.exponential(scale=2, size=1000)

# 绘制总高度为1的直方图
plt.figure(figsize=(10, 6))
plt.hist(data, bins=30, density=True, alpha=0.7, color='skyblue', edgecolor='black')

# 设置图表标题和标签
plt.title('How2matplotlib.com: Exponential Distribution (Total Height = 1)', fontsize=16)
plt.xlabel('Value', fontsize=12)
plt.ylabel('Density', fontsize=12)

# 添加网格线
plt.grid(True, linestyle='--', alpha=0.7)

# 显示图表
plt.show()

Output:

Matplotlib绘制总高度为1的直方图:完整教程与实例

在这个例子中,我们生成了一个指数分布的数据集,并使用density=True参数绘制了总高度为1的直方图。我们还添加了一些额外的样式设置,如颜色、边框和网格线,以增强图表的可读性。

3. 自定义直方图的外观

Matplotlib提供了多种方法来自定义直方图的外观。以下是一些常用的自定义选项:

3.1 调整柱子的颜色和透明度

import numpy as np
import matplotlib.pyplot as plt

data = np.random.normal(0, 1, 1000)

plt.hist(data, bins=30, density=True, color='lightgreen', alpha=0.8, edgecolor='darkgreen')
plt.title('How2matplotlib.com: Customized Histogram Color')
plt.xlabel('Value')
plt.ylabel('Density')
plt.show()

Output:

Matplotlib绘制总高度为1的直方图:完整教程与实例

在这个例子中,我们使用color参数设置柱子的填充颜色,alpha参数调整透明度,edgecolor参数设置边框颜色。

3.2 使用不同的柱子样式

import numpy as np
import matplotlib.pyplot as plt

data = np.random.normal(0, 1, 1000)

plt.hist(data, bins=30, density=True, histtype='step', linewidth=2, color='purple')
plt.title('How2matplotlib.com: Step Histogram')
plt.xlabel('Value')
plt.ylabel('Density')
plt.show()

Output:

Matplotlib绘制总高度为1的直方图:完整教程与实例

这个例子展示了如何使用histtype='step'参数来绘制只有轮廓的直方图。

3.3 调整柱子的宽度

import numpy as np
import matplotlib.pyplot as plt

data = np.random.normal(0, 1, 1000)

plt.hist(data, bins=30, density=True, rwidth=0.8, color='orange')
plt.title('How2matplotlib.com: Adjusted Bar Width')
plt.xlabel('Value')
plt.ylabel('Density')
plt.show()

Output:

Matplotlib绘制总高度为1的直方图:完整教程与实例

使用rwidth参数可以调整柱子的相对宽度,取值范围为0到1。

4. 在同一图表中比较多个数据集

有时我们需要在同一个图表中比较多个数据集的分布。Matplotlib允许我们轻松地实现这一点:

import numpy as np
import matplotlib.pyplot as plt

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

plt.hist(data1, bins=30, density=True, alpha=0.7, label='Dataset 1')
plt.hist(data2, bins=30, density=True, alpha=0.7, label='Dataset 2')
plt.title('How2matplotlib.com: Comparing Two Datasets')
plt.xlabel('Value')
plt.ylabel('Density')
plt.legend()
plt.show()

Output:

Matplotlib绘制总高度为1的直方图:完整教程与实例

在这个例子中,我们绘制了两个不同的正态分布数据集,并使用不同的颜色和标签来区分它们。

5. 添加核密度估计曲线

核密度估计(KDE)是一种非参数方法,用于估计随机变量的概率密度函数。我们可以将KDE曲线添加到直方图上,以提供更平滑的分布估计:

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

data = np.random.normal(0, 1, 1000)

plt.hist(data, bins=30, density=True, alpha=0.7, color='lightblue', edgecolor='black')

kde = gaussian_kde(data)
x_range = np.linspace(data.min(), data.max(), 100)
plt.plot(x_range, kde(x_range), 'r-', linewidth=2)

plt.title('How2matplotlib.com: Histogram with KDE')
plt.xlabel('Value')
plt.ylabel('Density')
plt.show()

Output:

Matplotlib绘制总高度为1的直方图:完整教程与实例

这个例子展示了如何使用scipy的gaussian_kde函数计算KDE,并将其绘制在直方图上。

6. 使用不同的分箱方法

分箱(binning)是直方图绘制中的一个重要概念。Matplotlib提供了多种分箱方法:

import numpy as np
import matplotlib.pyplot as plt

data = np.random.normal(0, 1, 1000)

fig, axs = plt.subplots(2, 2, figsize=(12, 10))
axs = axs.ravel()

bin_methods = ['auto', 'sturges', 'scott', 'fd']

for i, method in enumerate(bin_methods):
    axs[i].hist(data, bins=method, density=True)
    axs[i].set_title(f'How2matplotlib.com: {method.capitalize()} Binning')
    axs[i].set_xlabel('Value')
    axs[i].set_ylabel('Density')

plt.tight_layout()
plt.show()

Output:

Matplotlib绘制总高度为1的直方图:完整教程与实例

这个例子展示了四种不同的分箱方法:’auto’、’sturges’、’scott’和’fd’(Freedman-Diaconis)。

7. 添加累积分布函数

累积分布函数(CDF)是概率论和统计学中的一个重要概念。我们可以在直方图旁边添加CDF:

import numpy as np
import matplotlib.pyplot as plt

data = np.random.normal(0, 1, 1000)

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

ax1.hist(data, bins=30, density=True)
ax1.set_title('How2matplotlib.com: Histogram')
ax1.set_xlabel('Value')
ax1.set_ylabel('Density')

ax2.hist(data, bins=30, density=True, cumulative=True)
ax2.set_title('How2matplotlib.com: Cumulative Distribution')
ax2.set_xlabel('Value')
ax2.set_ylabel('Cumulative Density')

plt.tight_layout()
plt.show()

Output:

Matplotlib绘制总高度为1的直方图:完整教程与实例

在这个例子中,我们使用cumulative=True参数来绘制累积分布函数。

8. 处理大数据集

当处理大数据集时,可能需要调整直方图的绘制方式以提高效率:

import numpy as np
import matplotlib.pyplot as plt

# 生成大数据集
data = np.random.normal(0, 1, 1000000)

plt.hist(data, bins=100, density=True, histtype='step')
plt.title('How2matplotlib.com: Large Dataset Histogram')
plt.xlabel('Value')
plt.ylabel('Density')
plt.show()

Output:

Matplotlib绘制总高度为1的直方图:完整教程与实例

对于大数据集,使用histtype='step'可以加快绘图速度并减少内存使用。

9. 添加理论分布曲线

在数据分析中,我们经常需要将实际数据与理论分布进行比较:

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

data = np.random.normal(0, 1, 1000)

plt.hist(data, bins=30, density=True, alpha=0.7)

x = np.linspace(-4, 4, 100)
plt.plot(x, norm.pdf(x, 0, 1), 'r-', lw=2)

plt.title('How2matplotlib.com: Histogram with Normal Distribution')
plt.xlabel('Value')
plt.ylabel('Density')
plt.show()

Output:

Matplotlib绘制总高度为1的直方图:完整教程与实例

这个例子展示了如何将标准正态分布的理论曲线添加到直方图上。

10. 使用对数刻度

对于跨越多个数量级的数据,使用对数刻度可能会更有帮助:

import numpy as np
import matplotlib.pyplot as plt

data = np.random.lognormal(0, 1, 1000)

plt.hist(data, bins=30, density=True)
plt.xscale('log')
plt.title('How2matplotlib.com: Histogram with Log Scale')
plt.xlabel('Value (log scale)')
plt.ylabel('Density')
plt.show()

Output:

Matplotlib绘制总高度为1的直方图:完整教程与实例

这个例子展示了如何使用对数刻度来绘制对数正态分布的直方图。

11. 2D直方图

对于二维数据,我们可以绘制2D直方图:

import numpy as np
import matplotlib.pyplot as plt

x = np.random.normal(0, 1, 1000)
y = np.random.normal(0, 1, 1000)

plt.hist2d(x, y, bins=30, density=True)
plt.colorbar(label='Density')
plt.title('How2matplotlib.com: 2D Histogram')
plt.xlabel('X Value')
plt.ylabel('Y Value')
plt.show()

Output:

Matplotlib绘制总高度为1的直方图:完整教程与实例

这个例子展示了如何使用plt.hist2d()函数绘制二维直方图。

12. 使用不同的归一化方法

Matplotlib提供了多种归一化方法来计算直方图的高度:

import numpy as np
import matplotlib.pyplot as plt

data = np.random.normal(0, 1, 1000)

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

ax1.hist(data, bins=30, density=True)
ax1.set_title('How2matplotlib.com: Density Normalization')
ax1.set_xlabel('Value')
ax1.set_ylabel('Density')

ax2.hist(data, bins=30, weights=np.ones_like(data)/len(data))
ax2.set_title('How2matplotlib.com: Manual Normalization')
ax2.set_xlabel('Value')
ax2.set_ylabel('Frequency')

plt.tight_layout()
plt.show()

Output:

Matplotlib绘制总高度为1的直方图:完整教程与实例

这个例子展示了使用density=True和手动计算权重两种方法来实现总高度为1的直方图。

13. 堆叠直方图

堆叠直方图可以用来比较多个类别的分布:

import numpy as np
import matplotlib.pyplot as plt

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

plt.hist([data1, data2, data3], bins=30, density=True, stacked=True, label=['Data 1', 'Data 2', 'Data 3'])
plt.title('How2matplotlib.com: Stacked Histogram')
plt.xlabel('Value')
plt.ylabel('Density')
plt.legend()
plt.show()

Output:

Matplotlib绘制总高度为1的直方图:完整教程与实例

这个例子展示了如何使用stacked=True参数来创建堆叠直方图。

14. 使用面向对象的方法

虽然我们在之前的例子中主要使用了pyplot接口,但Matplotlib也支持面向对象的方法来创建和自定义图表:

import numpy as np
import matplotlib.pyplot as plt

data = np.random.normal(0, 1, 1000)

fig, ax = plt.subplots(figsize=(10, 6))

ax.hist(data, bins=30, density=True, alpha=0.7, color='skyblue', edgecolor='black')
ax.set_title('How2matplotlib.com: Object-Oriented Histogram')
ax.set_xlabel('Value')
ax.set_ylabel('Density')
ax.grid(True, linestyle='--', alpha=0.7)

plt.show()

Output:

Matplotlib绘制总高度为1的直方图:完整教程与实例

这种方法给予我们更多的控制权,特别是在创建复杂的图表布局时。

15. 自定义刻度和标签

有时我们可能需要自定义坐标轴的刻度和标签:

import numpy as np
import matplotlib.pyplot as plt

data = np.random.normal(0, 1, 1000)

fig, ax = plt.subplots(figsize=(10, 6))

ax.hist(data, bins=30, density=True)
ax.set_title('How2matplotlib.com: Custom Ticks and Labels')
ax.set_xlabel('Value')
ax.set_ylabel('Density')

# 自定义x轴刻度和标签
ax.set_xticks(np.arange(-3, 4, 1))
ax.set_xticklabels(['Low', 'Medium-Low', 'Low-Medium', 'Medium', 'Medium-High', 'High-Medium', 'High'])

# 旋转x轴标签
plt.setp(ax.get_xticklabels(), rotation=45, ha='right')

plt.tight_layout()
plt.show()

Output:

Matplotlib绘制总高度为1的直方图:完整教程与实例

这个例子展示了如何自定义x轴的刻度和标签,并旋转标签以避免重叠。

16. 添加统计信息

在直方图上添加一些基本的统计信息可以提供更多的数据洞察:

import numpy as np
import matplotlib.pyplot as plt

data = np.random.normal(0, 1, 1000)

fig, ax = plt.subplots(figsize=(10, 6))

ax.hist(data, bins=30, density=True)
ax.set_title('How2matplotlib.com: Histogram with Statistics')
ax.set_xlabel('Value')
ax.set_ylabel('Density')

# 添加统计信息
mean = np.mean(data)
std = np.std(data)
ax.axvline(mean, color='r', linestyle='dashed', linewidth=2)
ax.text(mean*1.1, ax.get_ylim()[1]*0.9, f'Mean: {mean:.2f}\nStd: {std:.2f}', 
        bbox=dict(facecolor='white', alpha=0.5))

plt.show()

Output:

Matplotlib绘制总高度为1的直方图:完整教程与实例

这个例子展示了如何在直方图上添加均值线和文本框,显示均值和标准差。

17. 使用不同的颜色映射

对于2D直方图或需要表示额外维度的情况,使用不同的颜色映射可以提供更丰富的信息:

import numpy as np
import matplotlib.pyplot as plt

x = np.random.normal(0, 1, 1000)
y = x + np.random.normal(0, 0.5, 1000)

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

h1 = ax1.hist2d(x, y, bins=30, density=True, cmap='viridis')
ax1.set_title('How2matplotlib.com: 2D Histogram (Viridis)')
ax1.set_xlabel('X Value')
ax1.set_ylabel('Y Value')
fig.colorbar(h1[3], ax=ax1, label='Density')

h2 = ax2.hist2d(x, y, bins=30, density=True, cmap='plasma')
ax2.set_title('How2matplotlib.com: 2D Histogram (Plasma)')
ax2.set_xlabel('X Value')
ax2.set_ylabel('Y Value')
fig.colorbar(h2[3], ax=ax2, label='Density')

plt.tight_layout()
plt.show()

Output:

Matplotlib绘制总高度为1的直方图:完整教程与实例

这个例子展示了如何使用不同的颜色映射(colormap)来绘制2D直方图。

18. 处理离群值

在实际数据中,离群值可能会影响直方图的可读性。我们可以通过设置合适的范围来处理这个问题:

import numpy as np
import matplotlib.pyplot as plt

data = np.random.normal(0, 1, 1000)
data = np.append(data, [10, -10])  # 添加一些离群值

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

ax1.hist(data, bins=30, density=True)
ax1.set_title('How2matplotlib.com: With Outliers')
ax1.set_xlabel('Value')
ax1.set_ylabel('Density')

ax2.hist(data, bins=30, density=True, range=(-3, 3))
ax2.set_title('How2matplotlib.com: Without Outliers')
ax2.set_xlabel('Value')
ax2.set_ylabel('Density')

plt.tight_layout()
plt.show()

Output:

Matplotlib绘制总高度为1的直方图:完整教程与实例

这个例子展示了如何使用range参数来限制直方图的范围,从而排除离群值的影响。

19. 使用不同的直方图类型

Matplotlib提供了多种直方图类型,每种类型都有其特定的用途:

import numpy as np
import matplotlib.pyplot as plt

data = np.random.normal(0, 1, 1000)

fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2, figsize=(12, 10))

ax1.hist(data, bins=30, density=True, histtype='bar', alpha=0.7)
ax1.set_title('How2matplotlib.com: Bar Histogram')

ax2.hist(data, bins=30, density=True, histtype='step')
ax2.set_title('How2matplotlib.com: Step Histogram')

ax3.hist(data, bins=30, density=True, histtype='stepfilled', alpha=0.7)
ax3.set_title('How2matplotlib.com: Stepfilled Histogram')

ax4.hist(data, bins=30, density=True, histtype='barstacked')
ax4.set_title('How2matplotlib.com: Barstacked Histogram')

for ax in (ax1, ax2, ax3, ax4):
    ax.set_xlabel('Value')
    ax.set_ylabel('Density')

plt.tight_layout()
plt.show()

Output:

Matplotlib绘制总高度为1的直方图:完整教程与实例

这个例子展示了四种不同的直方图类型:bar、step、stepfilled和barstacked。

20. 结合其他图表类型

直方图可以与其他类型的图表结合,以提供更全面的数据视图:

import numpy as np
import matplotlib.pyplot as plt

data = np.random.normal(0, 1, 1000)

fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(10, 10), sharex=True, 
                               gridspec_kw={'height_ratios': [3, 1]})

ax1.hist(data, bins=30, density=True)
ax1.set_title('How2matplotlib.com: Histogram with Box Plot')
ax1.set_ylabel('Density')

ax2.boxplot(data, vert=False)
ax2.set_xlabel('Value')

plt.tight_layout()
plt.show()

Output:

Matplotlib绘制总高度为1的直方图:完整教程与实例

这个例子展示了如何将直方图与箱线图结合,提供数据分布的不同视角。

总结起来,Matplotlib提供了丰富的工具和选项来创建和自定义总高度为1的直方图。通过调整各种参数,我们可以创建既美观又信息丰富的数据可视化。无论是简单的数据分布展示,还是复杂的多数据集比较,Matplotlib都能满足各种需求。在实际应用中,选择合适的直方图类型和设置对于有效传达数据信息至关重要。通过实践和探索,你可以掌握使用Matplotlib创建精确、美观的直方图的技巧,从而更好地理解和展示你的数据。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程