初识matplotlib——主要概念及两种编码

目录

一、概念

(一)Figure:图

(二)Axes:轴域

        创建包涵 Axes 的 Figure 的三种主要方法

(三)Axis:轴

(四)Artist:

二、绘图

(一)数据类型

三、编码风格

(一)OO样式:显式接口

(二)pyplot方式

关于pyplot.gca:

(三)对比:


先安装好,并导入包:

import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np

一、概念

面向对象编程,需要画布(FigureCanvas)、图像(Figure)、坐标轴(Axes) 

(一)Figure:图

        Matplotlib在图(Figure)(例如,窗口,Jupyter小部件等)上绘制数据,这个 figure 相当于拉出一个画板,一幅基本的图有下面这些基本结构:标题(Title)、图例(Legend)、x、y轴标签(xlabel、ylabel)等

        现在创建一个空图,拿出一块空画板:

fig= plt.figure()    # 一个没有 axes 的画板
plt.show()

        也可以调出多个Figure,执行几次 plt.figure() 就会有几个 figure,并且定位的是最新创建的figure

fig1=plt.figure(1)
fig2=plt.figure(2)
plt.show()

(二)Axes:轴域

        个人感觉轴域可以理解为由定义域和值域组成的一个画纸,是一个可以根据各个坐标指定点的绘图区域(或者极坐标图中的θ-r,3D图中的x-y-z)。

        这个画纸在画板上,它通常包括两个轴(Axis)对象。两个轴分别提供刻度(ticks)和标签(tick label),表示图中数据的比例。每个轴域还有一个标题(通过 set_title())设置)、一个 x 标签(通过 set_xlabel()) 设置)和一个y 标签(通过 set_ylabel()) 设置)。

        创建带有Axes的图的最简单方法是使用 plt.subplot(x,y,z)(x行y列,z为下标),然后,我们可就可以在轴域上绘制一些数据的图形了:

fig,ax = plt.subplots()    # 1个axes
plt.show()

        创建包涵 Axes 子图的 Figure 的三种主要方法

  • axes = fig.add_axes([left, bottom, width, height])
  • fig, axes = plt.subplots(行数, 列数)
  • axes = fig.add_subplot(行数, 列数, 序号)--最后一个参数代表当前选定第几个子图

        相比起上面的图,这里多了两条轴

        可以创建多个 Axes 的Figure:

fig, axs = plt.subplots(nrows=2,ncols=2)    # 2行2列4个axes
plt.show()

         前面两个都是被赋值的变量,随机命名,看看fig和ax是什么:

fig, ax = plt.subplots()
plt.show()
print(fig)
print(ax)

Figure(640x480)
Axes(0.125,0.11;0.775x0.77)    # 定义了一个图和轴域

        subplots 可以创建多个轴域,subplot 则可以用于定位 current axes(当前需要操作的axes)且当没有 figure 时,subplot会自动创建一个figure

ax3=plt.subplot(2,2,3)    # 2行2列,第三个轴域
plt.show()

        将上面的语法总结一下:

        Axes 类及其成员函数是使用 OOP 接口的主要入口点,并且在其上定义了大多数绘图方法,以供Axes对象使用(如上使用的plot方法)

        

(三)Axis:轴

        轴设置刻度和上下限,并且生成刻度(ticks,轴上的标记)和刻度标签(ticklabels,标记刻度的字符串)ticks位置由定位器(Locator)确定,ticklabel 字符串由格式器(Formatter)设置。正确的定位器(Locator)和格式器(Formatter)的组合可以对刻度位置和标签进行非常精细的控制

(四)Artist:

        所有画板上可视的元素都是Artist(如上面的轴和轴域),绝大多数Artist和轴域相关并绑定,不能共享或直接移动,如上面的标题、轴标签、刻度等组成图形的所有元素都是Artist对象的实例

简单类型Artist对象:标准的绘图元件,如Line2D,Rectangle,Text,AxesImage等

容器类型Artist对象:含多个Artist对象使他们组织成一个整体如Axis,Axes,Figure对象

使用Artist对象进行绘图流程:

  1. 创建Figure对象
  2. 为Figure对象创建一个/多个Axes对象
  3. 调用Axes对象的方法得到各种简单的Artist对象

