Python读取excel生成正态分布图
需求背景:
在制造业工厂为了统计产品尺寸的分布程度,需要制作正态分布图,excel 中没有专门的概率分布图制作比较麻烦。使用python容易实现。
运行环境:
win10 win8 win7 64位操作系统
python 3.6 以上
第三方库:
numpy
matplotlib
xlrd
程序代码:
import matplotlib.pyplot as plt
import numpy as np
import matplotlib
import matplotlib.mlab as mlab
import xlrd
#import time
def get_excel_value(j,filename): #j代表列0是第一列,j,filename 为文件名
row_list =[] #建立空列表插入尺寸数据
excel = xlrd.open_workbook(r"%s"%filename)
#sheet = excel.sheet_by_index(0) #根据下标获取对应的sheet表
sheet = excel.sheet_by_name("report") #根据表名获取对应的sheet表
#for j in range(0,sheet.ncols):
for i in range(5, sheet.nrows): #从表的第6行开始到
if sheet.row_values(i, start_colx=j, end_colx=j+1): #内循环
row_list.append(sheet.row_values(i, start_colx=j, end_colx=j+1)[0]) #每次循环取一个单元格数据插入列表中
arr_mean = np.mean(row_list)
arr_std = np.std(row_list,ddof=1)
return row_list,arr_mean,arr_std #函数返回尺寸数据,尺寸均值,尺寸标准差
def get_tolerance(j,filename): #读取公差函数,公差在工作表的3-5行
excel = xlrd.open_workbook(r"%s"%filename)
sheet = excel.sheet_by_index(0) #根据下标获取对应的sheet表
nominalvalue = sheet.row_values(2, start_colx=j, end_colx=j+1)[0]
up=sheet.row_values(3, start_colx=j, end_colx=j+1)[0]
low=sheet.row_values(4, start_colx=j, end_colx=j+1)[0]
LSL=nominalvalue+low
USL=nominalvalue+up
return LSL,USL
def get_name(j,filename): #获取尺寸名
excel = xlrd.open_workbook(r"%s"%filename)
sheet = excel.sheet_by_index(0) #根据下标获取对应的sheet表
name = sheet.row_values(1, start_colx=j, end_colx=j+1)[0]
return name
class higram:
def __init__(self,dimension,filename,mu,sigma,data,LSL,USL,num_bins ):
self.dimension=dimension
self.filename=filename
self.mu=mu
self.sigma=sigma
self.data=data
self.LSL=LSL
self.USL=USL
self.num_bins=num_bins
def creatchart(self):
# 设置matplotlib正常显示中文和负号
matplotlib.rcParams['font.sans-serif']=['SimHei'] # 用黑体显示中文
matplotlib.rcParams['axes.unicode_minus']=False # 正常显示负号
def norm_pdf(x,mu,sigma):
pdf = np.exp(-((x - mu)**2) / (2* sigma**2)) / (sigma * np.sqrt(2*np.pi)) #正态分布函数
return pdf
n, bins, patches = plt.hist(self.data, self.num_bins, density=1, facecolor="blue", edgecolor="black", alpha=0.5)#facecolor直方填充颜色edgecolor直方边框颜色
#FFC0CB Pink 粉红 #E6E6FA Lavender 淡紫色/熏衣草淡紫
y=norm_pdf(bins, mu, sigma) #概率分布图
#print(y)
plt.plot(bins, y, 'r--',linestyle='-') #概率分布图"_"代表实线,"r--"代表红色
x = np.linspace(self.LSL, self.LSL, 100) #等差数列
y = np.linspace(0, 60, 100)
plt.text(x[0],y[39],'LSL',size=13) #text(x,y,str),x,y 文字的坐标
plt.plot(x, y, 'g--', linewidth=1)
x = np.linspace(self.USL, self.USL, 100)
y = np.linspace(0, 60, 100)
plt.text(x[0],y[39],'USL',size=13)
plt.plot(x, y, 'g--', linewidth=1)
plt.xlabel("区间")# 显示纵轴标签
plt.ylabel("频数/频率") # 显示图标题
plt.title(self.dimension+"_正态分布图")
plt.subplots_adjust(left=0.15) #把画的图从左边0.15(整个为1)处开始, 要不把y轴的label显示不出来
plt.show()
if __name__ == "__main__":
#s=time.time()
data=get_excel_value(0,"检测报告.xls")[0] #尺寸数据
mu=get_excel_value(0,"检测报告.xls")[1] #尺寸均值
sigma=get_excel_value(0,"检测报告.xls")[2] #尺寸标准差
LSL=get_tolerance(0,"检测报告.xls")[0] #下公差
USL=get_tolerance(0,"检测报告.xls")[1] #上公差
Dimension=get_name(0,"检测报告.xls")
#尺寸名
#e=time.time()
#t=e-s
#print(t)
'''print("result:",data)
print("mean:",mu)
print("std:",sigma)
print("LSL:",LSL)
print("USL:",USL)
print("Dimension:",Dimension)'''
h=higram(Dimension,"检测报告.xls",mu,sigma,data,LSL,USL,num_bins=60)
h.creatchart()
运行效果: