MENU

Data visualization: Matplotlib的OOP绘图基础

• September 23, 2019 • Read: 4050 • Knowledge,Data Visualization

Python中,一切皆为对象;Matplotlib库对于数据的可视化,依然也是全面支持OOP范式的。这一种风格的好处是几乎能够绘制任意图片,但是,对于初学者来说来有点不太友好。

基础概念

figure与axes对象

figure可以理解为一个画布,而这个画布上可以绘制1个图,也可以绘制若干个图,这样我们称这些子图为axes对象。每当进行数据可视化时,首先要确定的就是这个图片中有几个子图,以及子图在画布中如何分布。

利用以下的命令来完成

import matplotlib.pyplot as plt

# 画布中只有一个子图
fig, ax = plt.subplots(11)  # 当为11时,可以省略plt.subplots()

说明:这一命令产生的画布对象为fig;由于只有1个子图,所以ax只有一个元素,表示子图。

当在画布中具有多个子图时,具体意义如下:

fig, ax = plt.subplots(2, 1)  # 子图总数为2*1, 为2行1列分布
# 因为具有2个子图,所以这里ax代表的是一个元组,元组的第一个元素为第一个子图
# 第二个元素为第二个子图
# 为了方便,常常会直接进行子图对象的unpack
fig, (ax0, ax1) = plt.subplots(2, 1)
# 这样在随后的调用上直接可以利用ax0, 或者ax进行使用。

绘图的第一步目的就是确定Figure和Axes对象,上述的subplots只是实现的一种方式。还可以采用Figure对象的add_subplot()来增加子图对象。这一方法的用法与API中提供的subplot函数意义基本一致。

# 先创建Figure对象
fig = plt.figure()
# 然后在画布中,创建第一个子图
# .add_subplot方法中前两个参数为子图的布局网格大小,
# 第三个指定这次创建子图是哪一个位置的
ax0 = fig.add_subplot(2,1,1)  # 在2*1的布局中,创建第一个子图ax0
ax1 = fig.add_subplot(2, 1, 2)  # 创建第二个子图

以上就是OOP绘图方式中,最为常用的创建“画布”与“子图”的方式。

OOP绘图的理解

对于OOP方式的绘图方式,它提供了一个良好的思考与构思的前提,为了进行绘制,操作者必须事先对于想要得到的图有一个预先的设想,要大致确定这个图片中应当具有哪些元素,它们的构成情况。这样从OOP的方式来看,就不难理解这一种绘图方式了。核心思想就是“有什么?”。

首先,当我们要进行绘图时,第一步创建了一个画布Figure对象(称为fig),那么这个图中假设只有一个图,那么就是子图数量为1,子图一定是画在画布上,所以,在画布上创建子图;然后,在子图中进行各种图形的绘制,标签、曲线,图例等都是上一级对象的子项,都是依存于上一级对象的。所以,这一种绘图方法是一种从浅到深的过程,有什么就去创建!

在子图Axes中绘制你想要的东西

真正的绘图其实是在Axes(子图)中进行 的。在子图中,要想绘制曲线图,那么就在ax上面用plot进行创建,要什么对象就用什么对应的函数进行创建。

除了“曲线”外,子图上还有一些其他元素十分重要!比如子图的标题、标签、坐标轴标签、网格等。主要的一些图片组成元素如下:

  • 曲线
  • 数据标签,legend
  • 题目title
  • 网格,grid
  • 坐标轴名,xlabel, ylabel

这些元素的实现,均采用Axes中的set_....方法进行。如:

# 绘制散点图
ax.scatter()
# 设置坐标轴名字
ax.set_xlabel('x')
ax.set_ylabel('y')
# 设置标题
ax.set_title('xxxxx')
# 标签
ax.legend(变量, loc='best')
# 网格
ax.grid()

Example

# 绘制2*1的图
# 数据准备
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(0, 2 * np.pi, 50)
y = x * 1.25
# 栅格化数据点
xx, yy = np.meshgrid(x, y)
# 计算各个点处的函数值
z = np.sin(xx) + np.cos(yy)  # z是一个矩阵,大小50*50

# 数据可视化
fig, (ax0, ax1) = plt.subplots(2, 1)
# 在ax0上绘制一个等值线图,由于colorbar需要确
# 定数据源,因此用cb来命名”图“
cb = ax0.contourf(xx, yy, z, cmap='RdBu_r', levels=12)
fig.colorbar(cb, ax=ax0)  # colorbar是属于figure的
ax0.set_title('contourf image')

cs = ax1.contour(xx, yy, z, cmap='RdBu_r', levels=12)
ax1.clabel(cs, inline=True)  # 等值线上的值
fig.colorbar(cs, ax=ax1)
ax1.set_title('contour image')
fig.savefig('testoop.png', dpi=600)
plt.show()

等值线云图

Last Modified: October 6, 2019
Archives Tip
QR Code for this page
Tipping QR Code