matplotlib面向对象绘图小白终结版

7次阅读

共计 4063 个字符,预计需要花费 11 分钟才能阅读完成。

0.写在前面

鄙人以为,在 matplotlib 中还是推荐使用面向对象的方法,因为它可以更好的控制和自定义绘图。
先送各位一张宝贝,这是我从 matplotlib 官方文档中摘下来的,拿走不谢,该图显示了大部分绘图元素:


1. 先看看 Matplotlibpyplotpylab三者的相 (ai) 互(hen)关 (qing) 系(chou)

——该条目摘自官方文档

  • Matplotlib是整个包
  • matplotlib.pyplotmatplotlib中的一个模块;
  • pylab是一个与 matplotlib 一起安装的模块。

Pyplot为底层面向对象的绘图库提供 状态机 接口。状态机 隐式地 自动创建图形和轴 以实现所需的图形,例如:

x = np.linspace(0, 2, 100)

plt.plot(x, x, label='linear')
plt.plot(x, x**2, label='quadratic')
plt.plot(x, x**3, label='cubic')

plt.xlabel('x label')
plt.ylabel('y label')

plt.title("Simple Plot")

plt.legend()

plt.show()


第一次调用 plt.plot 自动创建 必要的图形和轴以实现所需的绘图。随后对 plt.plot 的调用会 重新使用 当前轴,并且每次都会添加另一行。设置标题,图例和轴标签 还会自动使用 当前轴并设置标题,创建图例并分别标记轴。

pylab是一个便利模块,相当于在单个名称空间中批量导入 matplotlib.pyplot(用于绘图)和 numpy 一样(用于数学和使用数组)。不过不推荐使用 pylab,并且由于 命名空间污染 而强烈建议不要使用它。请改用pyplot

2.matplotlib绘图对象感性理解

参考自:
https://finthon.com/matplotli…

2.1.简介

  • Matplotlib中大的对象主要分为三个,FigureCanvas(画布、画布层),Figure(图、图像层),Axes(坐标轴、绘制的区域——轴域、坐标层)(概念划分参考自:https://www.cnblogs.com/dajun…)
  • FigureCanvas(画布) 涉及到底层操作,咱现在的水平就甭接触了 8 [手动滑稽]
  • 可以说使用 matplotlib 绘图,一个非常基础的问题就是要搞清楚 (图像层)和 坐标轴 (坐标层) 俩对象。只有真正了解这两个概念,才能获得对整个绘图过程的控制权。

2.2.Figure对象

import matplotlib.pyplot as plt

plt.figure()
plt.show()

使用 plt.figure() 创建一个 Figure 对象,通过 plt.show() 显示出来:
运行下看看:


空的,啥都没有,你懂得

2.3.axes对象

有了图像层,接下来就在图像层上绘图,因此我们首先需要创建一个坐标轴,可以调用 Figure 实例的 add_axes 方法:

fig = plt.figure()
ax = fig.add_axes([0.1, 0.1, 0.8, 0.8]) # [距离左边,下边,坐标轴宽度,坐标轴高度] 范围(0, 1)
plt.show()

[0.1, 0.1, 0.8, 0.8] 表示的是在 图像层 中,坐标轴区域 (坐标层) 距离画布左边 0.1 倍的位置,距离下边 0.1 倍的位置,确定了这两个位置后,坐标轴的整体宽度和高度占 0.8 倍的大小,换句话说,距离右边和上边 0.9(0.1+0.8) 倍。得到如下结果:

2.4.自动创建对象

如果你之前就接触过一些绘图的命令,你会发现:

plt.plot([0, 1, 2])
plt.show()

直接使用这两个命令就能绘图呀,竟然没有定义画布和坐标轴,得到如下图:

这是因为 matplotlib 会在最近用过的坐标层上进行绘图,如果没有的话,默认会创建一个图对象 ( 图像层 ) 和坐标轴 ( 坐标层 )。但是显示创建图对象( 图像层 ) 和坐标轴 ( 坐标层 ) 的好处是让我们对绘图过程有了完全的控制权(比如可以指定在什么地方绘图),而且绘图的逻辑更强。接下来我们绘制一张图中图来理解这个过程:

import numpy as np
import matplotlib.pyplot  as plt
x = np.linspace(0, 10, 10)
y = np.sin(x)
 
# 创建画布
fig = plt.figure()
# 创建坐标轴
ax1 = fig.add_axes([0.1, 0.1, 0.8, 0.8]) # 第一个坐标轴的范围
ax2 = fig.add_axes([0.2, 0.5, 0.4, 0.3]) # 第二个坐标轴的范围
 
ax1.plot(x, y, 'r')
ax2.plot(x, y, 'g')
plt.show()

我们得到了如下图像:

在这里我们创建了两个坐标轴 ax1ax2,分别对两个坐标层指定范围并作图

2.5.图片尺寸大小

在创建 Figure 对象的时候,我们可以使用 figsizedpi 控制图片尺寸。比如:

fig = plt.figure(figsize=(16,8), dpi=100)

figsize 表示画布长宽大小,单位为英寸;dpi 表示每英寸的像素值。因此上面的命令就创建了一张 1600*800 像素的画布。

2.5.保存图片

从上面输出的结果来看,plt.show() 并不是输出一张图片,而是一个交互式的绘图界面。如果要保存图片,还需要通过 savefig() 保存。没有显式指定画布和坐标轴,直接使用 plt.savefig() 保存也可以,显式指明了图对象 (绘图层) 可以用 Figure 实例的方法 fig.savefig()matplotlib 可以生成多种格式的高质量图像,包括 PNG,JPG,EPS,SVG,PGF 和 PDF,只要写好后缀名即可:

fig.savefig("result.png")

2.6.小结

建议按照显式的方法去绘图:先创建画布,再创建坐标轴,最后在坐标轴上绘图。这种代码方式会让绘图逻辑更加清晰,能够随心所欲的修改图片的每个地方。

3.matplotlib中子图对象AxesSubplot

3.1.先上实例代码感觉一下:

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(1,10,1)
y = np.random.randn(len(x))

fig = plt.figure()  #产生一个画布
ax = fig.add_subplot(111) #在画布上创建一个子图

ax.plot(x,y)
ax.set_title("object oriented")  #设置子图标题

plt.show()


听中文名字感觉一下,子图?是不是也得添加坐标层才能绘图?
现在 只创建子图画布

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(1,100,1)

fig = plt.figure()
ax1 = fig.add_subplot(211)

plt.show()


我们可以看到,我们没有给子图添加 坐标层 ,但是却显示了坐标,和我们之前直接显示plt.figure() 不同。
我们再瞅一眼子图的 “英文名字”——AxesSubplot
你是不是懂了啥?[手动滑稽]
对的,这个子图是自带 绘图层 的,明白了这个那就 ojbk 啦

3.2.接下来,咱们看一看 AxesSubplot 别的用法

绘图层 (figure 对象上)上创建两个子图(一行两列),都显示出来

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(1,100,1)

fig = plt.figure()

ax1 = fig.add_subplot(121)
ax1.plot(x,x)

ax2 = fig.add_subplot(122)
ax2.plot(x,x*x)

plt.show()


此处可以和 pyplot 绘图方式简单对比一下:

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(1,100,1)

plt.subplot(121)
plt.plot(x, x)

plt.subplot(122)
plt.plot(x, x*x)

plt.show()

我就不解释了哈,都能看懂 8


其实,这里还需要解释一下
plt.subplot() fig.add_subplot()参数的含义
若参数传入 231535,显然不匹配,若用 plt.subplot() 则只会显示后者,若用 fig.add_subplot() 则都会显示出来,但有可能会重叠,显然后者在上方

3.3.添加网格

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(1,10)

fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(x,x*2)
ax.grid(color='g',linestyle='--')

plt.show()

你懂得,这个 ax.grid() 对应plt.grid()

3.4.显示图例

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(1,11)

fig = plt.figure()
ax = fig.add_subplot(111)

ax.plot(x,x,label='inline label')
ax.legend()

plt.show()


同理,ax.legend()对应 plt.legend()
以上参考自(有删改):https://zhuanlan.zhihu.com/p/…

3.5.其他对比

AxesSubplot方式 pyplot方式
ax.set_title() plt.title()
ax.set_xlabel() plt.xlabel()
ax.set_ylabel() plt.ylabel()
ax.set_xlim() plt.xlim()
ax.set_ylim() plt.ylim()

就先这样吧,困了 ……

正文完
 0