前言
matplotlib画直方图是通过hist函数来画的,但是有时候或许我们想画一个直方图加上累计概率曲线,既然没有现成的,就只能咱们自己造了
计算累计曲线
ax1 = fig.add_subplot(111)
a1,a2,a3=ax1.hist(data,bins =10, alpha = 0.65,normed=1,edgecolor='k')
a1返回的是直方图每个柱子的高度,如果normed=1,则为频率/组距;normed=0,则为频数
[0.00042882 0.00039308 0.00046455 0.00219173 0.00456213 0.00106013
0.00042882 0.0002025 0.00014294 0.00022632]
a2返回的是直方图每个柱子的左右横坐标,如例子是10个bins,则a2会有11个值
[-497. -398. -299. -200. -101. -2. 97. 196. 295. 394. 493.]
a3返回的是patch对象,对我们的需求实现不是特别重要
<a list of 10 Patch objects>
所以接下来我们要做的就是获取累计概率曲线的横纵坐标
获取累计概率曲线的横坐标
indexs=[]
a2=a2.tolist()
for i,value in enumerate(a2):
if i<=len(a2)-2:
index=(a2[i]+a2[i+1])/2
indexs.append(index)
即生成每个区间的中点
获取累计概率曲线的纵坐标
dis=a2[1]-a2[0]
freq=[f*dis for f in a1]
acc_freq=[]
for i in range(0,len(freq)):
if i==0:
temp=freq[0]
else:
temp=sum(freq[:i+1])
acc_freq.append(temp)
思路也很简单,先把频率/组距乘以组距换算成每组对应的频率,接着再累加生成累计概率即可
生成双轴,绘制累加概率曲线
#这是双坐标关键一步
ax2=ax1.twinx()
#绘制累计概率曲线
ax2.plot(indexs,acc_freq)
#设置累计概率曲线纵轴为百分比格式
ax2.yaxis.set_major_formatter(FuncFormatter(to_percent))
效果展示:
完整代码
def cum_prob_curve(data,bins,title,xlabel,pic_path):
'''
绘制概率分布直方图和累计概率分布曲线
'''
import matplotlib.pyplot as plt
import matplotlib as mpl
from matplotlib.ticker import FuncFormatter
#从pyplot导入MultipleLocator类,这个类用于设置刻度间隔
from matplotlib.pyplot import MultipleLocator
fig= plt.figure(figsize=(8, 4),dpi=100)
# 设置图形的显示风格
plt.style.use('ggplot')
# 中文和负号的正常显示
mpl.rcParams['font.sans-serif'] = ['Times New Roman']
mpl.rcParams['font.sans-serif'] = [u'SimHei']
mpl.rcParams['axes.unicode_minus'] = False
ax1 = fig.add_subplot(111)
##概率分布直方图
a1,a2,a3=ax1.hist(data,bins =bins, alpha = 0.65,normed=1,edgecolor='k')
##累计概率曲线
#生成累计概率曲线的横坐标
indexs=[]
a2=a2.tolist()
for i,value in enumerate(a2):
if i<=len(a2)-2:
index=(a2[i]+a2[i+1])/2
indexs.append(index)
#生成累计概率曲线的纵坐标
def to_percent(temp,position):
return '%1.0f'%(100*temp) + '%'
dis=a2[1]-a2[0]
freq=[f*dis for f in a1]
acc_freq=[]
for i in range(0,len(freq)):
if i==0:
temp=freq[0]
else:
temp=sum(freq[:i+1])
acc_freq.append(temp)
#这是双坐标关键一步
ax2=ax1.twinx()
#绘制累计概率曲线
ax2.plot(indexs,acc_freq)
#设置累计概率曲线纵轴为百分比格式
ax2.yaxis.set_major_formatter(FuncFormatter(to_percent))
ax1.set_xlabel(xlabel,fontsize=8)
ax1.set_title(title,fontsize =8)
#把x轴的刻度间隔设置为1,并存在变量里
# x_major_locator=MultipleLocator(xlocator)
# ax1.xaxis.set_major_locator(x_major_locator)
ax1.set_ylabel('频率/组距',fontsize=8)
ax2.set_ylabel("累计频率",fontsize=8)
plt.savefig(pic_path,format='png', dpi=300)
plt.show()