seaborn绘制精美的散点图、柱状图、直方图和核密度图

1,135 阅读9分钟

公众号:尤而小屋
作者:Peter
编辑:Peter

大家好,我是Peter~

seaborn绘制精美图形又更新了:

本文给大家介绍如何使用seaborn绘制4类图形:

  • 散点图scatterplot
  • 柱状图barplot
  • 直方图histplot
  • 核密度估计图kdeplot

1 导入库

In [1]:

import pandas as pd
import numpy as np

import matplotlib
import matplotlib.pyplot as plt
plt.rcParams["font.sans-serif"]=["SimHei"] # 设置字体
plt.rcParams["axes.unicode_minus"]=False # 解决“-”负号的乱码问题

import seaborn as sns
%matplotlib inline 

import warnings
warnings.filterwarnings("ignore")

2 散点图scatterplot

使用内置消费数据集:

In [2]:

tips = sns.load_dataset("tips")
tips.head()

Out[2]:

total_billtipsexsmokerdaytimesize
016.991.01FemaleNoSunDinner2
110.341.66MaleNoSunDinner3
221.013.50MaleNoSunDinner3
323.683.31MaleNoSunDinner2
424.593.61FemaleNoSunDinner4

绘制基础散点图:

In [3]:

sns.scatterplot(data=tips, x="total_bill",y="tip")

plt.show()

使用hue参数进行分组:

1、如果hue参数是分类型,每个组是不同的颜色:

In [4]:

sns.scatterplot(data=tips, x="total_bill",y="tip",hue="day")

plt.show()

2、如果给定的hue是数值型,那么将会是渐变型的颜色:

In [5]:

sns.scatterplot(data=tips, x="total_bill",y="tip",hue="size")

plt.show()

此时如果也想显示不同的颜色,可以再配合使用palette参数:

In [6]:

sns.scatterplot(data=tips, 
                x="total_bill",
                y="tip",
                hue="size", # 分组字段
                palette="deep"  # 使用的调色板
               )

plt.show()

使用style参数将散点标记为不同marker:

1、当hue和style参数是同一个字段:

In [7]:

# hue和style相同

sns.scatterplot(data=tips, x="total_bill",y="tip",hue="time",style="time")

plt.show()

2、当hue和style是不同的字段:

In [8]:

# hue和style不同

sns.scatterplot(data=tips, x="total_bill",y="tip",hue="day",style="time")

plt.show()

size参数表示散点的大小:

In [9]:

sns.scatterplot(data=tips, x="total_bill",y="tip",hue="size",size="size")

plt.show()

通过参数sizes指定点的大小范围:

In [10]:

sns.scatterplot(data=tips, x="total_bill",y="tip",
                hue="size",
                size="size", 
                sizes=(20,200),  # 指定范围
                legend="full"  # 保证每个值出现在图例中
               )

plt.show()

不同markers标记的指定:

In [11]:

markers = {"Lunch": "s", "Dinner": "X"}

sns.scatterplot(data=tips, x="total_bill", y="tip", style="time", markers=markers)

plt.show()

通过marker指定为某个标记,而不是默认的圆点:

In [12]:

sns.scatterplot(data=tips, x="total_bill", y="tip",s=100, marker="+") # 十字星

plt.show()

使用五角星为标记符:

In [13]:

sns.scatterplot(data=tips, x="total_bill", y="tip",s=100, marker="*") # 五角星

plt.show()

通过relplot函数的kind参数指定为scatter也可以实现散点图的绘制:

In [14]:

sns.relplot(data=tips,
            x="total_bill",
            y="tip",
            kind="scatter", # 指定为散点图
            col="time",
            hue="day",
            style="day"
           )

plt.show()

3 柱状图barplot

In [15]:

penguins = sns.load_dataset("penguins")
penguins.head()

Out[15]:

speciesislandbill_length_mmbill_depth_mmflipper_length_mmbody_mass_gsex
0AdelieTorgersen39.118.7181.03750.0Male
1AdelieTorgersen39.517.4186.03800.0Female
2AdelieTorgersen40.318.0195.03250.0Female
3AdelieTorgersenNaNNaNNaNNaNNaN
4AdelieTorgersen36.719.3193.03450.0Female

In [16]:

penguins.columns

Out[16]:

Index(['species', 'island', 'bill_length_mm', 'bill_depth_mm',       'flipper_length_mm', 'body_mass_g', 'sex'],
      dtype='object')

基础柱状图:

In [17]:

sns.barplot(penguins, x="island", y="bill_length_mm")

plt.show()

绘制水平柱状图,只需要将x和y的数据进行对调:

In [18]:

sns.barplot(penguins, x="bill_length_mm", y="island")

plt.show()

使用hue参数进行分组:

In [19]:

sns.barplot(penguins, x="island", y="bill_length_mm", hue="sex")

plt.show()

带上误差棒errorbar:

In [20]:

sns.barplot(penguins, x="island", y="bill_length_mm", errorbar="sd")

plt.show()

航班数据集flights:

In [21]:

flights = sns.load_dataset("flights")

flights.head()

Out[21]:

yearmonthpassengers
01949Jan112
11949Feb118
21949Mar132
31949Apr129
41949May121

生成透视宽表的形式:

In [22]:

# 生成宽表
flights_wide = flights.pivot(index="year", columns="month", values="passengers")
flights_wide

Out[22]:

monthJanFebMarAprMayJunJulAugSepOctNovDec
year
1949112118132129121135148148136119104118
1950115126141135125149170170158133114140
1951145150178163172178199199184162146166
1952171180193181183218230242209191172194
1953196196236235229243264272237211180201
1954204188235227234264302293259229203229
1955242233267269270315364347312274237278
1956284277317313318374413405355306271306
1957315301356348355422465467404347305336
1958340318362348363435491505404359310337
1959360342406396420472548559463407362405
1960417391419461472535622606508461390432

对宽表整体数据的绘图:

In [23]:

sns.barplot(flights_wide)

plt.show()

取消误差棒,同时在x轴上进行求和:

In [24]:

sns.barplot(flights,
            x="year",
            y="passengers",
            estimator="sum",  # 求和的方式
            errorbar=None  # 不显示误差棒
           )

plt.show()

给柱状图添加数据信息:

In [25]:

ax = sns.barplot(flights, x="year", y="passengers", estimator="sum", errorbar=None)

# 添加数据信息
ax.bar_label(ax.containers[0], fontsize=10);

绘制水平柱状图:

In [26]:

sns.barplot(flights,
            x="passengers",
            y="year",
            estimator="sum",  # 求和的方式
            errorbar=None,  # 不显示误差棒
            orient="h"  # h-水平  v-垂直
           )

plt.show()

4 直方图histplot

直方图(Histogram)是一种统计报告图,主要用于表示连续变量(定量变量)的概率分布。这种图由一系列高度不等的纵向条纹或线段组成,通常用横轴表示数据类型,纵轴表示分布情况。

In [27]:

penguins.head()

Out[27]:

speciesislandbill_length_mmbill_depth_mmflipper_length_mmbody_mass_gsex
0AdelieTorgersen39.118.7181.03750.0Male
1AdelieTorgersen39.517.4186.03800.0Female
2AdelieTorgersen40.318.0195.03250.0Female
3AdelieTorgersenNaNNaNNaNNaNNaN
4AdelieTorgersen36.719.3193.03450.0Female

In [28]:

penguins.columns

Out[28]:

Index(['species', 'island', 'bill_length_mm', 'bill_depth_mm',       'flipper_length_mm', 'body_mass_g', 'sex'],
      dtype='object')

垂直方向上的直方图:

In [29]:

sns.histplot(data=penguins, x="bill_length_mm")

plt.show()

水平方向上的直方图:

In [30]:

sns.histplot(data=penguins, y="bill_length_mm")

plt.show()

设置箱体宽度binwidth和箱体个数bins:

In [31]:

sns.histplot(data=penguins, 
             x="bill_length_mm",
             binwidth=0.5,  # 箱体宽度
             bins=30  # 箱体个数
            )

plt.show()

直方图配合KDE图:

In [32]:

sns.histplot(data=penguins, x="bill_length_mm",kde=True)

plt.show()

使用hue参数进行分组:

In [33]:

sns.histplot(data=penguins, x="bill_length_mm",hue="sex")

plt.show()

hue和kde参数配合使用:

In [34]:

sns.histplot(data=penguins, x="bill_length_mm",hue="sex",kde=True)

plt.show()

参数multiple指定直方图叠加方式:

  • layer-默认
  • stack
  • fill
  • dodge

In [35]:

# # 默认是layer
# sns.histplot(data=penguins, 
#              x="bill_length_mm",
#              hue="sex",
#              multiple="layer"   
#             )

# plt.show()

In [36]:

sns.histplot(data=penguins, 
             x="bill_length_mm",
             hue="sex",
             multiple="stack"   #  不同取值['layer', 'stack', 'fill', 'dodge']
            )
plt.show()

使用其他不同的取值:

In [37]:

sns.histplot(data=penguins, 
             x="bill_length_mm",
             hue="sex",
             multiple="fill"   #  不同取值['layer', 'stack', 'fill', 'dodge']
            )

plt.show()

In [38]:

sns.histplot(data=penguins, 
             x="bill_length_mm",
             hue="sex",
             multiple="dodge"   #  不同取值['layer', 'stack', 'fill', 'dodge']
            )
plt.show()

关于shrink参数的使用:分组之间的间隔

In [39]:

sns.histplot(data=penguins, 
             x="bill_length_mm",
             hue="sex",
             multiple="dodge",
             shrink=0.5
            )
plt.show()

