使用seaborn画图时,经常不知道该该用什么函数、忘记函数的参数还有就是画出来的图单调不好看。
所以,本人对seaborn的一些常用的画图函数,并结合实例写成了代码,方便以后查询和记忆。
若代码或注释有错误,请大佬评论或邮箱指出,感激不尽。
import warnings
warnings.filterwarnings('ignore')
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
Matplotlib is building the font cache using fc-list. This may take a moment.
感谢:
画布主题
五种基本主题
seaborn有五种主题:
- darkgrid
- whitegrid
- dark
- white
- ticks
def sinplot(flip = 1):
x = np.linspace(0,10,100)
for i in range(1,4):
y = np.sin(x + i * 0.5) * (4 - i) * flip
plt.plot(x, y)
sns.set() # 默认主题
sinplot()
sns.set_style("whitegrid") # 白色网格
sinplot()
sns.set_style("white") # 白色
sinplot()
sns.set_style("darkgrid") # 灰色网格
sinplot()
sns.set_style("dark") # 灰色主题
sinplot()
sns.set_style("ticks")
sinplot() # 这个主题比white主题多的是刻度线
带有网格的主题便于读数
## 去掉不必要的边框
sns.set_style("ticks")
sinplot() # 这个主题比white主题多的是刻度线
sns.despine()
去掉了上边框和右边框,despine()还有别的参数,例如offset参数用于设置轴线偏移,跟多参数可以自行搜索。
## 临时设置主题
plt.figure(figsize=(10,8))
sns.set_style('dark')
with sns.axes_style('whitegrid'): # with内部的都是白色网格主题,外部就不起作用了
plt.subplot(2,1,1)
sinplot()
plt.subplot(2,1,2)
sinplot()
标签与图形粗细调整
当需要保存图表时,默认的参数保存下来的图表上刻度值或者标签有可能太小,有些模糊,可以通过set_context()方法设置参数。使保存的图表便于阅读。
有4种预设好的上下文(context),按相对大小排序分别是:paper, notebook, talk,和poster.缺省的规模是notebook。
sns.set()
plt.figure(figsize=(8,3))
sns.set_context("paper")
sinplot()
plt.figure(figsize=(8,3))
sns.set_context("notebook") # 发现刻度值稍微大了点,仔细看现款也是变大了的
sinplot()
plt.figure(figsize=(8,3))
sns.set_context("talk") # 线宽与刻度值都变大了
sinplot()
plt.figure(figsize=(8,3))
sns.set_context("poster") # 这个看起来更加清晰
sinplot()
set_context()方法是有一些参数的,可以调节字体线宽等。
plt.figure(figsize=(8,3))
sns.set_context("notebook", font_scale=1.5,rc={"lines.linewidth": 5})
sinplot() # font_scale字体规模 lines.linewidth线宽
绘图
直方图
sns.set()
x = np.random.normal(size=100) # 生成高斯数据100个
sns.distplot(x) # 如果不想要核密度估计添加参数kde=False
<matplotlib.axes._subplots.AxesSubplot at 0x13b8317e6d8>
sns.distplot(x, bins=20, kde=False) # bins把数据切分为20份
<matplotlib.axes._subplots.AxesSubplot at 0x13b8437c0f0>
散点图
观察两个变量之间的关系,一般使用散点图
mean, cov = [0,1], [(1, 0.5), [0.5, 1]]
data = np.random.multivariate_normal(mean, cov, 500)
data = pd.DataFrame(data, columns=['x', 'y'])
data.head()
x | y | |
---|---|---|
0 | 1.317763 | 2.187347 |
1 | 1.445011 | 2.185577 |
2 | 0.564271 | 1.471409 |
3 | 0.502232 | 0.753561 |
4 | -0.880189 | 1.642289 |
## scatterplot普通散点图
sns.scatterplot('x','y',data=data)
<matplotlib.axes._subplots.AxesSubplot at 0x13b866fd748>
## jointplot散点图同时画出直方图
sns.jointplot('x', 'y', data=data, kind="scatter")
## kind设置类型:'scatter','reg','resid'(残差),'kde'(核密度估计),'hex'
<seaborn.axisgrid.JointGrid at 0x13b86ba7cc0>
六角图
## jointplot六角图可以可视化数据分布密度
with sns.axes_style('white'):
sns.jointplot('x','y',data=data, kind='hex', color='k')
对图
sns.pairplot(data=iris, hue='species')
<seaborn.axisgrid.PairGrid at 0x13b97bd9400>
回归图
tips = sns.load_dataset('tips',engine='python')
tips.head()
total_bill | tip | sex | smoker | day | time | size | |
---|---|---|---|---|---|---|---|
0 | 16.99 | 1.01 | Female | No | Sun | Dinner | 2 |
1 | 10.34 | 1.66 | Male | No | Sun | Dinner | 3 |
2 | 21.01 | 3.50 | Male | No | Sun | Dinner | 3 |
3 | 23.68 | 3.31 | Male | No | Sun | Dinner | 2 |
4 | 24.59 | 3.61 | Female | No | Sun | Dinner | 4 |
sns.regplot(x='total_bill', y='tip', data=tips)
<matplotlib.axes._subplots.AxesSubplot at 0x1eff67ad080>
直线是散点图拟合出来的
f,ax = plt.subplots(2,1,figsize=(8,8))
sns.regplot('size', 'tip', data=tips, ax=ax[0]) # size是离散型数据
sns.regplot('size', 'tip', data=tips, x_jitter=0.1, ax=ax[1])
## x_jitter使数据左右抖动 有助于提高拟合准确度
<matplotlib.axes._subplots.AxesSubplot at 0x1eff682f780>
分类散点图
stripplot()
titanic = sns.load_dataset('titanic', engine='python')
iris = sns.load_dataset('iris', engine='python')
sns.stripplot(x='day', y='total_bill', data=tips, jitter=True)
## jitter=False数据将会发生很多的重叠
<matplotlib.axes._subplots.AxesSubplot at 0x13b88cf1dd8>
swarmplot()
sns.swarmplot(x='day', y='total_bill', data=tips)
## 数据不会发生重叠
<matplotlib.axes._subplots.AxesSubplot at 0x13b88e35d30>
sns.swarmplot(x='total_bill', y='day', data=tips, hue='sex')
## hue对数据进行分类
<matplotlib.axes._subplots.AxesSubplot at 0x13b88e769b0>
箱型图
plt.figure(figsize=(10,6))
sns.boxplot(x='day', y='total_bill', hue='time', data=tips)
<matplotlib.axes._subplots.AxesSubplot at 0x13b8aea8160>
箱型与分类散点组合图
plt.figure(figsize=(10,6))
sns.boxplot(x='day', y='total_bill', data=tips, palette='Purples_r')
sns.swarmplot(x='day', y='total_bill', data=tips)
<matplotlib.axes._subplots.AxesSubplot at 0x13b893e1240>
小提琴图
sns.violinplot(x='total_bill', y='day', hue='sex', data=tips)
## 小提琴左右对称
<matplotlib.axes._subplots.AxesSubplot at 0x13b88d335f8>
## 添加split参数,使小提琴左右代表不同属性
sns.violinplot(x='day', y='total_bill', hue='sex', data=tips, split=True)
<matplotlib.axes._subplots.AxesSubplot at 0x13b8a7e4c88>
小提琴与分类散点组合图
sns.violinplot(x='day', y='total_bill', data=tips, inner=None, palette='Set2')
sns.swarmplot(x='day', y='total_bill', data=tips, color='r', alpha=0.8)
<matplotlib.axes._subplots.AxesSubplot at 0x13b894f87f0>
条形图
sns.barplot(x='sex', y='survived', hue='class', data=titanic)
<matplotlib.axes._subplots.AxesSubplot at 0x13b89552400>
点图
## 更好的显示变化差异
plt.figure(figsize=(8,4))
sns.pointplot(x='sex', y='survived', hue='class', data=titanic)
<matplotlib.axes._subplots.AxesSubplot at 0x13b89528a20>
## 可以把点图做的更加美观
sns.pointplot(x='class', y='survived', hue='sex', data=titanic,
palette={'male':'g', 'female': 'm'}, # 针对male和female自定义颜色
markers=["^", "o"], linestyles=["-", "--"]) # 设置点的形状和线的类型
<matplotlib.axes._subplots.AxesSubplot at 0x13b8ab377f0>
多层面板分类图 factorplot/catplot
点图
sns.factorplot(x='day', y='total_bill', hue='smoker', data=tips)
C:ProgramDataAnaconda3libsite-packagesseaborncategorical.py:3666: UserWarning: The `factorplot` function has been renamed to `catplot`. The original name will be removed in a future release. Please update your code. Note that the default `kind` in `factorplot` (`'point'`) has changed `'strip'` in `catplot`.
warnings.warn(msg)
<seaborn.axisgrid.FacetGrid at 0x13b8abc3908>
发现一个警告,它说factorplot()
方法已经改名为catplot()
,而且在factorplot()
中默认的kind="point"
在catplot()
中变成了默认kind="strip"
那就接下来就用catplot()
方法吧
参数kind:point点图,bar柱形图,count频次,box箱体,violin提琴,strip散点,swarm分散点
分类散点图
sns.catplot(x='day', y='total_bill', hue='smoker', data=tips)
<seaborn.axisgrid.FacetGrid at 0x13b8649d588>
条形图
sns.catplot(x='sex', y='total_bill', hue='day', data=tips, kind='bar')
<seaborn.axisgrid.FacetGrid at 0x13b8befbbe0>
箱型图
sns.catplot(x='sex', y='total_bill', hue='day', data=tips, kind='box', palette='Set3')
<seaborn.axisgrid.FacetGrid at 0x13b8c137e80>
设置图形行列类别
sns.catplot(row='sex', col='smoker', # 设置图表的每行为sex的某个类别,每列为smoker的某个类别
x='day', y='total_bill', data=tips, kind='bar', palette='Set3')
## 纵坐标是对应类别的total_bill的平均值
<seaborn.axisgrid.FacetGrid at 0x13b8db65fd0>
sns.set_style("whitegrid")
sns.catplot(col='day', kind='box', data=tips, x='time', y='total_bill', hue='smoker', aspect=0.5)
plt.show() # aspect是一个比例 aspect*heigh就是宽 默认是1
结构化多绘图网格Facetgrid()
划分图表
grid = sns.FacetGrid(data=titanic, row='survived', col='class')
## 这只是初始化一个绘图的网格,row是行,col是列
## survived有两类 class有三类 所以是2行3列
grid = sns.FacetGrid(data=titanic, col='survived', row='class')
## 同理这个是3行2列
填充图形map()
## 在每个格子画图还需使用map()方法
grid = sns.FacetGrid(data=tips, col='sex')
grid.map(sns.boxplot, 'day', 'total_bill', palette='Set2')
## day和total_bill分别是每个图的x y轴的数据
C:ProgramDataAnaconda3libsite-packagesseabornaxisgrid.py:715: UserWarning: Using the boxplot function without specifying `order` is likely to produce an incorrect plot.
warnings.warn(warning)
<seaborn.axisgrid.FacetGrid at 0x13b903852e8>
grid = sns.FacetGrid(data=tips, col='sex', row='smoker')
grid.map(sns.barplot, 'day', 'total_bill', palette='Set2')
C:ProgramDataAnaconda3libsite-packagesseabornaxisgrid.py:715: UserWarning: Using the barplot function without specifying `order` is likely to produce an incorrect plot.
warnings.warn(warning)
<seaborn.axisgrid.FacetGrid at 0x13b9067a390>
添加分类标签add_legend()
grid = sns.FacetGrid(data=tips, row='smoker', hue='sex')
grid.map(sns.scatterplot, 'tip', 'total_bill', alpha=0.5)
grid.add_legend() # 添加分类标签
<seaborn.axisgrid.FacetGrid at 0x13b9369ea58>
title位置设置
grid = sns.FacetGrid(data=tips, col='sex', row='smoker', margin_titles=True)
## 标题加在旁边margin_titles=True;margin n.边缘 vt.加旁注于
grid.map(sns.regplot, 'size', 'total_bill', x_jitter=.3)
<seaborn.axisgrid.FacetGrid at 0x13b93754ba8>
设置横纵比
grid = sns.FacetGrid(data=tips, col='day')
grid.map(sns.barplot, 'sex', 'total_bill', color="0.5") # color设置颜色浓度
C:ProgramDataAnaconda3libsite-packagesseabornaxisgrid.py:715: UserWarning: Using the barplot function without specifying `order` is likely to produce an incorrect plot.
warnings.warn(warning)
为什么会那么的矮小?
查看参数height aspect
:
height : scalar, optional
Height (in inches) of each facet. See also: ``aspect``.
aspect : scalar, optional
Aspect ratio of each facet, so that ``aspect * height`` gives the width
height
:每个面的高度(英尺)
aspect
:每个面的横纵比,aspect*height
可以得出width
而默认的height=3 aspect=1
,那么width = aspect*height = 1*3 = 3
,所以显得比较矮小
UserWarning: The `size` paramter has been renamed to `height`; please update your code. 就是说size参数就是现在height参数,改名了,应该是改成height比size好理解
## 长宽比设置
grid = sns.FacetGrid(data=tips, col='day', height=4, aspect=0.5)
grid.map(sns.barplot, 'sex', 'total_bill', color="0.5") # 这样就美观多了
C:ProgramDataAnaconda3libsite-packagesseabornaxisgrid.py:715: UserWarning: Using the barplot function without specifying `order` is likely to produce an incorrect plot.
warnings.warn(warning)
自定义图形排列顺序
## 先重新设置tips数据中day属性的顺序:[Thur, Fri, Sat, Sun]
from pandas import Categorical
ordered_days = tips.day.value_counts().index
print(ordered_days) # ordered=False说明原本是乱序排列的,看来pandas可以识别星期
print("-------------")
ordered_days = Categorical(['Thur','Fri','Sat','Sun']) # 将其按顺序排列
print(ordered_days)
CategoricalIndex(['Sat', 'Sun', 'Thur', 'Fri'], categories=['Thur', 'Fri', 'Sat', 'Sun'], ordered=False, dtype='category')
-------------
[Thur, Fri, Sat, Sun]
Categories (4, object): [Fri, Sat, Sun, Thur]
在传输参数的时候,尽量使用pandas numpy
的格式,一般都是默认支持的,其他格式的可能会报各种错误。
grid = sns.FacetGrid(data=tips, row='day', row_order=ordered_days, # row_order指定行顺序
height=1.5, aspect=4)
grid.map(sns.boxplot, 'total_bill')
C:ProgramDataAnaconda3libsite-packagesseabornaxisgrid.py:715: UserWarning: Using the boxplot function without specifying `order` is likely to produce an incorrect plot.
warnings.warn(warning)
自定义轴标签 轴取值 子图之间的间隔
with sns.axes_style('white'):
grid = sns.FacetGrid(data=tips, row='sex', col='smoker',height=2.5)
grid.map(sns.scatterplot, 'total_bill', 'tip', edgecolor='red') # 点的边缘颜色
grid.set_axis_labels("Total Bill($)", "Tip") # 自定义轴标签
grid.set(xticks=[10, 30, 50], yticks=[2, 6, 10]) # 自定义轴取值
grid.fig.subplots_adjust(wspace=0.02, hspace=0.2)
## wspace左右部分空间间隔 hspace上下部分空间间隔
热度图
data = np.random.randn(3, 3)
print(data)
sns.heatmap(data)
plt.show() # 根据右侧的颜色棒可以看出每个数据的大小
[[ 0.62915095 -1.12225355 -0.52421596]
[-1.4004364 -1.07996694 -0.8255331 ]
[ 0.13171013 0.96617229 -0.26060623]]
sns.heatmap(data, vmax=0.5, vmin=0.5)
plt.show() # vmax vmin分别设置颜色棒的最大最小值
flights = pd.read_csv(r'data/flights.csv')
## flights数据集我直接在seaborn上加载一直报错,所以我就下载了一个
## https://github.com/mwaskom/seaborn-data/blob/master/flights.csv
注意传入的数据的格式:
data : rectangular dataset
2D dataset that can be coerced into an ndarray. If a Pandas DataFrame
is provided, the index/column information will be used to label the
columns and rows.
矩形数据集
可以被强制转换成ndarray的2D数据集。
如果是Pandas DataFrame的话,索引/列信息将用于标记行和列。
## pivot() 可以将dataframe转换为行列式矩阵 并指定每个元素的存储值
flights = flights.pivot(index='month', columns='year', values='passengers')
print(flights)
plt.figure(figsize=(10,6))
ax = sns.heatmap(flights, fmt='d', linewidths=.5)
## fmt设置字体模式 linewidth设置每个小方格的间距 线宽
year 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959
month
April 129 135 163 181 235 227 269 313 348 348 396
August 148 170 199 242 272 293 347 405 467 505 559
December 118 140 166 194 201 229 278 306 336 337 405
February 118 126 150 180 196 188 233 277 301 318 342
January 112 115 145 171 196 204 242 284 315 340 360
July 148 170 199 230 264 302 364 413 465 491 548
June 135 149 178 218 243 264 315 374 422 435 472
March 132 141 178 193 236 235 267 317 356 362 406
May 121 125 172 183 229 234 270 318 355 363 420
November 104 114 146 172 180 203 237 271 305 310 362
October 119 133 162 191 211 229 274 306 347 359 407
September 136 158 184 209 237 259 312 355 404 404 463
year 1960
month
April 461
August 606
December 432
February 391
January 417
July 622
June 535
March 419
May 472
November 390
October 461
September 508
plt.figure(figsize=(10,6))
sns.heatmap(flights, fmt='d', linewidths=.5, cmap='YlGnBu')
## cmap修改颜色,这个颜色我觉得好看也清晰
<matplotlib.axes._subplots.AxesSubplot at 0x1effa0132b0>
plt.figure(figsize=(10,6))
sns.heatmap(flights, fmt='d', linewidths=.5, cmap='YlGnBu', annot=True)
## annot 如果为真,则在每个单元格中写入数据值。
## 如果一个数组形状与“数据”相同,然后用它来注释热图原始数据的。
<matplotlib.axes._subplots.AxesSubplot at 0x1effa068e48>