[python常用图件绘制#04]核密度曲线图(显示峰值点)

一、关于核密度估计带宽的一些说明
进行核密度估计Kernel Density Estimation(KDE)时,带宽bw的选取尤为重要,不同的带宽会对结果造成很大的影响。利用seaborn库中kdeplot()绘制kde曲线时,可以选择scott和silverman两种自适应带宽方法。
1-1

import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns

plt.rcParams['axes.unicode_minus'] = False  # 解决保存图像是负号'-'显示为方块的问题
a = np.random.normal(-1, 1, size=100)

plt.figure(figsize=[10, 10])
sns.set_context("notebook", font_scale=1.5)

sns.distplot(a, axlabel="x", kde=True, kde_kws={"color": "g", "lw": 0},
             rug=True, rug_kws={"color": "k"}
             )
color_list = ['k', 'gray', 'b', 'g', 'r']
sns.kdeplot(a,
            kernel='gau',
            bw="scott",
            label="scott method",
            color=color_list[0],
            linewidth=3
            )
sns.kdeplot(a,
            kernel='gau',
            bw=2,
            label="bw=2",
            color=color_list[1],
            linewidth=2
            )
sns.kdeplot(a,
            kernel='gau',
            bw=1,
            label="bw=1",
            color=color_list[2],
            linewidth=2
            )
sns.kdeplot(a,
            kernel='gau',
            bw=0.5,
            label="bw=0.5",
            color=color_list[3],
            linewidth=2
            )
sns.kdeplot(a,
            kernel='gau',
            bw=0.1,
            label="bw=0.1",
            color=color_list[4],
            linewidth=2
            )

plt.show()

二、例图
1-1
样本数据的统计信息及其KDE曲线信息
1-2
三、代码

import matplotlib
import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns
import statsmodels.nonparametric.api as smnp


def kde_test(data, kernel, bw, gridsize, cut):
    """
    :param data:样本数据
    :param kernel:核函数
    :param bw:带宽
    :param gridsize:绘制拟合曲线中的离散点数;可理解为精度,会改变kde曲线的圆滑程度
    :param cut: 源代码说明——Draw the estimate to cut * bw from the extreme data points.
    :return: kde估计曲线的x、y坐标
    """
    fft = kernel == "gau"
    kde = smnp.KDEUnivariate(data)
    kde.fit(kernel, bw, fft, gridsize=gridsize, cut=cut)
    return kde.support, kde.density


class Kdefitplot:
    def __init__(self, data, kernel='gau', bw="scott", legends=None, labels=None, fsize=(10, 6.18), show_point=False, show_info=True):
        """
        :param data:以列表格式存储的数据
        :param kernel:密度估计选用的核函数,可选{'gau'|'cos'|'biw'|'epa'|'tri'|‘triw’},默认为'gau'
        :param bw:密度估计选用的自适应带宽方法,可选{'scott'|'silverman'|scalar|pair of scalars},默认为"scott"
        :param legends: 图例名,默认为 "概率密度", "kde曲线", "最大值点"
        :param labels:坐标轴标题名,默认为 "数据x", "概率密度"
        :param show_info:是否显示拟合结果信息,默认为True
        :param show_point:在kde曲线上显示目标点(最大值点),默认为False
        """
        self.data = data
        self.kernel = kernel
        self.bw = bw
        if legends is None:
            legends = ["概率密度", "kde曲线", "最大值点"]
        if labels is None:
            labels = ["样本数据", "概率密度"]
        self.legends = legends
        self.labels = labels
        self.fsize = fsize
        self.show_info = show_info
        self.show_point = show_point
        self.gridsize = 100
        self.cut = 3

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

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

    def draw_plot(self):
        # 利用seaborn库对字体大小进行统一设置,为fgsize[1]的0.12倍,即画布纵向大小为1000时,font_scale=1.2
        sns.set_style("darkgrid")
        sns.set_context("talk", font_scale=self.fsize[1] * 0.15)
        plt.rcParams['font.sans-serif'] = ['SimHei']
        matplotlib.rcParams['axes.unicode_minus'] = False
        plt.figure(figsize=self.fsize)

        # 绘制频率直方图
        sns.distplot(self.data, label=self.legends[0], rug=True, kde=True, kde_kws={"color": "g", "lw": 0})

        # 以gau为核函数,scott为带宽估计方法
        sns.kdeplot(self.data,
                    kernel=self.kernel,
                    bw=self.bw,
                    label=self.legends[1],
                    color="r",
                    linewidth=self.fsize[0]*0.2
                    )

        # 计算kde曲线的x、y值
        kdefit_x, kdefit_y = kde_test(self.data,
                                      self.kernel,
                                      self.bw,
                                      gridsize=self.gridsize,
                                      cut=self.cut)

        # point为kde曲线最大值点
        point = np.where(kdefit_y == np.max(kdefit_y))

        # 在kde曲线上显示目标点,格式为黑色实心圆
        if self.show_point:
            plt.plot(kdefit_x[point], kdefit_y[point], "o", color='k', linewidth=self.fsize[0]*0.4, label=self.legends[2])

        # 打印统计信息
        if self.show_info:
            # 显示核密度估计信息:kernel为核函数、bw为自适应带宽方法、point为kde曲线最大值点
            # 基本统计信息:Size为样本数据点个数、Average为平均值、Q25/Q50/Q75分别为25%/50%/75%分位数
            q25, q50, q75 = [round(q, 4) for q in np.percentile(self.data, [25, 50, 75])]
            base_info = f"Size:{len(self.data)}\nAver:{np.mean(self.data)}\nQ25:{q25}; Q50:{q50}; Q75:{q75}\n\n"
            kde_info = f"kernel:{self.kernel}\nbw:{self.bw}\nMax point appear in {kdefit_x[point]}\n"
            print(base_info + kde_info)

        # 设置x、y坐标轴标题
        plt.xlabel(self.labels[0])
        plt.ylabel(self.labels[1])

        plt.legend()
        plt.tight_layout()


if __name__ == "__main__":
    iqs_1 = 100 + 15 * np.random.randn(500)  
    iqs_2 = 200 + 75 * np.random.randn(500)
    kdeplot1 = Kdefitplot(iqs_1 + iqs_2, show_point=True)
    kdeplot1.draw_plot()
    plt.show()
  • 7
    点赞
  • 62
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Python中的直方图密度估计是一种用于估计概率密度函数的非参数方法。它可以通过使用平滑的峰值函数""来拟合观察到的数据,从而对真实的概率分布曲线进行模拟。在绘制直方图密度估计图时,可以使用峰峦图来展示多个数据系列的密度估计结果。峰峦图显示了X轴对应平均温度的数值范围,Y轴对应不同的月份,每个月份的密度估计数值映射到颜色,以此来展示多个数据系列的密度估计结果。在Python中,可以使用joypy包或plotnine包等绘图工具来实现绘制直方图密度估计峰峦图的功能。对于使用joypy包,可以直接使用joyplot()函数来绘制带有颜色渐变映射的密度估计峰峦图;而对于使用plotnine包,可以结合使用geomlinerange()函数和geomline()函数,并先使用sklearn包的KernelDensity()函数求取每个月份的密度估计曲线,再根据密度估计数据绘制峰峦图,从而实现绘制多个数据系列的密度估计图的功能。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [matlab 三维密度图_python数据分布型图表直方图系列密度估计图](https://blog.csdn.net/weixin_39855186/article/details/110258995)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Salierib

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值