You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Matplotlib实现68-95-99.7法则的正态分布可视化标注?

实现正态分布68-95-99.7法则的Matplotlib可视化

问题描述

我已经用Matplotlib绘制了正态分布图表:

import matplotlib.pyplot as plt
import numpy as np
import math

fig, ax = plt.subplots()
ax.set_title('概率密度分布')
ax.set_xlabel('x')
ax.set_ylabel('f(x)')
x = np.linspace(148, 200, 100) # X范围148到200
y = (1 / (5 * math.sqrt(2*math.pi))) * np.exp((-(x-178)**2) / (2*5**2))
ax.plot(x, y)
plt.show()

现在需要在绘图区域内添加竖线、为内部区间着色,并在y=0的轴上添加对应标记。尝试用plt.axvline时,竖线会超出主绘图区域:

plt.axvline(x = 178, color = 'g', label = 'axvline - full height')
plt.axvline(x = 178+5, color = 'b', label = 'axvline - full height')
plt.axvline(x = 178-5, color = 'b', label = 'axvline - full height')
plt.axvline(x = 178+5*2, color = 'r', label = 'axvline - full height')
plt.axvline(x = 178-5*2, color = 'r', label = 'axvline - full height')

请问如何用Python的Matplotlib实现所需的68-95-99.7法则可视化效果?

解决方案

1. 控制竖线高度,避免超出绘图区域

axvline默认贯穿整个轴范围,要让竖线只到曲线高度,可直接用ax.plot绘制从(x值, 0)到(x值, 对应曲线y值)的线段,精准匹配曲线高度。

2. 为区间分层着色

用ax.fill_between函数为不同σ区间填充颜色,从最外层(±3σ)到最内层(±1σ)依次绘制,通过透明度区分层次,保证视觉上的叠加效果。

3. 添加x轴标记

在x轴下方对应σ位置添加LaTeX格式的数学标记,调整y坐标避免遮挡曲线,让标注更规范清晰。

完整实现代码

import matplotlib.pyplot as plt
import numpy as np
import math

# 正态分布核心参数
mu = 178
sigma = 5
x = np.linspace(148, 200, 100)
y = (1 / (sigma * math.sqrt(2*math.pi))) * np.exp((-(x - mu)**2) / (2*sigma**2))

fig, ax = plt.subplots(figsize=(10, 6))
ax.set_title('概率密度分布(68-95-99.7法则)')
ax.set_xlabel('x')
ax.set_ylabel('f(x)')
ax.plot(x, y, color='black', linewidth=2)

# 定义各区间的范围、填充色和透明度
intervals = [
    (mu - 3*sigma, mu + 3*sigma, '#ffcccc', 0.2),  # ±3σ 区间
    (mu - 2*sigma, mu + 2*sigma, '#cceeff', 0.3),  # ±2σ 区间
    (mu - sigma, mu + sigma, '#ccffcc', 0.4)       # ±1σ 区间
]

# 分层填充区间
for x_left, x_right, color, alpha in intervals:
    ax.fill_between(x, y, where=(x >= x_left) & (x <= x_right), color=color, alpha=alpha)

# 定义函数获取对应x值的曲线y高度
def get_curve_y(x_val):
    return (1 / (sigma * math.sqrt(2*math.pi))) * math.exp((-(x_val - mu)**2) / (2*sigma**2))

# 绘制均值线(绿色)
mu_y = get_curve_y(mu)
ax.plot([mu, mu], [0, mu_y], color='green', linestyle='--', linewidth=2)

# 绘制±1σ线(蓝色)
sigma1_y = get_curve_y(mu + sigma)
ax.plot([mu-sigma, mu-sigma], [0, sigma1_y], color='blue', linestyle='--', linewidth=1.5)
ax.plot([mu+sigma, mu+sigma], [0, sigma1_y], color='blue', linestyle='--', linewidth=1.5)

# 绘制±2σ线(红色)
sigma2_y = get_curve_y(mu + 2*sigma)
ax.plot([mu-2*sigma, mu-2*sigma], [0, sigma2_y], color='red', linestyle='--', linewidth=1.5)
ax.plot([mu+2*sigma, mu+2*sigma], [0, sigma2_y], color='red', linestyle='--', linewidth=1.5)

# 绘制±3σ线(深红色)
sigma3_y = get_curve_y(mu + 3*sigma)
ax.plot([mu-3*sigma, mu-3*sigma], [0, sigma3_y], color='#8b0000', linestyle='--', linewidth=1)
ax.plot([mu+3*sigma, mu+3*sigma], [0, sigma3_y], color='#8b0000', linestyle='--', linewidth=1)

# 添加x轴标记
ax.text(mu, -0.002, r'$\mu$', ha='center', fontsize=12)
ax.text(mu-sigma, -0.002, r'$\mu-\sigma$', ha='center', fontsize=12)
ax.text(mu+sigma, -0.002, r'$\mu+\sigma$', ha='center', fontsize=12)
ax.text(mu-2*sigma, -0.002, r'$\mu-2\sigma$', ha='center', fontsize=12)
ax.text(mu+2*sigma, -0.002, r'$\mu+2\sigma$', ha='center', fontsize=12)
ax.text(mu-3*sigma, -0.002, r'$\mu-3\sigma$', ha='center', fontsize=12)
ax.text(mu+3*sigma, -0.002, r'$\mu+3\sigma$', ha='center', fontsize=12)

# 调整y轴下限,避免标记被截断
ax.set_ylim(bottom=-0.005)

plt.show()

效果说明

  • 竖线精准贴合曲线高度,不会超出绘图区域
  • 区间填充从外到内叠加,层次清晰,符合68-95-99.7的概率占比逻辑
  • x轴标记规范直观,不会遮挡曲线内容

内容的提问来源于stack exchange,提问作者Nadezhda GR

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 06:06:45