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

0.写在前面

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


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()

matplotlib面向对象绘图小白终结版_第2张图片
第一次调用 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() 显示出来:
运行下看看:

matplotlib面向对象绘图小白终结版_第3张图片
空的,啥都没有,你懂得

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)倍。得到如下结果:
matplotlib面向对象绘图小白终结版_第4张图片

2.4.自动创建对象

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

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

直接使用这两个命令就能绘图呀,竟然没有定义画布和坐标轴,得到如下图:
matplotlib面向对象绘图小白终结版_第5张图片
这是因为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()

我们得到了如下图像:
matplotlib面向对象绘图小白终结版_第6张图片
在这里我们创建了两个坐标轴 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()

matplotlib面向对象绘图小白终结版_第7张图片
听中文名字感觉一下,子图?是不是也得添加坐标层才能绘图?
现在只创建子图画布

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()

matplotlib面向对象绘图小白终结版_第8张图片
我们可以看到,我们没有给子图添加坐标层,但是却显示了坐标,和我们之前直接显示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()

matplotlib面向对象绘图小白终结版_第9张图片


此处可以和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()

matplotlib面向对象绘图小白终结版_第10张图片

你懂得,这个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()

matplotlib面向对象绘图小白终结版_第11张图片
同理,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()

就先这样吧,困了......

你可能感兴趣的:(matplotlib,python)