数据处理之可视化之 Seaborn

王 茂南 2018年4月30日21:24:11
评论
8509字阅读28分21秒
摘要这一篇文章是上一篇matplotlib的后续篇,我们会使用seaborn来进行图像的美化操作。在这里记录一下seaborn的常用用法。

Seaborn 介绍

之前我们学习了 Matplotlib 的一些内容(Python数据处理之 Matplotlib 学习),但是使用 Matplotlib 调整出非常漂亮的效果时,往往会伤透脑筋,非常麻烦。

Seaborn 基于 Matplotlib 核心库进行了更高级的 API 封装,可以让你轻松地画出更漂亮的图形。而 Seaborn 的漂亮主要体现在配色更加舒服、以及图形元素的样式更加细腻。

 

Seaborn 的安装

  1. pip install seaborn

如果上述命令无法安装,可以使用下面的命令进行安装

  1. sudo pip install git+https://github.com/mwaskom/seaborn.git

如果想要使得 seaborn 可以正常显示中文,可以在 sns.set() 的时候直接指定字体。

  1. sns.set(font='SimHei')  # 解决Seaborn中文显示问题

 

Seaborn 基础

使用 Seaborn 的样式

使用seaborn来优化图像操作起来是很方便的。下面我们来对比一下优化前和优化后。

  1. x = np.linspace(0, 1,100)
  2. fig = plt.figure()
  3. ax = fig.add_subplot(1,1,1)
  4. ax.set_title(u'This is Title')
  5. # 四个参数分别表示x,y轴数据,'b--'表示颜色是蓝色样式是虚线,最后一个表示标签,支持LaTex
  6. ax.plot(x, x ** 2, 'b.', label=r'$y = x^{2}$')
  7. # 自动生成图例
  8. ax.legend()
  9. # 设置图像x,y轴的范围,都是从0-1
  10. ax.axis([0, 1, 0, 1])
  11. fig.show()
数据处理之可视化之 Seaborn

下面我们来进行优化。优化的方式也是很简单的,只需要使用下面两步:

  1. import seaborn as sns # 导入 seaborn 模块
  2. sns.set()

下面看一下完整的代码:

  1. import seaborn as sns # 导入 seaborn 模块
  2. sns.set()
  3. x = np.linspace(0, 1,100)
  4. fig = plt.figure()
  5. ax = fig.add_subplot(1,1,1)
  6. ax.set_title(u'This is Title')
  7. # 四个参数分别表示x,y轴数据,'b--'表示颜色是蓝色样式是虚线,最后一个表示标签,支持LaTex
  8. ax.plot(x, x ** 2, 'b.', label=r'$y = x^{2}$')
  9. # 自动生成图例
  10. ax.legend()
  11. # 设置图像x,y轴的范围,都是从0-1
  12. ax.axis([0, 1, 0, 1])
  13. fig.show()
数据处理之可视化之 Seaborn

可以看到背景变成了浅灰色的网格,字体也稍微做了调整。我们在上面的sns.set()使用了默认的参数,分别如下:

  1. sns.set(context='notebook', style='darkgrid', palette='deep', font='sans-serif', font_scale=1, color_codes=False, rc=None)

其中:

  • context='' 参数控制着默认的画幅大小,分别有 {paper, notebook, talk, poster} 四个值。其中,poster > talk > notebook > paper。
  • style='' 参数控制默认样式,分别有 {darkgrid, whitegrid, dark, white, ticks}
  • palette='' 参数为预设的调色板。分别有 {deep, muted, bright, pastel, dark, colorblind} 等。
  • 剩下的 font='' 用于设置字体,font_scale= 设置字体大小,color_codes= 不使用调色板而采用先前的 'r' 等色彩缩写。

在这里我就不一一去演示了。

 

使用 Seaborn 绘制子图

