前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python可视化 | Seaborn教你一行代码生成数据可视化

Python可视化 | Seaborn教你一行代码生成数据可视化

作者头像
郭好奇同学
发布2021-11-24 11:43:06
1.2K0
发布2021-11-24 11:43:06
举报
文章被收录于专栏:好奇心Log好奇心Log

处理一组数据时,通常要做的第一件事就是了解变量的分布。本文会介绍seaborn中用于可视化单变量的一些函数。

代码语言:javascript
复制
#导入库

import numpy as np

import pandas as pd

import seaborn as sns

import matplotlib.pyplot as plt

from scipy import stats
代码语言:javascript
复制
sns.set(color_codes=True)
x = np.random.normal(size=100)

单变量可视化

查看seaborn中的单变量分布的最便捷方法是distplot()函数。默认情况下,将绘制直方图并拟合核密度估计(KDE, kernel density estimate)。

代码语言:javascript
复制
sns.distplot(x)
代码语言:javascript
复制
<matplotlib.axes._subplots.AxesSubplot at 0x7fd493fa0390>

直方图

直方图将数据分成bin(s),然后绘制条形以显示落在每个bin中的数据数量,来表示数据的分布。

为了说明这一点,可以删除密度曲线并添加一个地毯图,该图在每次观察时都会绘制一个小的垂直刻度。您可以使用rugplot()函数制作地毯图,也可以在distplot()中使用它。

代码语言:javascript
复制
sns.distplot(x, kde=False, rug=True)
代码语言:javascript
复制
<matplotlib.axes._subplots.AxesSubplot at 0x7fd49669ac50>

绘制直方图时,主要的选择是bin的数量以及放置它们的位置。distplot()会为你自动选择参数,但是尝试更多或更少的bin可能会揭示数据的其他特征。

代码语言:javascript
复制
sns.distplot(x, bins=20, kde=False, rug=True)
代码语言:javascript
复制
<matplotlib.axes._subplots.AxesSubplot at 0x7fd493a13b00>

核密度估计

核密度估计是绘制分布形状的一个有用的工具。像直方图一样,KDE根据一个轴上数据的密度,在另一个轴上显示高度。

代码语言:javascript
复制
sns.distplot(x, hist=False, rug=True)
代码语言:javascript
复制
<matplotlib.axes._subplots.AxesSubplot at 0x7fd493eca898>

与绘制直方图相比,绘制KDE的计算量更大。它的计算过程是,每个观察值首先被以该值为中心的高斯曲线代替。

代码语言:javascript
复制
x = np.random.normal(0, 1, size=30)

bandwidth = 1.06 * x.std() * x.size ** (-1 / 5.)

support = np.linspace(-4, 4, 200)

kernels = []

for x_i in x:
    kernel = stats.norm(x_i, bandwidth).pdf(support)
    kernels.append(kernel)
    plt.plot(support, kernel, color="r")

sns.rugplot(x, color=".2", linewidth=3);

接下来,将这些曲线求和,以计算每个点的密度值。然后将结果曲线归一化,以使其下方的面积等于1。

代码语言:javascript
复制
from scipy.integrate import trapz

density = np.sum(kernels, axis=0)

density /= trapz(density, support)

plt.plot(support, density)
代码语言:javascript
复制
[<matplotlib.lines.Line2D at 0x7fd3f272d978>]

如果在seaborn中使用kdeplot()函数,可以得到相同的曲线。distplot()为查看数据密度估计提供了更直接、便利的方法。

代码语言:javascript
复制
sns.kdeplot(x, shade=True)
代码语言:javascript
复制
<matplotlib.axes._subplots.AxesSubplot at 0x7fd493864eb8>

KDE的带宽(bw)参数控制估算值与数据拟合的紧密程度,非常类似于直方图中的bin大小。它对应上面绘制的内核的宽度。默认值使用的是通用规则,但是尝试更大或更小的值可能会有所帮助。

代码语言:javascript
复制
sns.kdeplot(x)

sns.kdeplot(x, bw=.2, label="bw: 0.2")

sns.kdeplot(x, bw=2, label="bw: 2")

