如何绘制频率直方图+累计概率曲线

前言

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()

在这里插入图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章