分享

Python绘图库之Seaborn(二)

 NeighborMrSun 2023-03-02 发布于湖南

Seaborn绘图

直方图

在Seaborn绘制直方图有三种方式,一个是使用Figure层面的函数,一个是使用Axes层面的函数,另一个是使用object层面的函数。

先看Axes层面的绘制直方图的函数histplot()。执行下面的代码:

import seaborn as sns
import matplotlib.pyplot as plt

sns.set_theme()
fig, ax = plt.subplots(figsize=(6,6))
penguins = sns.load_dataset('penguins')
sns.histplot(data=penguins,x='flipper_length_mm',ax=ax)
plt.show()

程序输出的结果见下图。

Image

绘制直方图主要的参数是分组间隔、或者是组距,分别通过参数bins和binwidth来设置,执行下面的代码:

import seaborn as sns
import matplotlib.pyplot as plt

sns.set_theme(style='ticks')
fig, ax = plt.subplots(figsize=(6,6))
penguins = sns.load_dataset('penguins')
sns.histplot(data=penguins,x='flipper_length_mm',bins=20,ax=ax)
plt.show()

程序输出的结果见下图。

Image

这是直接指定了分组组数,我们也可以指定组距,也就是等距分组,执行下面的代码:

import seaborn as sns
import matplotlib.pyplot as plt

sns.set_theme()
fig, ax = plt.subplots(figsize=(6,6))
penguins = sns.load_dataset('penguins')
sns.histplot(data=penguins,x='flipper_length_mm',color='aquamarine',binwidth=8,ax=ax)
plt.show()

程序输出的结果见下图。

Image

使用参数binrange可以限制绘制直方图的变量取值范围,传递一个列表或者元组即可。执行下面的代码:

import seaborn as sns
import matplotlib.pyplot as plt

sns.set_theme()
fig, ax = plt.subplots(figsize=(6,6))
penguins = sns.load_dataset('penguins')
sns.histplot(data=penguins,x='flipper_length_mm',color='mediumseagreen',
             bins=15,binrange=(200,240),ax=ax)
plt.show()

程序输出的结果见下图。

Image

如果我们想要绘制一个横向的直方图,应该传递什么参数吗?不需要,只需要指定变量在Y轴即可,执行下面的命令:

import seaborn as sns
import matplotlib.pyplot as plt

fig, ax = plt.subplots(figsize=(6,6))
penguins = sns.load_dataset('penguins')
sns.histplot(data=penguins, y='flipper_length_mm',color='thistle',ax=ax)
plt.show()

程序输出的结果见下图。

Image

在绘制直方图时,还可以添加核密度估计曲线,通过参数kde指定,执行下面的代码:

import seaborn as sns
import matplotlib.pyplot as plt

sns.set_theme()
fig, ax = plt.subplots(figsize=(6,6))
penguins = sns.load_dataset('penguins')
sns.histplot(data=penguins, x='flipper_length_mm', kde=True
             color='darkseagreen', ax=ax)
plt.show()

程序输出的结果见下图。

Image

如果你想要调整下窗宽,在估计概率密度函数时。可以使用参数kde_kws,具体地可以参考下面的核密度估计函数kdeplot()。

如果我们想要绘制多个直方图在一张图中,很简单传递整个数据集即可,它默认把所有列作为变量分别绘制直方图,执行下面的代码:

import seaborn as sns
import matplotlib.pyplot as plt

sns.set_theme()
fig, ax = plt.subplots(figsize=(6,6))
iris = sns.load_dataset('iris')
sns.histplot(data=iris, palette='Set2', ax=ax)
plt.show()

程序输出的结果见下图。

Image

上面都是对所有数据的直方图绘制,要是我们想要针对某个变量进行分组数据下的直方图估计呢?还是使用hue参数即可,执行下面的代码:

import seaborn as sns
import matplotlib.pyplot as plt

sns.set_theme()
fig, ax = plt.subplots(figsize=(6,6))
iris = sns.load_dataset('iris')
sns.histplot(data=iris, x='sepal_width', palette='twilight', hue='species', ax=ax)
plt.show()

程序输出的结果见下图。

Image

这是并列绘制的多个直方图,我们能不能绘制堆叠形式的直方图呢?当然可以的,通过参数multiple指定即可。执行下面的代码:

import seaborn as sns
import matplotlib.pyplot as plt

sns.set_theme()
fig, ax = plt.subplots(figsize=(6,6))
iris = sns.load_dataset('iris')
sns.histplot(data=iris, x='sepal_width', palette='turbo', hue='species'
             bins=15, multiple='stack',ax=ax)
plt.show()

程序输出的结果见下图。

Image