二、绘图

(一)数据类型

        绘图函数接收 numpy.array 或 numpy.ma.masked_array 作为输入(numpy.ma 是 numpy 的一个子模块,详见https://www.cnblogs.com/ShineLeBlog/p/15546092.html),或者是可以被传递给 numpy.asarray 的数据(用于转换为array)。一些类似于数组的类,如 pandas 数据或 numpy.matrix 可能不会正常工作。

        常见的约定是在绘图前将数据转换成 numpy.array。例如,要使用 np.asarray() 将 numpy.matrix 转换成 np.array 类型:

b = np.matrix([[1, 2], [3, 4]])
b_asarray = np.asarray(b)

        大多方法还可以解析 dict、ndarray、dataframe 等可寻址对象,Matplotlib允许使用关键字参数生成图像,传递和x,y相应的字符串:

1、生成3组随机数组

np.random.seed(19680801)  # seed the random number generator.
data = {'a': np.arange(50),
        'c': np.random.randint(0, 50, 50),
        'd': np.random.randn(50)}

        random.seed() 俗称为随机数种。不设置随机数种子,你每次随机抽样得到的数据都是不一样的。设置了随机数种子,能够确保每次抽样的结果一样。而 random.seed() 括号里的数字,相当于一把钥匙,对应一扇门,同样的数值能够使得抽样的结果一致。

 2、对于b列,生成一个正态分布数组做线性变换,元素 * 10,+ a,这个矩阵与c不是同一个!

data['b'] = data['a'] +( 10 * np.random.randn(50))
data['d'] = np.abs(data['d']) * 100
print(data['b'])
print(data['d'])

 3、画图,两个轴域:

fig, axes = plt.subplots(nrows=2,ncols=1)

        fig 拥有2行1列,共两个子图,存放在axes数组(np.array类型)中。

# 轴域1
ax = axes[0]
ax.scatter('a', 'b', c='c', s='d', data=data)
ax.set_xlabel('entry a')
ax.set_ylabel('entry b')        # x、y的名

# 轴域2 ,对轴域1去掉颜色参数c,形状参数s参数。
ax2 = axes[1]
ax2.scatter('a', 'b', data=data)
plt.show()

print(ax,ax2)
Axes(0.125,0.53;0.775x0.35) Axes(0.125,0.11;0.775x0.35)

        axes[0] 赋给 ax,axes[1] 赋给 ax2,可以对这些对象使用 matplotlib 里的方法

三、编码风格

        显示与隐式接口,使用Matplotlib基本上有两种方法:

  • 显式地创建图形和轴,并调用它们上的方法(“面向对象(OO)风格”)。
  • 依靠pyplot隐式创建和管理图和轴域,并使用pyplot函数进行绘制。pyplot 是 Matplotlib 的子库,提供了和 MATLAB 类似的绘图 API

        可以参考:Matplotlib中的plt和ax都是啥?_IT农民工1的博客-CSDN博客 总结得很简单

(一)OO样式:显式接口

        该接口的工作方式是实例化一个 Figure 类的实例,在该对象上使用 subplots 或其他方法创建一个/多个Axes对象,然后调用 Axes 上的绘图方法对图中的各种对象进行操作,从面向对象编程的角度来看,这种方式更加易于解释(如下例中的 plot 方法):

        先生成一些数据

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

[0.         0.02020202 0.04040404 0.06060606 0.08080808 0.1010101
 0.12121212 0.14141414 0.16161616 0.18181818 0.2020202  0.22222222
 0.24242424 0.26262626 0.28282828 0.3030303  0.32323232 0.34343434
 0.36363636 0.38383838 0.4040404  0.42424242 0.44444444 0.46464646
 0.48484848 0.50505051 0.52525253 0.54545455 0.56565657 0.58585859
 0.60606061 0.62626263 0.64646465 0.66666667 0.68686869 0.70707071
 0.72727273 0.74747475 0.76767677 0.78787879 0.80808081 0.82828283
 0.84848485 0.86868687 0.88888889 0.90909091 0.92929293 0.94949495
 0.96969697 0.98989899 1.01010101 1.03030303 1.05050505 1.07070707
 1.09090909 1.11111111 1.13131313 1.15151515 1.17171717 1.19191919
 1.21212121 1.23232323 1.25252525 1.27272727 1.29292929 1.31313131
 1.33333333 1.35353535 1.37373737 1.39393939 1.41414141 1.43434343
 1.45454545 1.47474747 1.49494949 1.51515152 1.53535354 1.55555556
 1.57575758 1.5959596  1.61616162 1.63636364 1.65656566 1.67676768
 1.6969697  1.71717172 1.73737374 1.75757576 1.77777778 1.7979798
 1.81818182 1.83838384 1.85858586 1.87878788 1.8989899  1.91919192
 1.93939394 1.95959596 1.97979798 2.        ]

1、创建 figure,规格为5 * 2.7,尝试了一下 layout 参数的功能应该是控制边距

# 在OO样式中,同样使用`.pyplot.figure`来创建figure。
fig, ax = plt.subplots(figsize=(5, 2.7), layout='constrained')
plt.show()

# 好理解一点的方式:subplots会自动创建axes,相当于
fig = plt.figure()
ax = fig.subplots()

2、在axes上根据数据画图,label 标明指图例,但要加上 ax.legend() 才能显示出来:

ax.plot(x, x, label='linear')  # Plot some data on the axes.
plt.show()
ax.legend()

 3、可以在同一 Axes 上作多个图:

4、设计x、y轴的标签及标题:

ax.set_xlabel('x label')  # Add an x-label to the axes.
ax.set_ylabel('y label')  # Add a y-label to the axes.
ax.set_title("Simple Plot")  # Add a title to the axes.
ax.legend()
plt.show()

        由于每个对象被显示地引用了(上例中的 fig 与 ax),并可以用于新的对象,所以称为显示接口,对象之间彼此灵活地关联,我们可以在图片结果显示出来之前对其进行自由定义

(二)pyplot方式

        与OO样式类似,只是这里 plt 的使用函数式绘图方法,Figure 和 Axes 已为用户自动地创建了,拥有与上述OO接口相同的绘图方法

        对比两组代码:

x = np.linspace(0, 2, 100)
plt.figure(figsize=(5, 2.7), layout='constrained') # 尝试去掉这句代码是否可以绘制?
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()

 (pyplot)

fig, ax = plt.subplots(figsize=(5, 2.7), layout='constrained')
ax.plot(x, x, label='linear') 
ax.plot(x, x**2, label='quadratic')
ax.plot(x, x**3, label='cubic')
ax.set_xlabel('x label') 
ax.set_ylabel('y label')
ax.set_title("Simple Plot")
ax.legend()
plt.show()

(OO显示接口) 

关于pyplot.gca:

        在 matplotlib 中有当前 figure当前 axes 的概念,gca() 函数的作用就是定位轴域 axes 。plt.plot() 相当于对特定轴域可以用 plt.gca() 方法获得当前对象(Get Current Axes),这个函数不接受任何参数也不返回任何值,接下来的绘图操作都是针对 plt.gca() 所获得的轴域

        例一:

plt.figure(figsize=(5, 2.7), layout='constrained')
# 创建Figure

plt.subplot(1,2,1)
ax1=plt.gca()
ax1.plot(x)
# 轴域1

plt.subplot(1,2,2)
ax2=plt.gca()
ax2.plot(x)
# 轴域2

ax1.plot(x**3)
# 由于 gca() 的存在我们可以在后续继续对ax1进行自定义

plt.show()

        程序从上到下、从左到右运行,可以看到这段代码运行的效果:创建Figure——创建Axes —— 获取当前 Axes —— 绘图 —— 再次创建 —— 再次获取 —— 绘图

         通过 plt.gca() 赋值与直接使用 plt.plot() 效果相同,但使用了 plt.gca() 后,我们在未来仍可对已经获得的某轴域直接进行自定义,如果没有使用 gca 方法,我们在接下来对某轴域进行编辑将会报错,如下

        例二:

 (上图说明有无plt.gca()视觉上效果一样,那区别何在?)

 (使用了 plt.gca() 对 ax1 可以后续进行编辑)

(未使用 plt.gca(),当前轴域位于 ax2,因此报错)

        此外根据下方代码可以看到,两个对象中 ax1 和 ax2 是不同类型的对象,plt.gca() 方法是获得轴域对象,以便后续进行操作,否则得到的将是一个 2D 图画列表对象

plt.figure(figsize=(5, 2.7), layout='constrained')

plt.subplot(1,2,1)
ax1=plt.plot(x)
print(type(ax1),id(ax1),ax1)

plt.subplot(1,2,2)
ax2=plt.gca()
ax2.plot(x)
print(type(ax2),id(ax2),ax2)


<class 'list'> 2317946799232 [<matplotlib.lines.Line2D object at 0x0000021BB346C730>]
<class 'matplotlib.axes._axes.Axes'> 2317996251312 Axes(0.547727,0.11;0.352273x0.77)

        plt.plot():如果只传入一个数组作为参数, Matplotlib 认为是 Y 轴的坐标并自动生成 x 值,且默认样式是一条蓝色的折线

(三)对比:

        上面介绍两种方法,当我们在想对某个轴域进行编辑时,重复调用 plt.subplot(x,y,z) 方法定位轴域进行操作或重复使用 plt.acg() 方法,或者查看 Figure 对象并获取其 Axes 对象列表,但颜色条也是 Axes 可能会产生误导,所以直接用显示接口(OO)的方式在最开创建好所有轴域对象。

  • subplot定位例子:

        figure1 创建两行一列的轴域,figure2 创建一个 plot,然后定位到 figure1 的 axes1,添加一个 title

  • Axes 列表:
axs = []    # Axes 列表
ax = plt.subplot(1, 2, 1)
print(axs,type(axs),ax,type(ax))
axs += [ax]    # 添加后列表内多了一个<Axes: >
print(axs,type(axs),ax,type(ax))

[] <class 'list'> Axes(0.125,0.11;0.352273x0.77) <class 'matplotlib.axes._axes.Axes'>
[<Axes: >] <class 'list'> Axes(0.125,0.11;0.352273x0.77) <class 'matplotlib.axes._axes.Axes'>

         在最开始就定义好,更加清晰明了

fig, ax = plt.subplots(1, 2)
ax[0].plot([1, 2, 3], [0, 0.5, 0.2])
ax[1].plot([3, 2, 1], [0, 0.5, 0.2])
fig.suptitle('Explicit Interface')

for i in range(2):
    ax[i].set_xlabel('Boo')
plt.show()

        看看他们是什么类型:分别是Figure,数组,轴域(行、列与括号内的参数相同)

print(type(fig),type(ax),type(ax[0]))

<class 'matplotlib.figure.Figure'> <class 'numpy.ndarray'> <class 'matplotlib.axes._axes.Axes'>
  1. 总的来说,显式(OO)的“Axes”接口最灵活,并且是其他接口的基础。用户可以下拉到显式界面并对底层对象进行操作。显式接口的设置会更详细一些,但对于复杂的绘图通常会比尝试使用隐式“pyplot”接口简单。
  2. pyplot 模块实现了 “pyplot” 界面,但它也提供了顶层的 Figure 和 Axes 创建方法,并最终启动了图形用户界面。因此,无论选择何种接口,仍然需要使用 pyplot。

        这就是 Matplotlib 的大体框架,在此基础上,可以对图片进行点、线、轴的样式编辑,进行文字标注,也可以尝试画出多维图形、并在 Figure 上自由地设置 Axes 的布局


原文来自:Matplotlib3.5.2 快速入门_matplotlib 3.5.2安装依赖查看_一只大鸽子的博客-CSDN博客

部分翻译自 Matplotlib 官方文档:Matplotlib documentation — Matplotlib 3.7.1 documentation

文章是在这些基础上自己动手进行操作的一些小尝试,Matplotlib 提供了 3 种API:

  • The pyplot API
  • The object-oriented API
  • The pylab API (已弃用,不作了解)

架构:003-Matplotlib绘图逻辑框架之基础架构_matplotlib框架_Python草堂的博客-CSDN博客

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

带带琪宝

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值