[python常用图件绘制#03]Gamma分布拟合图

〇、Gamma分布主要参数说明
对于一组连续的随机变量x来说,若它的概率密度分布函数f(x|α,β)符合下式时:
0-1
则将这个概率密度函数称为伽码(Г,Gamma)分布,记作 X ~Г(α,β),其中α称为形状参数,β称为尺度参数。通过绘图,可对比不同α,β取值下曲线的形态。
[python常用图件绘制#03]Gamma分布拟合图_第1张图片
绘制此图的代码如下:

import numpy as np
import matplotlib.pyplot as plt
import scipy.stats as st
import seaborn as sns

plt.rcParams['font.sans-serif'] = ['SimHei']  # 显示中文
sns.set_context("talk", font_scale=1)

# 设置画布
fig = plt.figure(figsize=(8, 8))  # 确定绘图区域尺寸
ax1 = fig.add_subplot(1, 1, 1)
x = np.arange(0.01, 20, 0.01) 

# 绘制gamma分布曲线
y1 = st.gamma.pdf(x, 1, scale=2)  # "α=1,β=2"
y2 = st.gamma.pdf(x, 2, scale=2)  # "α=2,β=2"
y3 = st.gamma.pdf(x, 3, scale=2)  # "α=3,β=2"
y4 = st.gamma.pdf(x, 5, scale=1)  # "α=5,β=1"
y5 = st.gamma.pdf(x, 9, scale=0.5)  # "α=9,β=0.5"

# 设置图例
ax1.plot(x, y1, label="α=1,β=2")
ax1.plot(x, y2, label="α=2,β=2")
ax1.plot(x, y3, label="α=3,β=2")
ax1.plot(x, y4, label="α=5,β=1")
ax1.plot(x, y5, label="α=9,β=0.5")

# 设置坐标轴标题
ax1.set_xlabel('x')
ax1.set_ylabel('p(x)')
ax1.set_title("Gamma分布示意图")
ax1.legend(loc="best")

plt.show()

一、功能介绍

输入:

  • 某样本数据
  • 样本分组数

输出:

  • 直方图(纵轴为频率)
  • Gamma分布拟合曲线
  • 显示拟合参数及R方值
    [python常用图件绘制#03]Gamma分布拟合图_第2张图片[python常用图件绘制#03]Gamma分布拟合图_第3张图片

二、代码

import matplotlib.pyplot as plt
import seaborn as sns
import scipy.stats as st
import numpy as np


class Gammafitplot:
    def __init__(self, x, num_bins, legends=None, labels=None, fsize=(10, 6.18), show_info=True):
        """
        :param x: 数据x列表
        :param num_bins: x的分组数
        :param legends: 图例名,默认为 "频率", "Gamma分布拟合"
        :param labels:坐标轴标题名,默认为 "数据x", "数据y"
        :param show_info:是否显示拟合结果信息
        """
        if legends is None:
            legends = ["频率", "Gamma分布拟合"]
        if labels is None:
            labels = ["数据x", "频率"]
        self.x = x
        self.num_bins = num_bins
        self.paras = (np.mean(x)**2/np.var(x), np.var(x)/np.mean(x))
        self.fsize = fsize
        self.legends = legends
        self.labels = labels
        self.show_info = show_info

    def change_legend(self, new_legends):
        # 更改图例
        self.legends = new_legends

    def change_label(self, new_labels):
        # 更改坐标轴标题
        self.labels = new_labels

    def change_para(self, new_paras):
        # 更改gamma分布的参数
        self.paras = new_paras

    def draw_plot(self):
        fs = self.fsize  # 画布大小
        alpha = self.paras[0]  # gamma分布中的参数α
        beta = self.paras[1]  # gamma分布中的参数β

        # 利用seaborn库对字体大小进行统一设置,为fgsize[1]的0.12倍,即画布纵向大小为1000时,font_scale=1.2
        sns.set_style("ticks")
        sns.set_context("talk", font_scale=fs[1]*0.12)
        plt.rcParams['font.sans-serif'] = ['SimHei']

        # 设置画布
        plt.figure(figsize=fs)

        # ax:绘制频率直方图
        plt.hist(self.x, self.num_bins, density=1, rwidth=0.9, label=self.legends[0])
        plt.xlabel(self.labels[0])
        plt.ylabel(self.labels[1])

        # ax2:绘制gamma拟合曲线
        self.x.sort()
        y = st.gamma.pdf(self.x, alpha, scale=beta)
        plt.plot(self.x, y, '-', label=self.legends[1])
        if self.show_info:
            info = "α={:.3f} β={:.3f}\nr-square={:.3f}".format(self.paras[0], self.paras[1], st.linregress(self.x, y)[2]**2)
            print(info)
        # 显示多图例
        plt.legend(loc=1, bbox_to_anchor=(1, 1))


if __name__ == "__main__":
    np.random.seed(19680801)
    iqs = 100 + 15 * np.random.randn(500)  # 待绘制直方图的数据
    bins = 50  # 数据分组数
    gammaplot = Gammafitplot(iqs, bins)
    gammaplot.draw_plot()
    plt.show()

本例中α、β参数的值默认根据经验公式(不具有有普适性)确定,可用下文代码中的Gammafitplot类的change_para()方法进行修改,如下:

if __name__ == "__main__":
    np.random.seed(19680801)
    iqs = 100 + 15 * np.random.randn(500)  # 待绘制直方图的数据
    bins = 50  # 数据分组数
    gammaplot = Gammafitplot(iqs, bins)
    gammaplot.change_para((50, 3))  # 将gamma分布的α、β分别设置为50和3
    gammaplot.draw_plot()
    plt.show()

你可能感兴趣的:(python画图)