美文网首页DATA ANALYSIS PROCESS
Matplotlib和Seaborn之直方图

Matplotlib和Seaborn之直方图

作者: IntoTheVoid | 来源:发表于2020-04-23 13:38 被阅读0次

    直方图

    直方图用来绘制数字变量的分布情况。它是条形图的定量版本。但是,我们不再为每个独特数字值绘制一个长条,而是将值分成连续的分箱,并针对每个分箱绘制一个长条,用于描绘相关数字。例如,使用 matplotlib 的 hist 函数的默认设置:

    plt.hist(data = df, x = 'num_var')
    
    
    image.png

    可以看出,在最左侧的分箱(约为 0 到 2.5 之间)中有 8 个数据点,在相邻分箱(约为 2.5 到 5 之间)中有 9 个数据点。总体来说,可以看出是一个双峰分布。直方图中的长条直接相连,而条形图中的长条是分开的,表明在直方图中数据的值处在连续范围内。如果某个数据值位于分箱边缘,则属于右侧分箱。例外情况是最右侧的分箱边缘,将上限的值放入最右侧的分箱内(上限的左侧)。

    默认情况下,hist 函数会根据值的范围将数据分成 10 个分箱。在几乎所有情况下,我们都需要更改这一设置。通常,只有 10 个分箱太少了,无法了解数据的分布情况。并且默认的刻度并没有采用很容易解释分箱范围的近似值。如果在上述示例中,将“约为 0 到 2.5 之间”说成“0 到 2.5 之间”并将“约为 2.5 到 5 之间”说成“2.5 到 5 之间”,是不是更方便?

    你可以使用描述统计学(例如通过 df['num_var'].describe())估测什么样的分箱下限和分箱上限比较合适。可以使用 numpy 的 arange 函数设置这些分箱边缘:

    bin_edges = np.arange(0, df['num_var'].max()+1, 1)
    plt.hist(data = df, x = 'num_var', bins = bin_edges)
    
    

    arange 的第一个参数是最左侧的分箱边缘,第二个参数是上限,第三个参数是分箱宽度。注意,即使我在第二个参数中指定了“max”值,我添加了“+1”(分箱宽度)。这是因为 arange 将仅返回完全小于上限的值。加上“+1”可有效地确保左右侧的分箱边缘至少是最大数据值,以便所有数据点都能绘制出来。最左侧的分箱设为硬编码的值,以便获得可解释的值,当然你也可以使用 numpy 的 around 等函数以程序方式达到这种效果。

    image.png

    在创建直方图时,有必要尝试不同的分箱宽度,看看哪个宽度最能表示数据。如果分箱太多,可能会发现太多噪点,干扰我们发现数据蕴含的规律。如果分箱太少,则根本无法看出真正的规律。

    plt.figure(figsize = [10, 5]) # larger figure size for subplots
    
    # histogram on left, example of too-large bin size
    plt.subplot(1, 2, 1) # 1 row, 2 cols, subplot 1
    bin_edges = np.arange(0, df['num_var'].max()+4, 4)
    plt.hist(data = df, x = 'num_var', bins = bin_edges)
    
    # histogram on right, example of too-small bin size
    plt.subplot(1, 2, 2) # 1 row, 2 cols, subplot 2
    bin_edges = np.arange(0, df['num_var'].max()+1/4, 1/4)
    plt.hist(data = df, x = 'num_var', bins = bin_edges)
    
    

    该示例通过 subplot 函数将两个图形并排地放到一起,函数的参数指定了有效子图的行数、列数和索引。figure() 函数在调用时传入了 "figsize" 参数,以便我们能够绘制更大的图形并包含多个子图。

    image.png

    替代方法

    seaborn 函数 distplot 也可以用于绘制直方图,并且与其他单变量绘图函数集成到一起。

    sb.distplot(df['num_var'])
    
    

    注意,第一个参数必须是 Series 或数组,其中包含要绘制的数据点,而不是指定数据来源和列。

    image.png

    distplot 函数具有指定直方图分箱的内置规则,默认情况下,会在数据上方绘制一个 (KDE) 核密度估计。纵轴基于 KDE,而不是直方图:长条的高度之和不一定等于 1,但是曲线下方的面积应该等于 1。如果你想详细了解 KDE,请参阅这节课末尾的补充内容。

    虽然默认的 distplot 分箱尺寸可能比固定的 .hist = 10 更合适,但是你依然需要进行调整,使分箱尺寸等于四舍五入的值。你可以使用其他参数设置绘制直方图并像之前一样指定分箱:

    bin_edges = np.arange(0, df['num_var'].max()+1, 1)
    sb.distplot(df['num_var'], bins = bin_edges, kde = False,
                hist_kws = {'alpha' : 1})
    
    

    alpha(透明度)设置必须当做字典与 "hist_kws" 关联,因为还有其他底层绘图函数(例如 KDE)具有自己的可选关键字参数。

    image.png

    上述代码的结果和上述分箱宽度为 1 的直方图完全一样。纵轴的单位也以计数的形式出现了。

    总之,如果你只想了解数据的直方图分布情况,而不是 distplot 提供的额外信息,则为了简便,建议只使用 Matplotlib 的 hist 函数。另一方面,如果你想快速了解如何为直方图选择代表性的分箱尺寸,建议在自定义之前,先快速查看下基本的 distplot

    相关文章

      网友评论

        本文标题:Matplotlib和Seaborn之直方图

        本文链接:https://www.haomeiwen.com/subject/mrrnfqtx.html