[python常用图件绘制#01]线性拟合结果图

一、功能介绍
输入:

  • 实测x、y数据

输出:

  • 必选:x、y散点图
  • 必选:x、y线性拟合直线
  • 可选:相关性、显著性分析结果显示
    [python常用图件绘制#01]线性拟合结果图_第1张图片
    [python常用图件绘制#01]线性拟合结果图_第2张图片

二、代码

import random
from scipy import stats
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
import numpy as np


class Linearfitplot:
    def __init__(self, x, y, legends=None, labels=None, fsize=(8, 8), show_info=1):
        """
        :param x: 数据x列表
        :param y: 数据y列表
        :param legends: 图例名,默认为 "线性拟合结果", "实测值"
        :param labels:坐标轴标题名,默认为 "数据x", "数据y"
        :param show_info:是否显示拟合结果信息
        """
        if legends is None:
            legends = ["线性拟合结果", "实测值"]
        if labels is None:
            labels = ["数据x", "数据y"]
        self.x = x
        self.y = y
        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 rsquared(self, show_info_or_not=0):
        """
        :param show_info_or_not: 布尔类型,当其为真时显示信息
        :param x:x数据序列
        :param y:y数据序列
        :return:
        r: 相关系数
        p:显著性
        slope:曲线斜率
        intercept:截距
        """
        ws = 3  # 各参数保留的小数位数
        check_p = "不显著"
        slope, intercept, *useless = stats.linregress(self.x, self.y)
        r, p = stats.pearsonr(self.x, self.y)
        if p <= 0.01:
            check_p = "非常显著**"
        elif p <= 0.05:
            check_p = "显著*"
        slope, intercept, r, p = round(slope, ws), round(intercept, ws), round(r, ws), round(p, ws)
        info = "y = {0}x + {1}\nr-square = {2}\np:{3};{4}".format(slope, intercept, round(r**2, ws), p, check_p)
        if show_info_or_not:
            return info
        else:
            return slope, intercept, r, p

    def draw_plot(self, *args):
        """
        绘制图像,包含散点图和拟合线
        :param args:
        :return:
        """
        # 设置画布大小
        plt.figure(figsize=self.fsize)
        # 生成df
        x_name, y_name = "x", "y"
        dict_data = {"x": self.x,
                     "y": self.y
                     }
        df = pd.DataFrame(dict_data)
        # 计算并绘制拟合曲线
        z1 = np.polyfit(x_data, y_data, 1)
        p1 = np.poly1d(z1)  # 将系数代入方程,得到函式p1
        yvals_data = p1(df[x_name])
        # 绘制曲线
        sns.set_style("darkgrid") # 绘制图像的样式
        plt.rcParams['font.sans-serif'] = ['SimHei']  # 显示中文
        sns.set_context("talk", font_scale=1)
        sns.lineplot(x_data, yvals_data, color="r", lw=1, label=self.legends[0])
        sns.scatterplot(x=x_name, y=y_name, data=df, *args, label=self.legends[1])
        plt.xlabel(self.labels[0])
        plt.ylabel(self.labels[1])
        info_show = self.rsquared(self.show_info)
        plt.text(self.fsize[0] * 0.6, self.fsize[0] * 0.1, info_show, size=self.fsize[0] * 1.8)
        plt.tight_layout()
        plt.show()


if __name__ == "__main__":
    len_data = 10  # 测试数据序列的长度
    x_data = list(range(len_data))  # x轴数据序列
    y_data = [i*2+1+random.uniform(0, 1) for i in x_data]
    plot1 = Linearfitplot(x_data, y_data, fsize=(8, 8))
    plot1.draw_plot()

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