plt.legend()
代码语言:javascript
复制
<matplotlib.legend.Legend at 0x7fd3f2754080>

在上图中,bw=2时,估算超出了数据集中的最大和最小值。可以控制通过cut参数绘制曲线的极限值有多远。但是,这只会影响曲线的绘制方式,而不会影响其拟合方式。

代码语言:javascript
复制
sns.kdeplot(x, shade=True, cut=0)

sns.rugplot(x)
代码语言:javascript
复制
<matplotlib.axes._subplots.AxesSubplot at 0x7fd493835ac8>

拟合参数分布

你还可以使用distplot()将参数分布拟合到数据集,并直观地评估其与观察到的数据的对应程度。

代码语言:javascript
复制
x = np.random.gamma(6, size=200)

sns.distplot(x, kde=False, fit=stats.gamma)
代码语言:javascript
复制
<matplotlib.axes._subplots.AxesSubplot at 0x7fd3f08cb2e8>

双变量分布可视化

在seaborn中可视化双变量的方法是jointplot()函数,该函数创建一个多面板图形,该图形同时显示两个变量之间的双变量(或联合)关系以及每个变量的单变量分布。

代码语言:javascript
复制
mean, cov = [0, 1], [(1, .5), (.5, 1)]

data = np.random.multivariate_normal(mean, cov, 200)

df = pd.DataFrame(data, columns=["x", "y"])

散点图

可视化双变量分布的最常用的方法是散点图,和matplotlib plt.scatter类似。

代码语言:javascript
复制
sns.jointplot(x="x", y="y", data=df)
代码语言:javascript
复制
<seaborn.axisgrid.JointGrid at 0x7fd3f08a0a20>

六边形图

双变量的直方图叫“六边形”图,因为它显示了落在六边形箱中的观测值。该图适用于相对较大的数据集。可通过matplotlib plt.hexbin函数使用,也可以在jointplot()中作为样式使用。

代码语言:javascript
复制
x, y = np.random.multivariate_normal(mean, cov, 1000).T

sns.jointplot(x=x, y=y, kind="hex");

核密度估计

对于双变量也可以进行核密度估计。

代码语言:javascript
复制
sns.jointplot(x="x", y="y", data=df, kind="kde")
代码语言:javascript
复制
<seaborn.axisgrid.JointGrid at 0x7fd3f0523c18>

你还可以使用kdeplot()函数绘制二维内核密度图,将密度图绘制到特定的(可能已经存在的)matplotlib上

代码语言:javascript
复制
f, ax = plt.subplots(figsize=(6, 6))

sns.kdeplot(df.x, df.y, ax=ax)

sns.rugplot(df.x, color="g", ax=ax)

sns.rugplot(df.y, vertical=True, ax=ax)
代码语言:javascript
复制
<matplotlib.axes._subplots.AxesSubplot at 0x7fd3f069ada0>

如果你希望更连续地显示双变量密度,则可以增加轮廓级别的数量

代码语言:javascript
复制
f, ax = plt.subplots(figsize=(6, 6))

cmap = sns.cubehelix_palette(as_cmap=True, dark=0, light=1, reverse=True)

sns.kdeplot(df.x, df.y, cmap=cmap, n_levels=60, shade=True)
代码语言:javascript
复制
<matplotlib.axes._subplots.AxesSubplot at 0x7fd3f0597fd0>

jointplot()函数使用JointGrid来管理图形,您可以直接使用JointGrid绘制图形。jointplot()在绘制后返回JointGrid对象,你可以使用该对象添加更多层或调整可视化的其他属性。

代码语言:javascript
复制
g = sns.jointplot(x="x", y="y", data=df, kind="kde", color="m")

g.plot_joint(plt.scatter, c="w", s=30, linewidth=1, marker="+")

g.ax_joint.collections[0].set_alpha(0)

g.set_axis_labels("$X$", "$Y$")
代码语言:javascript
复制
<seaborn.axisgrid.JointGrid at 0x7fd3f01c92e8>
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-11-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 好奇心Log 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 单变量可视化
    • 直方图
      • 核密度估计
      • 拟合参数分布
      • 双变量分布可视化
        • 散点图
          • 六边形图
            • 核密度估计
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档