如何繪製頻率直方圖+累計概率曲線

前言

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

在這裏插入圖片描述

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