我们可以使用 Seaborn 结合 matplotlib 来绘制子图。为了绘制子图,我们只需要在 sns 的 ax 中进行指定,指定子图即可

  1. import seaborn as sns
  2. import matplotlib.pyplot as plt
  3. flights = sns.load_dataset("flights")
  4. flights_wide = flights.pivot("year", "month", "passengers")
  5. fig, axs = plt.subplots(2, 1, figsize=(10, 4*2), facecolor='w', edgecolor='k', sharex=True)
  6. # 绘制第一个子图
  7. sns.lineplot(data=flights_wide["Jan"], ax=axs[0], label='Jan')
  8. sns.lineplot(data=flights_wide["Feb"], ax=axs[0], label='Feb')
  9. # 绘制第二个子图
  10. sns.lineplot(data=flights_wide["Mar"], ax=axs[1], label='Mar')
  11. sns.lineplot(data=flights_wide["Apr"], ax=axs[1], label='Apr')
  12. sns.lineplot(data=flights_wide["May"], ax=axs[1], label='May')
  13. plt.show()

最终的效果如下所示:

数据处理之可视化之 Seaborn

 

使用 Seaborn 自定义 label

我们有的时候使用 seaborn 需要自定义 x-label 和 y-label。在 seaborn 中会返回 axis-object,接着对 axis-object 进行自定义即可。下面是一个例子:

  1. import pandas as pd
  2. import seaborn as sns
  3. import matplotlib.pyplot as plt
  4. fake = pd.DataFrame({'cat': ['red', 'green', 'blue'], 'val': [1, 2, 3]})
  5. ax = sns.barplot(x = 'val', y = 'cat',
  6.               data = fake,
  7.               color = 'black')
  8. ax.set(xlabel='common xlabel', ylabel='common ylabel')
  9. plt.show()

结果如下图所示,可以看到我们 x 和 y 上面的 label 分别被修改成了 common xlabelcommon ylabel

数据处理之可视化之 Seaborn

 

使用 label 自定义 ticklable

我们继续完善上面的例子,我们希望对 xticklabel 和 yticklabel 进行自定义。例如自定义内容,和旋转角度。于是我们只需要加上下面两行即可:

  1. ax.set_xticklabels([0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0], rotation=-45, va="center")
  2. ax.set_yticklabels(['Label1', 'Label2', 'Label3'], rotation=45, va="center")

下面是最终输出的结果:

数据处理之可视化之 Seaborn

下面是完整的代码,相比上面,只是添加了两行(也就是 ax.set_xticklabelax.set_yticklabel):

  1. import pandas as pd
  2. import seaborn as sns
  3. import matplotlib.pyplot as plt
  4. fake = pd.DataFrame({'cat': ['red', 'green', 'blue'], 'val': [1, 2, 3]})
  5. ax = sns.barplot(x = 'val', y = 'cat',
  6.               data = fake,
  7.               color = 'black')
  8. ax.set(xlabel='common xlabel', ylabel='common ylabel')
  9. ax.set_xticklabels([0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0], rotation=-45, va="center")
  10. ax.set_yticklabels(['Label1', 'Label2', 'Label3'], rotation=45, va="center")
  11. plt.show()

我们还可以进一步对 tick label 进行设置,下面是一个例子。关于详细的例子,可以查看 Rotating axis labels in matplotlib and seaborn

  1. graph.set_xticklabels(
  2.     graph.get_xticklabels(),
  3.     rotation=45,
  4.     horizontalalignment='right',
  5.     fontweight='light',
  6.     fontsize='x-large'
  7. )

 

Seaborn 自定义图片边框

我们可以指定图的「内边距」和「子图内的空间」,从而使得图像不会显示不完全。

  1. plt.subplots_adjust(wspace=0.6, hspace=0.6, left=0.1, bottom=0.22, right=0.96, top=0.96)

但是,另一个问题是如何在 subplot_adjust 中指定上述参数的值,那么答案是使用 subplot_tool 。 在显示绘图之前放置以下代码,然后会出现一个弹出窗口,您可以使用这些值并找到您喜欢的值。

  1. plt.subplot_tool()

我们加入上面一行代码后运行,如下图所示。可以看到会出现一个交互框,我们可以在里面调整图的「内边距」和「子图内的空间」,并且可以非常直观的显示在图像中。

数据处理之可视化之 Seaborn

 

使用 Seaborn 绘制基础图像

绘制线形图

我们使用 lineplot 来绘制折线图。下面放一个简单的例子,具体的用法可以查看官方文档。现在我们生成如下的测试数据:

  1. x = np.arange(-3, 3, 0.05)
  2. y1 = x
  3. y2 = x ** 2
  4. y3 = np.sin(x)
  5. data = pd.DataFrame(np.array([y1, y2, y3]).T, columns=['x', 'x^2', 'sin(x)'], index=x)

