seaborn 常用画图

python seaborn画图

以前觉得用markdown写图文混排的文字应该很麻烦,后来发现CSDN的markdown真是好用的。

在做分析时候,有时需要画几个图看看数据分布情况,但总记不住python的绘图函数。今天有空顺便整理下python的seaborn绘图函数库。 
Seaborn其实是在matplotlib的基础上进行了更高级的API封装,从而使得作图更加容易,在大多数情况下使用seaborn就能做出很具有吸引力的图,而使用matplotlib能制作具有更多特色的图。应该把Seaborn视为matplotlib的补充,而不是替代物。

seaborns是针对统计绘图的,方便啊。

一般来说,seaborn能满足数据分析90%的绘图需求,够用了,如果需要复杂的自定义图形,还是要matplotlit。这里也只是对seaborn官网的绘图API简单翻译整理下,对很多参数使用方法都没有说到,如果需要精细绘图,还是需要参照其seaborn的文档的。

这里简要介绍常用的图形,常用的参数,其精美程度不足以当做报告绘图,算是做笔记吧。

1.几个概念

如果使用过R语言的ggplot2绘图包,对分组分面,统计绘图等概念应该很熟悉,这里也介绍下。

1.1.分组绘图

比如说需要在一张图上绘制两条曲线,分别是南方和北方的气温变化,分别用不同的颜色加以区分。在seaborn中用hue参数控制分组绘图。

1.2.分面绘图

其实就是在一张纸上划分不同的区域,比如2*2的子区域,在不同的子区域上绘制不同的图形,在matplotlib中就是 add_subplot(2,2,1),在seaborn中用col参数控制,col的全称是columns,不是color,如果辅助col_wrap参数会更好些。后来发现,col可以控制columns的子图,那么row可以控制rows的子图排列。 
如果需要分面绘图,应该使用seaborn的FacetGrid对象,seaborn的一般的绘图函数是没有分面这个参数的。

1.3.统计函数

分组绘图的时候,会对分组变量先要用统计函数,然后绘图,比如先计算变量的均值,然后绘制该均值的直方图。统计绘图参数是 estimator,很多情况下默认是numpy.mean。在ggplot2中就大量使用了这种方法。如果不适用统计绘图,就需要先用pandas进行groupby分组汇总,然后用seaborn绘图,多此一举了。

2.图形分类

在seaborn中图形大概分这么几类,因子变量绘图,数值变量绘图,两变量关系绘图,时间序列图,热力图,分面绘图等。

因子变量绘图

  1. 箱线图boxplot
  2. 小提琴图violinplot
  3. 散点图striplot
  4. 带分布的散点图swarmplot
  5. 直方图barplot
  6. 计数的直方图countplot
  7. 两变量关系图factorplot

回归图 
回归图只要探讨两连续数值变量的变化趋势情况,绘制x-y的散点图和回归曲线。

  1. 线性回归图lmplot
  2. 线性回归图regplot

分布图 
包括单变量核密度曲线,直方图,双变量多变量的联合直方图,和密度图

热力图 
1. 热力图heatmap

聚类图 
1. 聚类图clustermap

时间序列图 
1. 时间序列图tsplot 
2. 我的时序图plot_ts_d , plot_ts_m

分面绘图 
1.分面绘图FacetGrid

3.因子变量绘图

3.1.boxplot箱线图


   
   
  1. import seaborn as sns
  2. sns.set_style( "whitegrid")
  3. tips = sns.load_dataset( "tips")
  4. # 绘制箱线图
  5. ax = sns.boxplot(x=tips[ "total_bill"])
  6. # 竖着放的箱线图,也就是将x换成y
  7. ax = sns.boxplot(y=tips[ "total_bill"])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

这里写图片描述


   
   
  1. # 分组绘制箱线图,分组因子是day,在x轴不同位置绘制
  2. ax = sns.boxplot(x= "day", y= "total_bill", data=tips)
  • 1
  • 2

这里写图片描述


   
   
  1. # 分组箱线图,分子因子是smoker,不同的因子用不同颜色区分
  2. # 相当于分组之后又分组
  3. ax = sns.boxplot(x= "day", y= "total_bill", hue= "smoker",
  4. data=tips, palette= "Set3")
  • 1
  • 2
  • 3
  • 4

这里写图片描述


   
   
  1. # 改变线宽,linewidth参数
  2. ax = sns.boxplot(x= "day", y= "total_bill", hue= "time",
  3. data=tips, linewidth= 2.5)
  4. # 改变x轴顺序,order参数
  5. ax = sns.boxplot(x= "time", y= "tip", data=tips,
  6. order=[ "Dinner", "Lunch"])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

   
   
  1. # 对dataframe的每个变量都绘制一个箱线图,水平放置
  2. iris = sns.load_dataset( "iris")
  3. ax = sns.boxplot(data=iris, orient= "h", palette= "Set2")
  • 1
  • 2
  • 3

这里写图片描述