上面的直方图都是以bar的形式来绘制的,也就是类似于条形图,这个可以改变不?当然可以,通过参数element即可,执行下面的代码:

import seaborn as sns
import matplotlib.pyplot as plt

sns.set_theme()
fig, ax = plt.subplots(figsize=(6,6))
iris = sns.load_dataset('iris')
sns.histplot(data=iris, x='sepal_width', palette='rainbow', hue='species'
             bins=15, element='step',ax=ax)
plt.show()

程序输出的结果见下图。

Image

上面的直方图绘制的指标都是频数count,能不能绘制频率呢?当然可以,使用参数stat即可,执行下面的代码:

import seaborn as sns
import matplotlib.pyplot as plt

sns.set_theme()
fig, ax = plt.subplots(figsize=(6,6))
tips = sns.load_dataset('tips')
sns.histplot(data=tips, x='total_bill', palette='ocean', hue='sex'
             bins=15, stat='frequency',ax=ax)
plt.show()

程序输出的结果见下图。

Image

Frequency表示不是我们统计中常用的那个频率,它是指频数除以组距,如果我们想要获取频率和组距的比值呢?指定参数stat为'probability'?执行下面的代码:

import seaborn as sns
import matplotlib.pyplot as plt

sns.set_theme()
fig, ax = plt.subplots(figsize=(6,6))
tips = sns.load_dataset('tips')
sns.histplot(data=tips, x='total_bill', palette='YlGnBu', hue='sex'
             binwidth=2, stat='probability',ax=ax)
plt.show()

程序输出的结果见下图。

Image

实际上,指定stat为probability并不是说绘制的统计量是频率除以组距,而直接是指频率,它的解释是使得条形高度之和为1,这便是说指标体系为频率。

那我们怎样子才能使得绘制指标为频率除以组距呢?也就是说我们想要直方图的面积等于1,每一个分组下的条形面积表示频率,这可以说是直方图的经典定义了。只需要指定参数stat为density即可,执行下面的代码:

import seaborn as sns
import matplotlib.pyplot as plt

sns.set_theme()
fig, ax = plt.subplots(figsize=(6,6))
tips = sns.load_dataset('tips')
sns.histplot(data=tips, x='total_bill', palette='YlOrBr', hue='sex'
             binwidth=2.5, stat='density',ax=ax)
plt.show()

程序输出的结果见下图。

Image

这便是真正地使用直方图来估计概率密度的图示方法。

如果我们需要绘制离散型数据的直方图(实际上就应该是柱状图了),只需要指定参数discrete为True即可,执行下面的代码:

import seaborn as sns
import matplotlib.pyplot as plt

sns.set_theme()
fig, ax = plt.subplots(figsize=(6,6))
tips = sns.load_dataset('tips')
sns.histplot(data=tips, x='day', color='palegreen', discrete=True, shrink=0.6, ax=ax)
plt.show()

程序输出的结果见下图。

Image

如果我们想要绘制两个变量的直方图,并排绘制,通过参数multiple指定为'dodge',执行下面的代码:

import seaborn as sns
import matplotlib.pyplot as plt

sns.set_theme()
fig, ax = plt.subplots(figsize=(6,6))
tips = sns.load_dataset('tips')
sns.histplot(data=tips, x='day', hue='sex', multiple='dodge', shrink=.8)
plt.show()

程序输出的结果见下图。

Image

有时候我们需要绘制对数化的直方图,这也很简单,只需要指定参数log_scale为True即可,默认是以10为底数的对数化,执行下面的代码:

import seaborn as sns
import matplotlib.pyplot as plt

sns.set_theme()
fig, ax = plt.subplots(figsize=(6,6))
planets = sns.load_dataset('planets')
sns.histplot(data=planets, x='distance', log_scale=True, ax=ax, color='peachpuff')
plt.show()

程序输出的结果见下图。

Image

如果不想要填充颜色,设置参数fill为False即可,执行下面的代码:

import seaborn as sns
import matplotlib.pyplot as plt

sns.set_theme()
fig, ax = plt.subplots(figsize=(6,6))
planets = sns.load_dataset('planets')
sns.histplot(data=planets, x='distance', log_scale=True, fill=False,ax=ax, color='black')
plt.show()

程序输出的结果见下图。

Image

还可以绘制累积直方图,那么当我们指定stat为probability时,得到的累积直方图不就是经验累积分布函数吗?执行下面的代码:

import seaborn as sns
import matplotlib.pyplot as plt

sns.set_theme()
fig, ax = plt.subplots(figsize=(6,6))
planets = sns.load_dataset('planets')
sns.histplot(data=planets, x='distance', hue='method',
             hue_order=['Radial Velocity''Transit'], element='step'
             fill=False, cumulative=True,stat='probability',log_scale=True, ax=ax)
