EDA → 可视化 ← 数形结合

前言

Python有许多用于数据可视化的库,例如常见的有seaborn、pyecharts(echarts的Python版本)、ggplot(移植于R语言的ggplot2,但是有些差别,Python有其他方法可以调用R语言的ggplot2)、bokeh、Plotly(同时支持Python和R语言)等等,这些大多是基于Matplotlib进行开发封装的。

因此,不管你想要用哪个库,matplotlib都是必须要学的。虽然他语法复杂,但是灵活性大,你几乎能画出任何你想要的图形。

参考资料:知乎讨论:Python中除了matplotlib外还有哪些数据可视化的库?

1. 认识Matplotlib

Matplotlib是一个Python 2D绘图库(使用Matplotlib发布的mpl_toolkits库可以画3D图形 ),能够以多种硬拷贝格式和跨平台的交互式环境生成出版物质量的图形,用来绘制各种静态,动态,交互式的图表。

Matplotlib 是 Python 最著名的绘图库,它提供了一整套和 MATLAB 相似的命令 API,十分适合交互式地进行制图。而且也可以方便地将它作为绘图控件,使用在Python脚本,Python和IPython Shell、Jupyter notebook,Web应用程序服务器和各种图形用户界面工具包等上面。

2.Matplotlib 例子

2.1 例子1

Matplotlib的图像是画在figure(如windows,jupyter窗体)上的,每一个figure又包含了一个或多个axes(一个可以指定坐标系的子区域)。最简单的创建figure以及axes的方式是通过pyplot.subplots命令,创建axes以后,可以使用Axes.plot绘制最简易的折线图。

声明:以下使用的是IPython Shell

  1. %matplotlib # 在IPython Shell调用Matplotlib绘图接口,需要加这行代码
  2. import matplotlib.pyplot as plt
  3. import numpy as np
  4. fig, ax= plt.subplots() # 创建一个包含一个axes的figure
  5. # 绘图
  6. ax.plot([1, 2, 3, 4], [1, 4, 3, 2])

这里有一个小知识点,很小很小,但是对于刚刚接触数据可视化的新手可能容易弄混。
ax.plot([1, 2, 3, 4], [1, 4, 3, 2]) 这句代码里面第一个参数是数据集里各个数据点的X值的集合,第二个参数数据集里各个数据点的Y值的集合。
所以这里输入的参数值并不是数学上常见的成对坐标点如(x1,y1)、(x2,y2)、…、(xn,yn)的格式,而是 (x1,x2,…,xn)和(y1,y2,…,yn)
Task01:初识Matplotlib - 图1

2.2 例子2

和MATLAB命令类似,你还可以通过一种更简单的方式绘制图像,matplotlib.pyplot 方法能够直接在当前axes上绘制图像,如果用户未指定axes,matplotlib会帮你自动创建一个。所以上面的例子也可以简化为以下这一行代码。

  1. plt.plot([1, 2, 3, 4], [1, 4, 2, 3])

Task01:初识Matplotlib - 图2
这里有个trick(坑)需要注意一下。如上所示,在IPython或jupyter notebook的同一个代码框中,如果不对其声明画在哪个图上(可以使用 plot() 函数里面的 ax 参数进行指定),就会自动画到最后一个创建的图上(即最后一个Figure对象的最后一个Axes子图里)。

  1. plt.figure() # 创建一个新的Figure对象
  2. plt.plot([1, 2, 3, 4], [1, 4, 2, 3])

Task01:初识Matplotlib - 图3

更多例子可以在Matplotlib官网查看:

https://matplotlib.org/gallery/index.html

3.Figure的组成

现在我们来深入看一下figure的组成。通过一张figure解剖图,我们可以看到一个完整的matplotlib图像通常会包括以下四个层级,这些层级也被称为容器(container),下一节会详细介绍。在matplotlib的世界中,我们将通过各种命令方法来操纵图像中的每一个部分,从而达到数据可视化的最终效果,一副完整的图像实际上是各类子元素的集合。

  • Figure:顶层级,用来容纳所有绘图元素。
  • Axes:matplotlib宇宙的核心,容纳了大量元素用来构造一幅幅子图,一个figure可以由一个或多个子图组成。
  • Axis:axes的下属层级,用于处理所有和坐标轴,网格有关的元素。
  • Tick:axis的下属层级,用来处理所有和刻度有关的元素。

Task01:初识Matplotlib - 图4

4. 两种绘图接口

matplotlib提供了两种最常用的绘图接口

  1. 显式创建figure和axes,在上面调用绘图方法,也被称为OO模式(object-oriented style)。
  2. 依赖pyplot自动创建figure和axes,并绘图。

使用第一种绘图接口,是这样的:

  1. x = np.linspace(0, 2, 100)
  2. fig, ax = plt.subplots()
  3. ax.plot(x, x, label='linear')
  4. ax.plot(x, x**2, label='quadratic')
  5. ax.plot(x, x**3, label='cubic')
  6. ax.set_xlabel('x label')
  7. ax.set_ylabel('y label')
  8. ax.set_title("Simple Plot")
  9. ax.legend()

Task01:初识Matplotlib - 图5

而如果采用第二种绘图接口,绘制同样的图,代码是这样的:

plt.figure() IPython 里面需要加这行,jupyter notebook则不用,原因见<2.2 例子2>。

  1. x = np.linspace(0, 2, 100)
  2. plt.figure() # IPython里面需要加这行,jupyter notebook则不用
  3. plt.plot(x, x, label='linear')
  4. plt.plot(x, x**2, label='quadratic')
  5. plt.plot(x, x**3, label='cubic')
  6. plt.xlabel('x label')
  7. plt.ylabel('y label')
  8. plt.title("Simple Plot")
  9. plt.legend()

Task01:初识Matplotlib - 图6

5.讨论

5.1 在工作或学习中通常何时会用到数据可视化,希望通过可视化达到什么目的?

个人经验:

  • ① 在机器学习中,数据可视化经常用于各种算法模型拟合效果的直观展示

例子1:线性回归模型的拟合效果。
Task01:初识Matplotlib - 图7

例子2:机器学习聚类算法的K-MEANS算法和DBSCAN算法对数据集划分类别的效果对比。

下图来源:K-MEANS可视化网站https://www.naftaliharris.com/blog/visualizing-k-means-clustering/
Task01:初识Matplotlib - 图8

下图来源:DBSCAN算法可视化网站
https://www.naftaliharris.com/blog/visualizing-dbscan-clustering/
Task01:初识Matplotlib - 图9

  • ② 在数据分析和数据挖掘中经常用来检查数据的分布,以及窥探数据集内在的规律或事件发展的规律。
    以下是个人在数据分析和数据挖掘中使用到数据可视化的2个案例。

例1:使用黄氏曲线评估零售店促销活动效果

例2:Kaggle项目:Predict Future Sales(商品未来销量预测)

5.2 OO模式和pyplot模式的区别与联系

问题详细:
OO模式和pyplot模式这两者的区别和联系是啥?或者说它们各自的优缺点是啥?
我们又应该优先选择哪种方式呢?

个人理解:

  • ① pyplot模式可以说比较简单粗暴吧。直接在Figure对象上生成图片 (本人的水平有限,不代表底层原理的实际实现)。像Pandas模块集合了pyplot的接口,可以使用pandas.DataFrame.plot()直接出图,但是相比OO模式,缺少了一些个性化的选择。

  • ② OO模式是在Axes上生成图片的 (本人的水平有限,不代表底层原理的实际实现) ,可以实现的不止多子图这么简单,有一些Axes和Axis接口,只有OO模式可以实现,例如双坐标轴、colorbar等等。

例子:Plots with different scales

  1. import numpy as np
  2. import matplotlib.pyplot as plt
  3. t = np.arange(0.01, 10.0, 0.01)
  4. data1 = np.exp(t)
  5. data2 = np.sin(2 * np.pi * t)
  6. fig, ax1 = plt.subplots()
  7. color = 'tab:red'
  8. ax1.set_xlabel('time (s)')
  9. ax1.set_ylabel('exp', color=color)
  10. ax1.plot(t, data1, color=color)
  11. ax1.tick_params(axis='y', labelcolor=color)
  12. ax2 = ax1.twinx()
  13. color = 'tab:blue'
  14. ax2.set_ylabel('sin', color=color)
  15. ax2.plot(t, data2, color=color)
  16. ax2.tick_params(axis='y', labelcolor=color)
  17. fig.tight_layout()
  18. plt.show()

Task01:初识Matplotlib - 图10

  • ③ 在我自己的使用中,一些基础图像一般是用pandas.DataFrame.plot()接口,直接从数据到出图;如果是比较复杂的图形,一般都采用OO模式。有时候也会配合使用seaborn,让图像更美观一些。