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

如何绘制二维NumPy数组列表的Matplotlib概率质量函数(PMF)?

正确绘制已计算好的PMF的方法

你遇到的问题很典型:plt.hist()是用来生成直方图的,它会自动对数据进行区间分组并计算频数/频率,而你已经手动计算出了每个离散取值对应的精确概率(也就是PMF),所以直接用直方图肯定和你的预期结果不符。

针对你已经得到的二维NumPy数组格式的PMF(第一列是离散取值,第二列是对应概率),应该用**条形图(bar)或者阶梯图(step)**来绘制,这两种方式更适合展示离散概率分布。

方法一:单场景PMF绘制

如果只需要绘制单个场景的PMF,代码可以这么写:

import matplotlib.pyplot as plt
import numpy as np

# 用你给出的示例PMF数组来测试
sample_pmf = np.array([
    [0.00000000e+00, 1.91734780e-01],
    [1.00000000e+00, 2.94277080e-02],
    [2.00000000e+00, 3.28276369e-01],
    [3.00000000e+00, 4.43357154e-01],
    [4.00000000e+00, 3.54294582e-03],
    [5.00000000e+00, 1.57306794e-03],
    [6.00000000e+00, 2.00530733e-03],
    [7.00000000e+00, 2.95245485e-05],
    [8.00000000e+00, 2.24386568e-05],
    [9.00000000e+00, 2.83435665e-05],
    [1.00000000e+01, 1.18098194e-06],
    [1.20000000e+01, 1.18098194e-06]
])

# 提取取值和概率列
vals = sample_pmf[:, 0]
probs = sample_pmf[:, 1]

# 绘制条形图
plt.figure(figsize=(10, 6))
plt.bar(vals, probs, width=0.8, align='center', color='#1f77b4', alpha=0.7)

# 添加标签和标题
plt.xlabel('离散取值')
plt.ylabel('概率')
plt.title('单个场景的概率质量函数(PMF)')
plt.xticks(vals)  # 强制显示所有离散取值作为x轴刻度
plt.grid(axis='y', linestyle='--', alpha=0.7)

plt.show()

方法二:多场景PMF对比绘制

如果你有多个场景的PMF需要对比,可以给每个场景的条形设置偏移,避免重叠:

import matplotlib.pyplot as plt
import numpy as np

# 假设plot_pmf是你存储所有场景PMF的列表
plot_pmf = [sample_pmf, sample_pmf * 0.9 + 0.01]  # 模拟第二个场景的PMF

plt.figure(figsize=(12, 6))
bar_width = 0.35  # 每个条形的宽度
for idx, pmf_arr in enumerate(plot_pmf):
    vals = pmf_arr[:, 0]
    probs = pmf_arr[:, 1]
    # 给每个场景的x轴位置加偏移,避免条形重叠
    plt.bar(vals + idx * bar_width, probs, width=bar_width, 
            align='center', alpha=0.7, label=f'场景{idx+1}')

plt.xlabel('离散取值')
plt.ylabel('概率')
plt.title('多场景PMF对比')
plt.legend()
plt.xticks(vals + bar_width/2, vals)  # 调整x轴刻度位置
plt.grid(axis='y', linestyle='--', alpha=0.7)

plt.show()

为什么之前的直方图结果不对?

你用plt.hist(bl[0])得到的是原始模拟数据的直方图,它会:

  1. 自动将数据划分成连续区间(bins)
  2. 计算每个区间内的数据频数,再转换成频率
    这和你手动计算的PMF完全不同——你的PMF是每个精确离散值对应的概率,尤其是那些小概率的大取值(比如10、12),直方图会把它们合并到同一个区间里,导致展示的结果和你计算的PMF差异极大。

额外小技巧:阶梯图展示PMF

如果想要更简洁的离散分布展示,也可以用阶梯图:

plt.step(vals, probs, where='mid', linewidth=2, label='PMF')
plt.scatter(vals, probs, color='red')  # 加上每个点的标记
plt.legend()
plt.show()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:25:45