plt.show()

程序输出的结果见下图。

Image

你会发现,累积直方图显然不是经验累积分布函数,因为最后的求和都不是1,这是为什么呢?首先,这二者根本不是一个概念,累积直方图只是将直方图进行累积求和,而经验分布函数是基于秩来考虑的。

那为什么这里我们指定stat为probability后求和不为一呢?这是因为我们分组了,而且这个分组变量的类别数也不只有两类,只是我们通过参数order_hue指定需要的绘制两个罢了。

实际上,绘制经验分布有专门的函数ecdfplot()。

如果我们想要绘制两个变量的联合直方图呢?只需要指定x,y两个参数即可,执行下面的代码:

import seaborn as sns
import matplotlib.pyplot as plt

sns.set_theme()
fig, ax = plt.subplots(figsize=(6,6))
planets = sns.load_dataset('planets')
sns.histplot(data=planets, x='distance', y='mass', stat='frequency',
             color='violet', cbar=True, ax=ax)
plt.show()

程序输出的结果见下图。

Image

通过指定cbar为True,绘制了颜色bar图。

有关函数histplot()的更多用法请参考这里

https://seaborn./generated/seaborn.histplot.html

再看Figure层面的直方图函数,displot()。它的基本用法和histplot函数是一样的,只需要指定参数kind='hist'即可。执行下面的代码:

import seaborn as sns
import matplotlib.pyplot as plt

sns.set_theme()
penguins = sns.load_dataset('penguins')
fig = sns.displot(data=penguins, kind='hist', x='flipper_length_mm', y='bill_length_mm',
                  color='#808080', cbar=True, height=6, aspect=1)
plt.show()

程序输出的结果见下图。

Image

关于绘制直方图的Figure层面函数displot的更多用法请参考这里

https://seaborn./generated/seaborn.displot.html

再看第三种绘制直方图的方式,使用object方法,执行代码如下:

import seaborn as sns
import seaborn.objects as so

sns.set_theme() # 设置seaborn绘图风格
fmri = sns.load_dataset('fmri')
(
so.Plot
(
data=fmri, x='signal', color='region'
)
.add
(
so.Bars(), so.Hist(stat='density',binwidth=0.05),so.Dodge()
)
.layout(size=(6,6))
.show()
)

程序输出的结果见下图。

Image

三种方法中的object方法是最繁琐的,一般没有特别地需求是不会使用它的。前两个方法足以满足我们的需求了。

核密度估计曲线图

先看Axes层面的函数kdeplot(),主要的参数是窗宽bw_adjust,核估计方法一般是高斯核函数。其他的参数多为分组变量。

如果我们要绘制某单变量的核密度估计曲线图,执行下面的代码:

import seaborn as sns
import matplotlib.pyplot as plt

sns.set_theme()
fig, ax = plt.subplots(figsize=(6,6))
tips = sns.load_dataset('tips')
sns.kdeplot(data=tips, x='total_bill', color='#c79fef', ax=ax)
plt.show()

程序输出的结果见下图。

Image

给定数据集,同时绘制多列变量的核密度估计曲线,执行下面的代码:

import seaborn as sns
import matplotlib.pyplot as plt

sns.set_theme()
fig, ax = plt.subplots(figsize=(6,6))
iris = sns.load_dataset('iris')
sns.kdeplot(data=iris, palette='cool', ax=ax)
plt.show()

程序输出的结果见下图。

Image

给定一个分组变量,也可以绘制多个核密度估计曲线了,执行下面的代码:

import seaborn as sns
import matplotlib.pyplot as plt

sns.set_theme()
fig, ax = plt.subplots(figsize=(6,6))
iris = sns.load_dataset('iris')
sns.kdeplot(data=iris, x='petal_length', palette='cool', hue='species', ax=ax)
plt.show()

程序输出的结果见下图。

Image

使用参数fill来填充曲线下面的面积部分,执行下面的代码:

import seaborn as sns
import matplotlib.pyplot as plt

sns.set_theme()
fig, ax = plt.subplots(figsize=(6,6))
tips = sns.load_dataset('tips')
sns.kdeplot(data=tips, x='total_bill', hue='size', fill=True, common_norm=False
            palette='PRGn', alpha=0.5, linewidth=0, ax=ax)
plt.show()

程序输出的结果见下图。

Image

这里之所以要指定common_norm=False,是为了使得每一个类别下的概率密度曲线的面积为1,而不是所有的密度曲线下面的面积为1。

再看二维核密度估计曲线,执行下面的代码:

import seaborn as sns
import matplotlib.pyplot as plt