生成的样例数据如下所示:

数据处理之可视化之 Seaborn
  1. sns.lineplot(data=data)
  2. plt.show()
数据处理之可视化之 Seaborn

 

柱状图

我们可以利用 barchat 来绘制柱状图,同时使用 axhline 来绘制水平线。下面是参考代码:

  1. #Importing the necessary libraries
  2. import seaborn as sns
  3. import matplotlib.pyplot as plt
  4. #Loading the dataset into the variable 'dataset'
  5. dataset = sns.load_dataset("iris")
  6. dataset.head()
  7. #Graph is created and stored in the variable 'graph'
  8. graph = sns.barplot(x="sepal_width",y="petal_width",data=dataset)
  9. #Drawing a horizontal line at point 1.25
  10. graph.axhline(1.25)
  11. #The plot is shown
  12. plt.show()

运行上面的代码,我们可以获得以下的结果。可以看到其中包含着「柱状图」和「水平线」。

数据处理之可视化之 Seaborn

我们可以更进一步,对「水平线」添加一些样式,和 label,然后使用 legend 来进行显示。

  1. graph.axhline(1.25, linestyle='dashed', label="horizontal")
  2. plt.legend()

参考资料Adding a horizontal line in a Seaborn plot in Python

 

seaborn.lmplot-二维散点图+拟合

seaborn.lmplot()是一个非常有用的方法,它会在绘制二维散点图时,自动完成回归拟合。在sns中, 我们使用regplot也是可以完成拟合的, 但是Implot这个方法更加高级一些. 我们用官方文档里的话来说明一下.

This function combines regplot() and FacetGrid. It is intended as a convenient interface to fit regression models across conditional subsets of a dataset.

  1. import numpy as np
  2. import pandas as pd
  3. from pandas import Series,DataFrame
  4. # 载入绘图模块
  5. import matplotlib.pyplot as plt
  6. import seaborn as sns
  7. # 创建数据
  8. data_x = np.arange(1,100,2)
  9. data_y = 2*data_x+np.random.normal(10,30,len(data_x))
  10. data = DataFrame({'x': data_x, 'y': data_y})
  11. # 绘图
  12. sns.lmplot(x='x', y='y',data=data)
  13. plt.show()

 

数据处理之可视化之 Seaborn

除了上面的基础的使用之外, 我们还是可以设置图像的长宽比例, 同时对多组数据进行回归. 我们下面看一个简单的例子.

其中:
  • hue可以表示不同的label
  • aspect表示绘制结果的长宽比例
  1. data_x = np.arange(1, 100, 2)
  2. data_y = 2*data_x+np.random.normal(10,30,len(data_x))
  3. data_label = np.random.randint(low=0,high=2,size=50)
  4. data = pd.DataFrame({'x':data_x, 'y':data_y, 'label':data_label})
  5. temp = data[data['label']==1]['x'].values
  6. data.loc[data['label']==1,'x'] = temp*2 + np.random.normal(10,30,len(temp))
  7. # 绘图
  8. sns.lmplot(x='x', y='y', hue='label', data=data, aspect=1.5)
  9. plt.show()
最终绘制的结果如下图所示: 数据处理之可视化之 Seaborn  

seaborn.PairGrid

seaborn.PairGrid()可以用来查看两个维度数据之间的关系,用处当然也非常多了。比如,方便我们在数据分析过程中找出强关联特征。

  1. import numpy as np
  2. import pandas as pd
  3. from pandas import Series,DataFrame
  4. # 载入绘图模块
  5. import matplotlib.pyplot as plt
  6. import seaborn as sns
  7. # 创建数据
  8. data_1 = np.arange(1,100,2)
  9. data_2 = 2*data_x+np.random.normal(10,30,len(data_1))
  10. data_3 = np.random.random(len(data_1))
  11. col = np.random.choice(['1a','2b','3c'],len(data_1)) #这个用来分类
  12. data = DataFrame({'x': data_1, 'y': data_2,'z':data_3,'col':col})
  13. # 绘图
  14. sns.PairGrid(data=data).map(plt.scatter)
  15. plt.show()
