首页 > 技术文章 > 使用matplotlib画图分析数据

grainrain 2021-11-14 23:09 原文

有一组数据如下,需要分析下面数据的分布情况

  # 排序后

 

用直方图可以很好地看看数据在各个区间的分布,

1. 绘制直方图的方法:参考 参考2

from matplotlib import pyplot as plt

# 方法一
a = data
bin_width = 3
num_bins = (max(a)-min(a))//bin_width    #计算组数
plt.xticks(range(min(a), max(a)+bin_width,bin_width))#设置X轴刻度,band_width设置了组间距
plt.hist(a,num_bins)# 频率分布直方图

plt.grid(alpha = 0.4)
# plt.savefig(".\h.png")
plt.show()

# 方法二
width = 2    # 直方柱体宽度,若不指定,则各直方柱间将是紧挨着的
x = [xt for xt in range(min(data), max(data), 50)]    # 指定各直方柱的位置(xt)和柱(组)间距离(50),根据需要修改间距
plt.hist(data, x, width=width, label='xx', weights = np.ones_like(data) / len(data), color=color_l)    # 根据数据(data)和x画直方图,并指定标签和颜色
plt.grid(alpha = 0.4)  # 在背景添加网格
plt.legend()        # 显示label
plt.show()

其中weights参数指定了各个数据的频数,所以画出来的将是频率直方图,去掉这个参数得到的就是频数直方图 参考

matplotlib中color支持的颜色:参考

2. 有了这些数据,还可以连接各个直方柱的顶点,查看分布情况

y, edges = np.histogram(data, x)    # 返回得到data按x分组后各直方组的频数y,各直方组的边界(边界数=组数+1)
# centers = 0.5*(edges[1:]+ edges[:-1])  # 如果指定了weidth,这个计算方法有问题
plt.plot(edges[:-1], y, color=color_l[i], linestyle='-', marker='*') # 此处直接取直方柱的左上角作为标记点
plt.show()

其中,linestyle指定连线的类型,marker指定标记点的样式

 

 

3. 其实上面的数据还是很像高斯分布的,所以最好能够得到它的均值和方差,拟合曲线等

一个方法就是用scipy中的norm类,可以得到数据的正态拟合的均值(u)和方差(δ),其它的还有scipy中的optimize.curve_fit  参考

from scipy.stats import norm

mean,std=norm.fit(data)  
x = np.linspace(xmin, xmax)
y = norm.pdf(x, mean, std)
plt.plot(x, y)
plt.show()

 np.var(data)也可以求得方差

4. 多组数据同时显示

1)在一张图中,为每组数据设置不同的x刻度,防止各组数据重合显示(若重合,将只显示频数最大的那组数据)

for i in range(0, len(lists)):
  x = [xt+i*width for xt in range(0, max(lists[i]), 50)]
  ...

2)为每组数据设置不同的子图,分别显示  参考

plt1, plt2 = plt.subplot(211), plt.subplot(212)    # 211表示分2行1列的第1个(行),212为2行1列的第2个(行)
plt1.hist ...
plt2.plot ...

"""
plt.subplot(221)    # 第一行的第一列
plt.subplot(222)    # 第一行的第二列
plt.subplot(212)    # 这是按2行1列划分的第2个
# 所以整体是上面2个子图,下面一个子图
"""

 

3)更多样式 参考

推荐阅读