python-3.x - 用每个 SD 的数据百分比或计数绘制正态分布
问题描述
l = {31.2: 1, 35.1: 4, 39.0: 13, 42.9: 33, 46.8: 115, 50.7: 271, 54.6: 363, 58.5: 381, 62.4: 379, 66.3: 370, 70.2: 256, 74.1: 47, 78.0: 2}
# convert the dictionary to a list
l_list = [k for k, v in l.items() for _ in range(v)]
我希望正态分布曲线适合上述数据以及每个区域上打印的样本数量,如下图所示。
解决方案
这是一种计算和绘制适合数据的高斯法线的方法。请注意,数据已经预先组合在一起,因此无法再计算真实均值和标准差。
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import gaussian_kde, norm
l = {31.2: 1, 35.1: 4, 39.0: 13, 42.9: 33, 46.8: 115, 50.7: 271, 54.6: 363, 58.5: 381, 62.4: 379, 66.3: 370, 70.2: 256, 74.1: 47, 78.0: 2}
# convert the dictionary to a list
l_array = np.array( [k for k, v in l.items() for _ in range(v)])
s = sum(l.values())
bin_width = 3.9
bin_centers = list(l.keys())
heights = [v/s/bin_width for v in l.values()]
plt.bar(bin_centers, heights, width=bin_width*0.9, color='dodgerblue', label='histogram')
for c, h, v in zip(bin_centers, heights, l.values()):
plt.text(c, h, v, ha='center', va='bottom')
plt.xticks(bin_centers)
mean = l_array.mean()
sdev = l_array.std()
for i in range(-3, 4):
plt.axvline(mean+i*sdev, color='limegreen', ls='--', lw=2, label='mean + i*sdev' if i == 0 else None)
x = np.linspace(mean-4*sdev, mean+4*sdev, 500)
plt.plot(x, norm.pdf(x, mean, sdev), color='orange', lw=3, label='gaussian normal')
plt.autoscale(enable=True, axis='x', tight=True)
plt.legend()
plt.show()
推荐阅读
- flutter - Flutter AnimationBuilder 无法与提供者状态管理一起使用
- shopify - Shopify 公共应用代理请求接收密码页面
- sql - 连续获得最小值
- python - 验证手机号码 - Odoo
- angular - Angular 材质如何与 coreui 模板集成
- php - GraphQL 声纳 API 突变
- c# - Unity Scriptable Object 根据另一个字段值将字段的类型更改为新类型
- php - 如何将参数添加到 URL
- php - 尝试连接数据库时出现错误 CodeIgniter\Database\Exceptions\DatabaseException #8
- c# - 异步在方法中间跳过执行