箱线图+有分布趋势的散点图–>的组合图


   
   
  1. # 箱线图+有分布趋势的散点图
  2. # 图形组合也就是两条绘图语句一起运行就可以了,相当于图形覆盖了
  3. ax = sns.boxplot(x= "day", y= "total_bill", data=tips)
  4. ax = sns.swarmplot(x= "day", y= "total_bill", data=tips, color= ".25")
  • 1
  • 2
  • 3
  • 4

这里写图片描述

3.2.violinplot小提琴图

小提琴图其实是箱线图与核密度图的结合,箱线图展示了分位数的位置,小提琴图则展示了任意位置的密度,通过小提琴图可以知道哪些位置的密度较高。在图中,白点是中位数,黑色盒型的范围是下四分位点到上四分位点,细黑线表示须。外部形状即为核密度估计(在概率论中用来估计未知的密度函数,属于非参数检验方法之一)。


   
   
  1. import seaborn as sns
  2. sns.set_style( "whitegrid")
  3. tips = sns.load_dataset( "tips")
  4. # 绘制小提琴图
  5. ax = sns.violinplot(x=tips[ "total_bill"])
  • 1
  • 2
  • 3
  • 4
  • 5

这里写图片描述


   
   
  1. # 分组的小提琴图,同上面的箱线图一样通过X轴分组
  2. ax = sns.violinplot(x= "day", y= "total_bill", data=tips)
  • 1
  • 2

这里写图片描述


   
   
  1. # 通过hue分组的小提琴图,相当于分组之后又分组
  2. ax = sns.violinplot(x= "day", y= "total_bill", hue= "smoker",
  3. data=tips, palette= "muted")
  • 1
  • 2
  • 3

这里写图片描述


   
   
  1. # 分组组合的小提琴图,其实就是hue分组后,各取一半组成一个小提琴图
  2. ax = sns.violinplot(x= "day", y= "total_bill", hue= "smoker",
  3. data=tips, palette= "muted", split= True)
  • 1
  • 2
  • 3

这里写图片描述


   
   
  1. # 调整x轴顺序,同样通过order参数
  2. ax = sns.violinplot(x= "time", y= "tip", data=tips,
  3. order=[ "Dinner", "Lunch"])
  • 1
  • 2
  • 3

这里写图片描述

其他的样式不常用,就不贴上来了。

3.3.stripplot散点图

需要注意的是,seaborn中有两个散点图,一个是普通的散点图,另一个是可以看出分布密度的散点图。下面把它们花在一起就明白了。


   
   
  1. # 普通的散点图
  2. ax1 = sns.stripplot(x=tips[ "total_bill"])
  3. # 带分布密度的散点图
  4. ax2 = sns.swarmplot(x=tips[ "total_bill"])
  • 1
  • 2
  • 3
  • 4

这里写图片描述


   
   
  1. # 分组的散点图
  2. ax = sns.stripplot(x= "day", y= "total_bill", data=tips)
  • 1
  • 2

这里写图片描述


   
   
  1. # 添加抖动项的散点图,jitter可以是0.1,0.2...这样的小数,表示抖动的程度大小
  2. ax = sns.stripplot(x= "day", y= "total_bill", data=tips, jitter= True)
  • 1
  • 2

这里写图片描述


   
   
  1. # 是不是想横着放呢,很简单的,x-y顺序换一下就好了
  2. ax = sns.stripplot(x= "total_bill", y= "day", data=tips,jitter= True)
  • 1
  • 2

这里写图片描述


   
   
  1. # 重点来了,分组绘制,而且是分组后分开绘制,在柱状图中,跟分组柱状图类似的。
  2. # 通过 hue, split 参数控制
  3. # 1.分组
  4. ax = sns.stripplot(x= "sex", y= "total_bill", hue= "day",
  5. data=tips, jitter= True)
  6. # 2.分开绘制
  7. ax = sns.stripplot(x= "day", y= "total_bill", hue= "smoker",
  8. data=tips, jitter= True,palette= "Set2", split= True)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

这里写图片描述 
这里写图片描述


   
   
  1. # 散点图+小提起图
  2. # 两条命令一起运行就行了
  3. ax = sns.violinplot(x= "day", y= "total_bill", data=tips,inner= None, color= ".8")
  4. ax = sns.stripplot(x= "day", y= "total_bill", data=tips,jitter= True)
  • 1
  • 2
  • 3
  • 4

这里写图片描述

3.4.swarmplot带分布的散点图

swarmplt的参数和用法和stripplot的用法是一样的,只是表现形式不一样而已。


   
   
  1. import seaborn as sns
  2. sns.set_style( "whitegrid")
  3. tips = sns.load_dataset( "tips")
  4. ax = sns.swarmplot(x=tips[ "total_bill"])
  • 1
  • 2
  • 3
  • 4

这里写图片描述


   
   
  1. # 分组的散点图
  2. ax = sns.swarmplot(x= "day", y= "total_bill", data=tips)
  • 1
  • 2

这里写图片描述


   
   
  1. # 箱线图+散点图
  2. # whis 参数设定是否显示箱线图的离群点,whis=np.inf 表示不显示
  3. ax = sns.boxplot(x= "tip", y= "day", data=tips, whis=np.inf)
  4. ax = sns.swarmplot(x= "tip", y= "day", data=tips)
  • 1
  • 2
  • 3
  • 4

这里写图片描述


   
   
  1. # 小提琴图+散点图
  2. ax = sns.violinplot(x= "day", y= "total_bill", data=tips, inner= None)
  3. ax = sns.swarmplot(x= "day", y= "total_bill", data=tips,
  4. color= "white", edgecolor= "gray")
  • 1
  • 2
  • 3
  • 4

这里写图片描述

3.5.pointplot

Show point estimates and confidence intervals using scatter plot glyphs. 
使用散点图符号显示点估计和置信区间。

这个我不知道在什么地方用到,不太明白。就先写这个了。

3.6.barplot直方图

我不喜欢显示直方图上面的置信度线,难看,所以下面的图形我都设置ci=0.(Size of confidence intervals to draw around estimated values)

直方图的统计函数,绘制的是变量的均值 estimator=np.mean


   
   
  1. # 注意看看Y轴,看到没,统计函数默认是 mean,
  2. import seaborn as sns
  3. sns.set_style( "whitegrid")
  4. tips = sns.load_dataset( "tips")
  5. ax = sns.barplot(x= "day", y= "total_bill", data=tips,ci= 0)
  • 1
  • 2
  • 3
  • 4
  • 5

这里写图片描述


   
   
  1. # 分组的柱状图
  2. ax = sns.barplot(x= "day", y= "total_bill", hue= "sex", data=tips,ci= 0)
  • 1
  • 2

这里写图片描述


   
   
  1. # 绘制变量中位数的直方图,estimator指定统计函数
  2. from numpy import median
  3. ax = sns.barplot(x= "day", y= "tip", data=tips,
  4. estimator=median, ci= 0)
  • 1
  • 2
  • 3
  • 4

这里写图片描述


   
   
  1. # 改变主题颜色
  2. # palette="Blues_d"
  3. ax = sns.barplot( "size", y= "total_bill", data=tips,
  4. palette= "Blues_d")
  • 1
  • 2
  • 3
  • 4

这里写图片描述

3.7.countplot计数统计图

这个很重要,对因子变量计数,然后绘制条形图


   
   
  1. import seaborn as sns
  2. sns. set(style= "darkgrid")
  3. titanic = sns.load_dataset( "titanic")
  4. ax = sns.countplot(x= "class", data=titanic)
  • 1
  • 2
  • 3
  • 4

这里写图片描述


   
   
  1. # 分组绘图
  2. ax = sns.countplot(x= "class", hue= "who", data=titanic)
  3. # 如果是横着放,x用y替代
  4. ax = sns.countplot(y= "class", hue= "who", data=titanic)
  • 1
  • 2
  • 3
  • 4
  • 5

这里写图片描述

3.8.factorplot

这是一类重要的变量联合绘图。 
绘制 因子变量-数值变量 的分布情况图。


   
   
  1. # 用小提琴图 反应 time-pulse 两变量的分布情形
  2. import seaborn as sns
  3. sns. set(style= "ticks")
  4. exercise = sns.load_dataset( "exercise")
  5. g = sns.factorplot(x= "time", y= "pulse", hue= "kind",
  6. data=exercise, kind= "violin")
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

这里写图片描述


   
   
  1. # 不同的deck(因子)绘制不同的alive(数值),col为分子图绘制,col_wrap每行画4个子图
  2. titanic = sns.load_dataset( "titanic")
  3. g = sns.factorplot(x= "alive", col= "deck", col_wrap= 4,
  4. data=titanic[titanic.deck.notnull()],
  5. kind= "count", size= 2.5, aspect= .8)
  • 1
  • 2
  • 3
  • 4
  • 5

这里写图片描述

4.回归图

回归图有两个,我暂时没有看出他们有什么区别,从函数说明来看看吧。 
lmplot: Plot data and regression model fits across a FacetGrid. 
regplot:Plot data and a linear regression model fit.

4.1.回归图lmplot


   
   
  1. # 线性回归图
  2. import seaborn as sns; sns.set(color_codes= True)
  3. tips = sns.load_dataset( "tips")
  4. g = sns.lmplot(x= "total_bill", y= "tip", data=tips)
  • 1
  • 2
  • 3
  • 4

这里写图片描述


   
   
  1. # 分组的线性回归图,通过hue参数控制
  2. g = sns.lmplot(x= "total_bill", y= "tip", hue= "smoker", data=tips)
  • 1
  • 2

这里写图片描述


   
   
  1. # 分组绘图,不同的组用不同的形状标记
  2. g = sns.lmplot(x= "total_bill", y= "tip", hue= "smoker",
  3. data=tips,markers=[ "o", "x"])
  • 1
  • 2
  • 3

这里写图片描述


   
   
  1. # 不仅分组,还分开不同的子图绘制,用col参数控制
  2. g = sns.lmplot(x= "total_bill", y= "tip", col= "smoker", data=tips)
  • 1
  • 2

这里写图片描述


   
   
  1. # col+hue 双分组参数,既分组,又分子图绘制,jitter控制散点抖动程度
  2. g = sns.lmplot(x= "size", y= "total_bill", hue= "day",
  3. col= "day",data=tips, aspect= .4, x_jitter= .1)
  • 1
  • 2
  • 3

这里写图片描述


   
   
  1. # 分组绘制,控制size尺寸
  2. g = sns.lmplot(x= "total_bill", y= "tip", col= "day", hue= "day",
  3. data=tips, col_wrap= 2, size= 3)
  • 1
  • 2
  • 3

这里写图片描述


   
   
  1. # 既然col可以控制分组子图的,那么row也是可以控制分组子图的
  2. g = sns.lmplot(x= "total_bill", y= "tip", row= "sex",
  3. col= "time", data=tips, size= 3)
  • 1
  • 2
  • 3

这里写图片描述

4.2.回归图regplot

Plot the relationship between two variables in a DataFrame:


   
   
  1. import seaborn as sns; sns. set(color_codes= True)
  2. tips = sns.load_dataset( "tips")
  3. ax = sns.regplot(x= "total_bill", y= "tip", data=tips)
  • 1
  • 2
  • 3

这里写图片描述


   
   
  1. # 控制散点的形状和颜色
  2. import numpy as np; np.random.seed( 8)
  3. mean, cov = [ 4, 6], [( 1.5, .7), ( .7, 1)]
  4. x, y = np.random.multivariate_normal(mean, cov, 80).T
  5. ax = sns.regplot(x=x, y=y, color= "g", marker= "+")
  • 1
  • 2
  • 3
  • 4
  • 5

这里写图片描述


   
   
  1. # 控制回归的置信度,你会看到拟合直线的外面的面积的有变化的
  2. ax = sns.regplot(x=x, y=y, ci= 68)
  • 1
  • 2

这里写图片描述


   
   
  1. # 上面的都是拟合一次曲线,拟合二次曲线通过order=2设置,
  2. # 拟合一次曲线相当于 order=1
  3. ans = sns.load_dataset( "anscombe")
  4. ax = sns.regplot(x= "x", y= "y", data=ans.loc[ans.dataset == "II"],
  5. scatter_kws={ "s": 80},order= 2, ci= None, truncate= True)
  • 1
  • 2
  • 3
  • 4
  • 5

这里写图片描述

5.数值分布绘图

5.1.直方图histplot

直方图hist=True,核密度曲线rug=True


   
   
  1. # 绘制数值变量的密度分布图
  2. # 默认既绘制核密度曲线,也绘制直方图
  3. import seaborn as sns, numpy as np
  4. sns.set(rc={ "figure.figsize": ( 8, 4)}); np.random.seed( 0)
  5. x = np.random.randn( 100)
  6. ax = sns.distplot(x)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

这里写图片描述


   
   
  1. # 只绘制核密度曲线,不绘制直返图
  2. ax = sns.distplot(x, rug= True, hist= False)
  • 1
  • 2

这里写图片描述


   
   
  1. # 横着放
  2. ax = sns.distplot(x, vertical= True)
  • 1
  • 2

这里写图片描述

5.2.核密度图kdeplot


   
   
  1. # 绘制核密度图
  2. import numpy as np; np.random.seed( 10)
  3. import seaborn as sns; sns.set(color_codes= True)
  4. mean, cov = [ 0, 2], [( 1, .5), ( .5, 1)]
  5. x, y = np.random.multivariate_normal(mean, cov, size= 50).T
  6. ax = sns.kdeplot(x)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

这里写图片描述


   
   
  1. # shade参数决定是否填充曲线下面积
  2. ax = sns.kdeplot(x, shade= True, color= "r")
  • 1
  • 2

这里写图片描述


   
   
  1. # 双变量密度图,相当于等高线图了
  2. # shade 参数改用颜色深浅表示密度的大小,不过不用,就真的是等高线了
  3. ax = sns.kdeplot(x, y, shade= True)
  • 1
  • 2
  • 3

这里写图片描述


   
   
  1. # 分组绘制双变量的核密度图
  2. # 相当于绘制两个核密度图,通过图可以看到密度中心
  3. # 类似于挖掘算法中聚类中心绘图
  4. iris = sns.load_dataset( "iris")
  5. setosa = iris.loc[iris.species == "setosa"] # 组1
  6. virginica = iris.loc[iris.species == "virginica"] # 组2
  7. ax = sns.kdeplot(setosa.sepal_width, setosa.sepal_length,
  8. cmap= "Reds", shade= True, shade_lowest= False)
  9. ax = sns.kdeplot(virginica.sepal_width, virginica.sepal_length,
  10. cmap= "Blues", shade= True, shade_lowest= False)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

这里写图片描述

5.3.双变量关系图jointplot

joint,顾名思义,就是联合呀。 
Draw a plot of two variables with bivariate and univariate graphs.

kind参数可以使用不同的图形反应两变量的关系,比如点图,线图,核密度图。


   
   
  1. # 默认绘制双变量的散点图,计算两个变量的直方图,计算两个变量的相关系数和置信度
  2. import numpy as np, pandas as pd; np.random.seed( 0)
  3. import seaborn as sns; sns.set(style= "white", color_codes= True)
  4. tips = sns.load_dataset( "tips")
  5. g = sns.jointplot(x= "total_bill", y= "tip", data=tips)
  • 1
  • 2
  • 3
  • 4
  • 5

这里写图片描述


   
   
  1. # 通过kind参数,除了绘制散点图,还要绘制拟合的直线,拟合的核密度图
  2. g = sns.jointplot( "total_bill", "tip", data=tips, kind= "reg")
  • 1
  • 2

这里写图片描述


   
   
  1. # 使用六角形代替点图图
  2. g = sns.jointplot( "total_bill", "tip", data=tips, kind= "hex")
  • 1
  • 2

这里写图片描述


   
   
  1. # 绘制核密度图
  2. iris = sns.load_dataset( "iris")
  3. g = sns.jointplot( "sepal_width", "petal_length", data=iris,
  4. kind= "kde", space= 0, color= "g")
  • 1
  • 2
  • 3
  • 4

这里写图片描述


   
   
  1. # 控制图形的大小和颜色
  2. g = sns.jointplot( "total_bill", "tip", data=tips,
  3. size= 5, ratio= 3, color= "g")
  • 1
  • 2
  • 3

这里写图片描述

5.4.变量关系组图pairplot

就是绘制dataframe中各个变量两两之间的关系图。 
在变量关系图中,最常见的就是 x-y的线图,x-y的散点图,x-y的回归图。其实这三者都可以通过lmplot绘制,只是控制不同的参数而已。x-y的线图,其实就是时间序列图,这里就不说了。 
这里又说一遍散点图,是为了和前面的因子变量散点图相区分,前面的因子变量散点图,讲的是不同因子水平的值绘制的散点图,而这里是两个数值变量值散点图关系。为什么要用lmplot呢,说白了就是,先将这些散点画出来,然后在根据散点的分布情况拟合出一条直线。但是用lmplot总觉得不好,没有用scatter来得合适。


   
   
  1. # x-y 的散点图,不画回归线,fit_reg=False
  2. tips = sns.load_dataset( "tips")
  3. g = sns.lmplot(x= "total_bill", y= "tip", data=tips,
  4. fit_reg= False,hue= 'smoker',scatter= True)
  5. # 只画回归线,不画散点图,scatter=False
  6. g = sns.lmplot(x= "total_bill", y= "tip", data=tips,
  7. fit_reg= True,hue= 'smoker',scatter= False)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

这里写图片描述 
这里写图片描述


   
   
  1. import seaborn as sns; sns.set(style= "ticks", color_codes= True)
  2. iris = sns.load_dataset( "iris")
  3. g = sns.pairplot(iris)
  • 1
  • 2
  • 3

这里写图片描述


   
   
  1. # 分组的变量关系图,似乎很厉害啊
  2. g = sns.pairplot(iris, hue= "species")
  • 1
  • 2

这里写图片描述


   
   
  1. # hue 分组后,不同的组用不同的形状标记
  2. g = sns.pairplot(iris, hue= "species", markers=[ "o", "s", "D"])
  • 1
  • 2

这里写图片描述


   
   
  1. # 当然也可以只取dataframe中的一部分变量绘图
  2. g = sns.pairplot(iris, vars=[ "sepal_width", "sepal_length"])
  • 1
  • 2

这里写图片描述


   
   
  1. # 对角线默认绘制直方图,当然也可以绘制核密度图
  2. g = sns.pairplot(iris, diag_kind= "kde")
  3. # 相应的,两变量关系图,也可以绘制线性回归图
  • 1
  • 2
  • 3

这里写图片描述

这里写图片描述

6.热力图

6.1.热力图heatmap


   
   
  1. import numpy as np; np.random.seed( 0)
  2. import seaborn as sns; sns. set()
  3. uniform_data = np.random.rand( 10, 12)
  4. ax = sns.heatmap(uniform_data)
  • 1
  • 2
  • 3
  • 4

这里写图片描述


   
   
  1. # 改变颜色映射的值范围
  2. ax = sns.heatmap(uniform_data, vmin= 0, vmax= 1)
  • 1
  • 2

这里写图片描述


   
   
  1. Plot a dataframe with meaningful row and column labels:
  2. # 绘制x-y-z的热力图,比如 年-月-销量 的热力图
  3. flights = sns.load_dataset( "flights")
  4. flights = flights.pivot( "month", "year", "passengers")
  5. ax = sns.heatmap(flights)
  • 1
  • 2
  • 3
  • 4
  • 5

这里写图片描述


   
   
  1. # 绘制热力图,还要将数值写到热力图上
  2. ax = sns.heatmap(flights, annot= True, fmt= "d")
  • 1
  • 2

这里写图片描述


   
   
  1. # 这个图在绘制缺失值分布有用,但是不知道怎么样。
  2. # Plot every other column label and don’t plot row labels
  3. data = np.random.randn( 50, 20)
  4. ax = sns.heatmap(data, xticklabels= 2, yticklabels= False)
  • 1
  • 2
  • 3
  • 4

这里写图片描述

7.聚类图clustermap

暂时不知道怎么用,先这样吧。

8.时间序列图

tsplot函数说是绘制时间序列图,还不如说是绘制简单的线图更加合适吧,因为我在绘制带timestap时间索引的pandas.Series时,并没有自动升采样绘图,只是数据有有什么数据就画什么,这在时间序列上应该是不对的。

因为我遇到这样一种情况,一个产品只在上半年卖,从数据库中取出数据只有每年上半年的数据,下半年没有数据也应该填充为0才对啊,但是seaborn的tsplot没有这个功能。

下面先介绍tsplot绘制线图吧,传入一个list或者series,直接绘制线图。

8.1.tsplot时序图


   
   
  1. # Plot a trace with translucent confidence bands:
  2. # 绘制带有半透明置信带的轨迹:
  3. # data是多组list的组合,这时候应该绘制多条曲线才对啊,其实不是的,是多组list的均值的序列图(默认)
  4. import numpy as np; np.random.seed( 22)
  5. import seaborn as sns; sns.set(color_codes= True)
  6. x = np.linspace( 0, 15, 31)
  7. data = np.sin(x) + np.random.rand( 10, 31) + np.random.randn( 10, 1)
  8. ax = sns.tsplot(data=data)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

这里写图片描述


   
   
  1. # tsplot的参数不太懂,直接上图吧
  2. gammas = sns.load_dataset( "gammas")
  3. ax = sns.tsplot( time= "timepoint", value= "BOLD signal",
  4. unit= "subject", condition= "ROI", data=gammas)
  • 1
  • 2
  • 3
  • 4

这里写图片描述


   
   
  1. # 绘制不同的置信度拟合图,这个好用
  2. ax = sns.tsplot( data= data, ci=[ 68, 95], color= "m")
  • 1
  • 2

这里写图片描述


   
   
  1. # 使用不同的统计函数,默认的是均值,这里是中位数
  2. ax = sns.tsplot( data= data, estimator=np.median)
  • 1
  • 2

这里写图片描述

8.2.panda线图

pandas的dataframe本身也有绘图函数,对于常见的分析图形还是很方便的,而且可以在plot函数中指定title等


   
   
  1. sale4.loc[sale4[ 'sku']== 'SKU412946',[ 'month', 'salecount']]\
  2. .plot(x= 'month',y= 'salecount',title= 'SKU412946')
  • 1
  • 2

这里写图片描述

8.3.采样的时序图

这里重点讲一下。如果时序中每天的数据都有还好说,如果没有,就需要采样了。


   
   
  1. def plot_ts_day(x,y):
  2. """绘制每天的时间序列图。
  3. 需要注意的是,序列是不是连续的,也就是说某天的数据是没有的,因此需要采样至每天都有记录,原来数据没有的就填充0
  4. x:时间轴,string或者time类型,是一个seires
  5. y:值
  6. """
  7. # x转成时间类型Timestamp,y也转成list
  8. x=[pd.to_datetime(str(i)) for i in x]
  9. y=[i for i in y]
  10. s=pd.Series(y,index=x)
  11. s = s.resample(rule= 'D',fill_method= 'ffill') # 生采样没有的会被填充
  12. # 原来没有的就填充为0
  13. s[s.index]= 0
  14. s[x]=y
  15. # 重建索引,画出来的图好看点
  16. x2 = [i.strftime( '%Y-%m-%d') for i in s.index]
  17. s.index = x2
  18. # 画图,这里使用series的plot函数,而不是seaborn.tsplot函数
  19. s.plot()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

这里写图片描述


   
   
  1. def plot_ts_month(x,y):
  2. """绘制月的时间序列图,每月一个数据点,而不是每天一个"""
  3. # 将x转成时间类型timestamp,y也转成list
  4. try:
  5. x = [pd.to_datetime(str(i)) for i in x]
  6. except:
  7. x=[pd.to_datetime(str(i)+ '01') for i in x]
  8. y=[i for i in y]
  9. #
  10. s=pd.Series(y,index=x)
  11. # 降采样至月
  12. s = s.resample( 'M', label= 'right').sum().fillna( 0)
  13. # 重建索引,这样画出来的图好看点
  14. s.index=[i.strftime( '%Y%m') for i in s.index]
  15. s.plot()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

这里写图片描述

8.4.pandas分组的线图

说实话,到现在还没搞懂怎么用sns.tsplot绘制分组线图,但是任务紧急,就用pandas的dataframe自带方法plot来绘图了,其实也挺简单的。 
主要注意的是,尽量给dataframe或者series建立时间索引,不然x轴很难看的。


   
   
  1. # 绘制月销量图
  2. # 数据如下
  3. # year month2 salecount
  4. # 2014 1 531
  5. # 2014 2 505
  6. # 建立索引,'201601'
  7. data.index = data[ 'year'].map(str)+data[ 'month2'].map( lambda x: str(x) if x>= 10 else '0'+str(x))
  8. # 绘图,其实也就是和8.3的方法一致了
  9. data[ 'salecount'].plot()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

分组的线图,比如seaborn中的hue参数,方法是,先将dataframe长表格式转成宽表格式(透视表),每列是不同的年。


   
   
  1. # 分组的线图
  2. # 转成透视表后,绘图
  3. data.pivot( index= 'month2',columns= 'year', values= 'salecount').plot(title= '销量')
  4. # 当数据很大的时候,你想绘制分组的统计图,比如将不同产品,相同的年月的销量进行加或者均值后在绘制线图
  5. # 使用 aggfunc 参数即可,默认是mean
  6. data.pivot_table( index= 'month2',columns= 'year', values= 'salecount',aggfunc= 'sum') \
  7. .plot(title= '销量',style= 'o-')
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

这里写图片描述

图形格式选项


   
   
  1. # 图形参数
  2. # style
  3. # 图形的属性
  4. # 1.color:颜色
  5. # 1.1 r:红色
  6. # 1.2 b:蓝色
  7. # 1.3 g:绿色
  8. # 1.3 y:黄色
  9. #
  10. # 2.数据标记markder
  11. # 2.1 o:圆圈
  12. # 2.2 .:圆点
  13. # 2.2 d:棱形
  14. #
  15. # 3.线型linestyle
  16. # 3.1 没有参数的话就是默认画点图
  17. # 3.2 --:虚线
  18. # 3.3 -:实线
  19. #
  20. # 4.透明度
  21. # alpha
  22. #
  23. # 5.大小
  24. # size
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

   
   
  1. # 绘 "点-线" 图
  2. data.pivot( index= 'month2',columns= 'year', values= 'salecount')\
  3. .plot(title= '销量',style= '-o')
  • 1
  • 2
  • 3

这里写图片描述

9.双坐标轴图

有没有遇到这样一种情况,需要将销量和趋势图和温度的变化图同时画在一幅图上,以便观察两者的趋势变化情况,但是因两者是数值差距很大,如果共用同一Y轴,温度曲线就基本看不到了。还是上图上代码吧。


   
   
  1. import seaborn as sns
  2. sale=pd.Series(np.random.random( 10)* 100). map( int)
  3. tmperature=pd.Series(np.random.random( 10)* 10). map( int)
  4. ax=plt.subplot( 111)
  5. sale.plot(ax=ax,color= 'b')
  6. ax.set_xlabel( 'time')
  7. ax.set_ylabel( 'sale')
  8. # 重点来了,twinx 或者 twiny 函数
  9. ax2 = ax.twinx()
  10. tmperature.plot(ax=ax2,color= 'r')
  11. ax2.set_ylabel( 'tmperature')
  12. plt.title( 'double series figure')
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

这里写图片描述

9.一些技巧

9.1 批量保存图片

如果只有一张图片,这没什么好说的,但是如果要对每个维度绘图,然后保存图片呢。


   
   
  1. fig = plt.figure()
  2. ax=fig.add_subplot( 111)
  3. sub_data[years].plot(ax=ax, style= 'o-',title= '%s 月销量趋势图'%lev3)
  4. file = r'E:\服装预测\销量趋势-%s.jpg' %lev3
  5. savefig(file)
  6. time.sleep( 0.5) # 注意这里要暂停一下,不然会出问题的
  7. plt.close() # 最后记得关闭句柄
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

9.2 显示中文问题


   
   
  1. import seaborn as sns
  2. import matplotlib as mpl
  3. import matplotlib.pyplot as plt
  4. from matplotlib.pyplot import savefig
  5. mpl.rcParams[ 'font.sans-serif'] = [ 'SimHei'] # 指定默认字体
  6. mpl.rcParams[ 'axes.unicode_minus'] = False # 解决保存图像是负号'-'显示为方块的问题
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

10.分段统计绘图

遇到这样一种情况,如下的数据格式,现在platform不是重点,需要对diff_date字段分段汇总然后绘图。


   
   
  1. # platform age cnt
  2. # 2 0 22
  3. # 2 0 40
  4. # 4 0.1 47
  5. # 5 0.1 48
  6. # 3 0.1 51
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

这里借用panas.cut函数,因为是绘图看趋势,不需要精确得到每个分段的分割点。