关于element参数的使用:

  • bars:默认
  • step
  • poly

In [40]:

sns.histplot(data=penguins, 
             x="bill_length_mm",
             hue="sex",
             element="step"  # ['bars', 'step', 'poly']
            )

plt.show()

In [41]:

sns.histplot(data=penguins, 
             x="bill_length_mm",
             hue="sex",
             element="poly"  #  ['bars', 'step', 'poly']
            )

plt.show()

5 核密度估计图kdeplot

核密度估计(Kernel Density Estimation,简称KDE)是一种非参数的估计方法,用于估计一个随机变量的概率密度函数。

它通过对数据集中的每个点应用一个核函数(如高斯核),然后将所有这些核函数叠加起来,形成一个平滑的密度曲线。这种方法可以很好地捕捉数据的分布特征,尤其是在样本量较小或有异常值时,比传统的直方图和箱线图更能反映数据的真实分布。

基础核密度估计图:

In [42]:

tips.head()

Out[42]:

total_billtipsexsmokerdaytimesize
016.991.01FemaleNoSunDinner2
110.341.66MaleNoSunDinner3
221.013.50MaleNoSunDinner3
323.683.31MaleNoSunDinner2
424.593.61FemaleNoSunDinner4

In [43]:

sns.kdeplot(data=tips, x="tip")

plt.grid()
plt.show()

在水平方向上的核密度图:

In [44]:

sns.kdeplot(data=tips, y="tip")

plt.grid()
plt.show()

鸢尾花iris数据集:

In [45]:

iris = sns.load_dataset("iris")
iris.head()

Out[45]:

sepal_lengthsepal_widthpetal_lengthpetal_widthspecies
05.13.51.40.2setosa
14.93.01.40.2setosa
24.73.21.30.2setosa
34.63.11.50.2setosa
45.03.61.40.2setosa

In [46]:

sns.kdeplot(data=iris)

plt.grid()
plt.show()

调整曲线的平滑度:

In [47]:

sns.kdeplot(data=tips, x="tip",bw_adjust=0.8)

plt.grid()
plt.show()

使用hue进行分组:

In [48]:

sns.kdeplot(data=tips, x="tip",hue="day")

plt.grid()
plt.show()

使用数值型的数据作为hue参数的取值:

In [49]:

sns.kdeplot(data=tips, x="tip",hue="size")

plt.grid()
plt.show()

可以看到颜色是同一个色系的渐变色。也可以改变颜色:

In [50]:

sns.kdeplot(data=tips, 
            x="tip",
            hue="size",
            fill=True,
            common_norm=False,
            palette="Spectral_r",  # 指定调色板
            alpha=0.8,  # 透明度
            linewidth=3  # 线宽
           )

plt.grid()
plt.show()

参数multiple的使用:指定图形的叠加方式

  • layer:默认
  • stack
  • fill

In [51]:

sns.kdeplot(data=tips, 
            x="tip", 
            hue="day", 
            multiple="layer"  # 默认是layer
           )

plt.show()

使用其他不同的参数:

In [52]:

sns.kdeplot(data=tips, 
            x="tip", 
            hue="day", 
            multiple="stack"  # 不同取值['layer', 'stack', 'fill']
           )

plt.show()

In [53]:

sns.kdeplot(data=tips, 
            x="tip", 
            hue="day", 
            multiple="fill"  # 不同取值['layer', 'stack', 'fill']
           )

plt.show()

经验累积分布函数的使用:

In [54]:

sns.kdeplot(data=tips, 
            x="tip", 
            hue="day",
            cumulative=True,
            #common_grid=True,
            common_norm=False
           )

plt.grid()
plt.show()

绘制双变量的核密度估计图:

In [55]:

sns.kdeplot(data=tips, x="total_bill",y="tip")  # 同时指定x-y

plt.show()

指定hue参数进行分组:

In [56]:

sns.kdeplot(data=tips, x="total_bill",y="tip",hue="sex")  

plt.show()

指定fill参数填充区域:

In [57]:

sns.kdeplot(data=tips, x="total_bill",y="tip",hue="sex",fill=True)  

plt.show()

参数thresh表示等高线的阈值:

In [58]:

sns.kdeplot(data=tips,
            x="total_bill",
            y="tip",
            hue="sex",
            levels=5,  #  最多显示的levels数
            thresh=0.2  # 等高线的最小值,只有高于此值的等高线才会显示在图上;提高图的清晰度,排除噪声或低密度的区域
           )  

plt.show()

使用参数cmap代表不同的颜色:

In [59]:

sns.kdeplot(data=tips,
            x="total_bill",
            y="tip",
            hue="sex",
            levels=200,  #  最多显示的levels数
            thresh=0,  # 等高线的最小值,只有高于此值的等高线才会显示在图上;提高图的清晰度,排除噪声或低密度的区域
            cmap="mako"
           )  

plt.show()