sns.set_theme()
fig, ax = plt.subplots(figsize=(6,6))
iris = sns.load_dataset('iris')
sns.kdeplot(data=iris, x='petal_length', y='petal_width', bw_adjust=0.5
            color='yellowgreen',  alpha=0.6, ax=ax)
plt.show()

程序输出的结果见下图。

Image

有关函数kdeplot()的更多参数使用请参考这里

https://seaborn./generated/seaborn.kdeplot.html

再看Figure层面的核密度估计曲线函数,还是displot(),执行下面的代码:

import seaborn as sns
import matplotlib.pyplot as plt

sns.set_theme()
geyser = sns.load_dataset('geyser')
fig = sns.displot(data=geyser, kind='kde', x='waiting', y='duration', hue='kind'
                  fill=True, palette='viridis', height=6, aspect=1)
plt.show()

程序输出的结果见下图。

Image

这个核密度估计曲线就没有第三种方式object函数来实现了。

经验分布函数

绘制经验分布函数图,使用函数ecdfplot()即可。

先看单一变量的经验分布函数图,执行下面的代码:

import seaborn as sns
import matplotlib.pyplot as plt

sns.set_theme()
fig, ax = plt.subplots(figsize=(6,6))
tips = sns.load_dataset('tips')
sns.ecdfplot(data=tips, x='total_bill', color='tab:olive', alpha=0.4, ax=ax)
plt.show()

程序输出的结果见下图。

Image

将多个总体的经验分布函数绘制到同一张图中,使用分组变量hue即可,执行代码如下:

import seaborn as sns
import matplotlib.pyplot as plt

sns.set_theme()
fig, ax = plt.subplots(figsize=(6,6))
iris = sns.load_dataset('iris')
sns.ecdfplot(data=iris, x='petal_length', hue='species'
             palette='inferno', alpha=0.7, ax=ax)
plt.show()

程序输出的结果见下图。

Image

ecdfplot函数有关更多的参数使用请参考这里

https://seaborn./generated/seaborn.ecdfplot.html

下面看Figure层面的绘图函数使用,执行下面的代码:

import seaborn as sns
import matplotlib.pyplot as plt

sns.set_theme()
geyser = sns.load_dataset('geyser')
fig = sns.displot(data=geyser, kind='ecdf', x='waiting', hue='kind'
                  palette='cividis', height=6, aspect=1)
plt.show()

程序输出的结果见下图。

Image

毛毯图

所谓毛毯图就是在轴附近绘制很多短竖线,竖线的密集程度表示分布的密集程度。使用函数rugplot完成的。

绘制某个变量的地毯图,执行代码如下:

import seaborn as sns
import matplotlib.pyplot as plt

sns.set_theme()
fig, ax = plt.subplots(figsize=(6,6))
tips = sns.load_dataset('tips')
sns.rugplot(data=tips, x='tip', ax=ax)
plt.show()

程序输出的结果见下图。

Image

其实,一般不单独地绘制地毯图的,而是配合散点图或者直方图或核密度估计曲线来绘制的。

散点图配合地毯图,执行下面的代码:

import seaborn as sns
import matplotlib.pyplot as plt

sns.set_theme()
fig, ax = plt.subplots(figsize=(6,6))
tips = sns.load_dataset('tips')
sns.scatterplot(data=tips, x='tip', y='total_bill', color='#DDA0DD', alpha=0.6, ax=ax)
sns.rugplot(data=tips, x='tip', ax=ax)
sns.rugplot(data=tips, y='total_bill', ax=ax)
plt.show()

程序输出的结果见下图。

Image

下面再绘制核密度估计曲线和地毯图配合,执行下面的代码:

import seaborn as sns
import matplotlib.pyplot as plt

sns.set_theme()
fig, ax = plt.subplots(figsize=(6,6))
tips = sns.load_dataset('tips')
sns.kdeplot(data=tips, x='tip', color='#DFA099', alpha=0.6, ax=ax)
sns.rugplot(data=tips, x='tip', height=-0.01, clip_on=False, ax=ax)
plt.show()

程序输出的结果见下图。

Image

有关函数rugplot更多的参数用法请参考这里

https://seaborn./generated/seaborn.rugplot.html

Figure层面的函数仍然使用displot,只需要指定参数rug=True即可,绘制地毯图如下:

import seaborn as sns
import matplotlib.pyplot as plt

sns.set_theme()
penguins = sns.load_dataset('penguins')
fig = sns.displot(penguins, kind='kde', x='bill_length_mm', y='bill_depth_mm',
                  rug=True, color='#008080', alpha=0.7, height=6, aspect=1)
plt.show()

程序输出的结果见下图。

Image

第三种方式object函数是没有的,没有现成的接口调用绘制地毯图。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多