cut函数有两种使用方法,如果bins=10这样的数值,则将series切成等间隔的10段,如果bins=[0,5,20,55...]这样的一个列表,则根据列表规则切分。


   
   
  1. # 先用pd.cut分段,并取出分段数值
  2. # 通过 precision 控制小数的位数
  3. data[ 'cut_point']=pd.cut(data[ 'age'],
  4. bins=[ 0, 3, 5.9, 8.9, 11.9, 14.8, 17.8, 20.8, 23.8, 26.7, 29.7], # 分割点
  5. labels=[ '0-3', '3-5.9',......] # 区间命名
  6. right= True, # 区间默认是坐开右闭
  7. precision= 1)
  8. # 用sns画图,可以直接汇总每个分段的数量后绘图,而不需要groupby汇总
  9. # 相当于回到前面,用barplot绘图
  10. sns.barplot(x= 'cut_point',y= 'cnt', data=data, estimator=np.sum, ci= 0)
  11. plt.xlabel( '这是横坐标名称')
  12. plt.ylabel( '这是纵坐标名称')
  13. plt.title( '这是图标标题')
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

这里写图片描述

11.分面子图绘图

11.1

接下来好好说说这个比较难的,在10中我们分区间绘图,但是我们没有考虑platform这个因子变量啊,如果我们要考虑这个因子变量,就需要分面了,比如不同的platform画一个子图。


   
   
  1. # 和上面的一样,先分组取出分割点
  2. # 用pd.cut分段,并取出分段数值,通过 precision 控制小数的位数
  3. data[ 'bins']=pd.cut( data[ 'age'], bins= 10,precision= 1)
  4. # 取出分割点,因为cut后得到的是 '(2.99, 5.97]' 这样的字符串
  5. data[ 'cut_point']= data[ 'bins'].apply( lambda x: eval(x.replace( ']', ')'))[ 1])
  6. # 下面重点来了,用FacetGrid进行子图绘制
  7. g=sns.FacetGrid( data= data,col= 'platform',col_wrap= 3,size= 5) # 这里相当于groupby
  8. g=g=g.map(sns.barplot, 'cut_point', 'cnt',ci= 0, estimator=np.sum)
  9. # 很奇怪的是,如果写
  10. # g=g.map(sns.barplot,x='cut_point',y='cnt',ci=0, estimator=np.sum)就报错。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

这里写图片描述

11.2

自定义子图绘制


   
   
  1. def my_barplot(x,y,**kwargs):
  2. """
  3. 自定义函数的时候,没有显示传入dataframe,但是会自动获取,很神奇吧。
  4. x,y是dataframe的列名
  5. """
  6. ax = plt.gca() # 这个是重点,获取对应的ax子图句柄
  7. data[ 'bins']=pd.cut(data[ 'age'], bins= 10,precision= 1)
  8. data[ 'cutpoint']=data[ 'bins'].apply( lambda x: eval(x.replace( ']', ')'))[ 1])
  9. sns.barplot(x= 'cutpoint', y= 'cnt',data=data, estimator=np.sum, ci= 0, ax=ax)
  10. g = sns.FacetGrid(data=data, col= 'platform',col_wrap= 3,
  11. size= 5,sharex= False)
  12. g = g.map(my_barplot, 'age', 'cnt')
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

这里写图片描述

12.颜色主题

主题

在换了win10后发现seaborn的画出来的图很难看,基本上就是matplotlib的样子。想来肯定是主题和颜色样式没有设置好。今天看了下文档,补充下主题的设置。 
seaborn的默认主题就是最好看的,如下:


   
   
  1. import seaborn as sns
  2. sns.set() # 恢复默认主题,在win10中开始的时候要执行一次。
  • 1
  • 2

还有其他几个主题,包括:


   
   
  1. sns.set_style( "whitegrid") # 白色网格背景
  2. sns.set_style( "darkgrid") # 灰色网格背景
  3. sns.set_style( "dark") # 灰色背景
  4. sns.set_style( "white") # 白色背景
  5. sns.set_style( "ticks") # 四周加边框和刻度
  • 1
  • 2
  • 3
  • 4
  • 5

下面来几张图,发现就默认主题和白色网格背景是比较好看。 
这里写图片描述 
这里写图片描述 
这里写图片描述

颜色

颜色一般来说用默认的颜色就好了,而且也比较好看,如果非要设置颜色,可以通过sns.set_palette("husl")设置。 
常用的其他颜色模式还有:


   
   
  1. sns.set_palette( "muted") # 常用
  2. sns.set_palette( "RdBu")
  3. sns.set_palette( "Blues_d")
  4. sns.set_palette( "Set1")
  5. sns.set_palette( "RdBu")
  • 1
  • 2
  • 3
  • 4
  • 5

效果如下图: 
这里写图片描述 
这里写图片描述 
这里写图片描述 
这里写图片描述 
这里写图片描述

13.后话

这里只是简单说说seaborn常用的绘图函数而已,看seaborn官网上面有很多好看的图形样例,而这里的函数画出来的哪里有官网的好看啊。 
而且这里也没有说到具体的布局控制,颜色主题等,要想绘制精美的图形,还需要学习具体的参数设定啊。

不过这里提到的这些简要图形,对于普通的分析快速绘图足够用了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值