数据处理之可视化之 Seaborn

可以看到自动将3个维度的数值进行两两配对,绘制出9张散点图,并且我们还可以加上颜色,按照分类来绘制

  1. import numpy as np
  2. import pandas as pd
  3. from pandas import Series,DataFrame
  4. # 载入绘图模块
  5. import matplotlib.pyplot as plt
  6. import seaborn as sns
  7. # 创建数据
  8. data_1 = np.arange(1,100,2)
  9. data_2 = 2*data_x+np.random.normal(10,30,len(data_1))
  10. data_3 = np.random.random(len(data_1))
  11. col = np.random.choice(['1a','2b','3c'],len(data_1)) #这个用来分类
  12. data = DataFrame({'x': data_1, 'y': data_2,'z':data_3,'col':col})
  13. # 绘图
  14. sns.PairGrid(data=data,hue='col').map(plt.scatter)
  15. plt.show()
  数据处理之可视化之 Seaborn  

seaborn.distplot

绘制关于数据的分布. 下面是从两个正态分布抽样, 并绘制出分布. 首先产生数据.
  1. # p(x)
  2. mu_target = 3.5
  3. sigma_target = 1
  4. p_x = [np.random.normal(mu_target, sigma_target) for _ in range(3000)]
  5. # q(x)
  6. mu_appro = 3
  7. sigma_appro = 1
  8. q_x = [np.random.normal(mu_appro, sigma_appro) for _ in range(3000)]
接着进行数据的可视化.
  1. fig = plt.figure(figsize=(10,6))
  2. ax = fig.add_subplot(1,1,1)
  3. # 画出两个分布的图像
  4. sns.distplot(p_x, label="distribution $p(x)$")
  5. sns.distplot(q_x, label="distribution $q(x)$")
  6. plt.title("Distributions", size=16)
  7. plt.legend()
最终的结果如下所示: 数据处理之可视化之 Seaborn  

seaborn.PairGrid

最后我们来看一下绘制单变量和双变量的组合个图。这部分可以参考以下的链接Seaborn JointGrid 说明文档

  1. import numpy as np
  2. import pandas as pd
  3. from pandas import Series,DataFrame
  4. # 载入绘图模块
  5. import matplotlib.pyplot as plt
  6. import seaborn as sns
  7. # 创建数据
  8. data_x = np.arange(1,100,2)+np.random.normal(5,20,50)
  9. data_y = 2*data_x+np.random.normal(10,30,len(data_x))
  10. data = DataFrame({'x': data_x, 'y': data_y})
  11. # 绘图
  12. sns.JointGrid(x='x', y='y',data=data).plot(sns.regplot,sns.distplot)
  13. plt.show()

代码最后的 sns.JointGrid().plot() 用于设置图形的样式,在这里我们将双变量设置为散点图,而上面和右边的单变量设置为直方图,于是就可以得到下面的效果了。

数据处理之可视化之 Seaborn

除了上面的方式外,我们还可以通过指定「ax」的方式来绘制,如下面的例子所示:

  1. g = sns.JointGrid()
  2. # 导入数据
  3. penguins = sns.load_dataset("penguins")
  4. x, y = penguins["bill_length_mm"], penguins["bill_depth_mm"]
  5. # 绘制图像
  6. sns.scatterplot(x=x, y=y, ax=g.ax_joint)
  7. sns.lineplot([0, 60], [0, 20], linewidth=1, ax=g.ax_joint) # 绘制直线
  8. sns.histplot(x=x, fill=False, linewidth=2, ax=g.ax_marg_x)
  9. sns.kdeplot(y=y, linewidth=2, ax=g.ax_marg_y)

结果如下图所示,我们还在图中添加了一条直线(通过上面第九行,在 seaborn 的图中填了一个直线,也就是图中的虚线):

数据处理之可视化之 Seaborn

  • 微信公众号
  • 关注微信公众号
  • weinxin
  • QQ群
  • 我们的QQ群号
  • weinxin
王 茂南
  • 本文由 发表于 2018年4月30日21:24:11
  • 转载请务必保留本文链接:https://mathpretty.com/9314.html
匿名

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: