Matplotlib学习手册A003_Figure对象解析

专注于matplotlib的pyplot函数式绘图的人,可能会说:Figure有什么需要解析的,我一直使用“plt.figure()”就足够了,有时我甚至直接"plt.plot()"就行了。Figure对象有必要解析吗?

Figure对象是matplotlib绘图的开始,它是连接后端的桥梁,它是绘图元素定位、布局的基础。

一切可见元素皆是Artist

mpl框架的artist模块中定义了一个抽象基类,用作定义下述对象的父类:

  1. 将要渲染(render)到画布(canvas)里的对象;
  2. 所有可见的元素。

这些对象都是Artist的子类。

Artist提供了所有mpl绘图的所有可见元素。Artist对象有两种类型:

  • 容器类型;
  • 简单类型。

**容器类型:**可以容纳、包含其它Artist对象的对象。如Figure, Axes。Figure可以包含多个Axes、Text等。Axes包含Axis,Line2D,Text等。

容器把包含在其内的对象组织为一个整体。

**简单类型:**是标准的、最基本的绘图元件,不能再包含其它对象,如Line2D, Text, Rectangle等。

Figure是一个顶级容器

matplotlib.artist模块提供了一个 Figure 类,它是顶层的容器型Artist,它容纳所有绘图元件。

在2D平面坐标中,你应该把它看成一个矩形(Rectangle)区域。创建一个Figure也就是在画布上定义一块矩形区域。

这个矩形区域有两个最根本的用处:

  1. 可以再划分为多个子区域;如subplot就是在Figure矩形区域中划分子区域。
  2. 用于包含在其中的对象的坐标定位参考。

第2点非常重要,它是坐标变换、其它对象尺寸设置的参考对象。

Figure默认是白色、无边框的,把它填充一个其它颜色的前景色并设置边框有助于我们理解它。

输入如下代码,创建一个有前景色和边框的Figure:

from matplotlib.backends.backend_agg import FigureCanvasAgg
from matplotlib.figure import Figure
fig =Figure(figsize=(6.4,4.8), 
 dpi=100,
 facecolor=(239/256,239/256,239/256),
 edgecolor=(82/256,101/256,155/256),
 linewidth=10.0,
 frameon=True,
 )
canvas = FigureCanvasAgg(fig)
s, (width, height) = canvas.print_to_buffer() 
from PIL import Image #调用PIL
im = Image.frombytes("RGBA", (width, height), s)
im.show() 

Matplotlib学习手册A003_Figure对象解析

from matplotlib.backends.backend_agg import FigureCanvasAgg
from matplotlib.figure import Figure
fig =Figure(figsize=(6.4,4.8), 
 dpi=100,
 facecolor=(239/256,239/256,239/256),
 edgecolor=(82/256,101/256,155/256),
 linewidth=10.0,
 frameon=True,
 )
canvas = FigureCanvasAgg(fig)
#在figure的中心添加一个文本
fig.text(0.5,0.5,'fig_center') 
s, (width, height) = canvas.print_to_buffer() 
from PIL import Image 
im = Image.frombytes("RGBA", (width, height), s)
im.show() 

Matplotlib学习手册A003_Figure对象解析

如果要将一个容器类的artist添加到figure中时,如,我们添加一个Axes到Figure中,我们不仅要提供定位坐标(axes的左下角在figure中的位置),还要指定子容器相对于Figure的大小,用分数表示,即把Figure的宽和长看为1,子容器是它的“0.?”。

from matplotlib.backends.backend_agg import FigureCanvasAgg
from matplotlib.figure import Figure
from matplotlib.axes import Axes
fig =Figure(figsize=(6.4,4.8), 
 dpi=100,
 facecolor=(239/256,239/256,239/256),
 edgecolor=(82/256,101/256,155/256),
 linewidth=10.0,
 frameon=True,
 )
canvas = FigureCanvasAgg(fig)
fig.text(0.5,0.5,'fig_center')
#请注意下面的axes定义
ax = Axes(fig,[0.1,0.2,0.3,0.8])
fig.add_axes(ax)
s, (width, height) = canvas.print_to_buffer() 
from PIL import Image #调用PIL
im = Image.frombytes("RGBA", (width, height), s)
im.show() 

Matplotlib学习手册A003_Figure对象解析
添加到figure中的axes,axes的左下角是定位坐标,宽度和高度定义了axes的尺寸。axes的定位坐标和尺寸都是相对于figue来计算的。

理解Figure的坐标定位、尺寸参照作用,比掌握Figure的众多参数设置更重要!

简单地理解后端

因为Figure中一些参数、方法与后端有关,而我们一般绘图又很少需要与后端打交道,但如果后端一点都不了解,又不利于从整体上把握matplotlib的架构,所以这里用草根的语言和理解简单地介绍一下后端,记住以下几点就差不多了,中高级部分再详细讨论。

  • 后端就是在后台将你的绘图代码翻译为计算机绘图语言(算法)、并绘制成图形、显示到屏幕上的程序模块。
  • 后端决定了支持的图形格式、渲染的方式等;所以,有些参数仅支持一部分后端。
  • 后端还是计算机屏幕坐标与图形坐标映射的工具。

试想,你并没有直接操控计算机显示系统,你仅是在写python代码,你的代码是如何与计算机显示系统良好对接的呢?你绘制的绘图元件为什么总是能正确地在屏幕上显示出来,而没有发生位置错乱、颜色错误呢?

简单地理解:后端就是将你的代码转换为计算机图形语言,并正确地在屏幕上显示出来的后台程序块。

Figure基础参数使用

Figure类的调用

class matplotlib.figure.Figure(
 figsize=None, 
 dpi=None, 
 facecolor=None, 
 edgecolor=None, 
 linewidth=0.0, 
 frameon=None, 
 subplotpars=None, 
 tight_layout=None, 
 constrained_layout=None)

实例化Figure类时,需要9个参数,但Figure类定义中,这些形参都提供了默认值。所以,我们可以一个参数都不提供,就会取默认参数rcParams中的设置创建一个figure实例。

Matplotlib学习手册A003_Figure对象解析

大部分参数的设置和用法一目了然,下面补充解释下面几个参数:

  • color
  • subplotpars=None,
  • tight_layout=None,
  • constrained_layout=None

color: matplotlib的颜色,可以使用常用颜色的名称指定颜色,如’red’, 'blue’等,也可以使用浮点数3元素元组表示的RGB颜色,如(0.1, 0.2, 0.5),也可以这样(239/256,239/256,239/256)。

subplotpars: 是SubplotParams类的一个实例,定义子图参数。如果不提供该参数,则用rcParams[“figure.subplot.*”]作为子图参数。一般无需设置它,默认即可。

class matplotlib.figure.SubplotParams(
 left=None, 
 bottom=None, 
 right=None, 
 top=None, 
 wspace=None, 
 hspace=None
 )

要自定义Figure的subplotpars参数,先创建一个figure.SubplotParams类的实例。该类的前4个参数依次是子图(矩形区域)的“左、底、右、顶”边在Figure中的位置,浮点数。

wspace:

float,子图之间预留空间的宽度大小,用平均axis轴线宽度的分数表示。

hspace:

float,子图之间预留空间的高度大小,用平均axis轴线高度的分数表示。

下面是默认的rcParams[“figure.subplot.*”],单位是figure的分数。

'figure.subplot.bottom': 0.11,
 'figure.subplot.hspace': 0.2,
 'figure.subplot.left': 0.125,
 'figure.subplot.right': 0.9,
 'figure.subplot.top': 0.88,
 'figure.subplot.wspace': 0.2,

tight_layout: 布尔值,或字典。设置如何调整子图的布局。如果为False,使用subplotpars参数;如果为True,使用带有默认padding的tight_layout调整subplot参数。

tight_layout(self, renderer=None, pad=1.08, h_pad=None, w_pad=None, rect=None)
  • =True, pad = 1.08,是字体的1.08倍大小,它远远小于rcParams[“figure.subplot.*”]中的设置值。
  • =False, 使用subplotpars参数设置,subplotpars默认为None,即,用rcParams[“figure.subplot.*”]中的设置。

下图是设置:tight_layout = False /True 的效果比较。

from matplotlib.backends.backend_agg import FigureCanvasAgg
from matplotlib.figure import Figure,SubplotParams
from matplotlib.axes import Axes
import numpy as np
from numpy import math
fig =Figure(figsize=(9.6,4.8), 
 dpi=100,
 facecolor=(239/256,239/256,239/256),
 edgecolor=(82/256,101/256,155/256),
 linewidth=10.0,
 frameon=True,
 subplotpars=None, 
 tight_layout=True, 
 constrained_layout=None
 )
canvas = FigureCanvasAgg(fig)
ax_fca = (249/256,244/256,206/256)
ax_fcb = (138/256,176/256,209/256)
pl_cb = (8/256,89/256,156/256)
pl_cr = (239/256,8/256,8/256)
ax_a = fig.add_subplot(121,facecolor=ax_fca)
ax_b = fig.add_subplot(122,facecolor=ax_fcb) 
x = np.arange(0, 2*math.pi, 0.001)
y = np.sin(x)
ax_a.plot(x, y, color=pl_cr)
ax_b.plot(x, y, color=pl_cb) 
ax_a.plot(x, np.cos(x), color='g')
ax_b.plot(x, np.cos(x), color='r') 
s, (width, height) = canvas.print_to_buffer() 
from PIL import Image 
im = Image.frombytes("RGBA", (width, height), s)
im.show() 

Matplotlib学习手册A003_Figure对象解析
tight_layout=True
Matplotlib学习手册A003_Figure对象解析
tight_layout=False

还可以提供一个字典给 tight_layout,下面是在字典中设置tight_layout的示例:

from matplotlib.backends.backend_agg import FigureCanvasAgg
from matplotlib.figure import Figure,SubplotParams
from matplotlib.axes import Axes
import numpy as np
from numpy import math

tl = {'pad':2.0,'h_pad':1.0,'w_pad':5.0,'rect':(0.1,0.1,0.9,0.9)}

fig =Figure(figsize=(9.6,4.8), 
 dpi=100,
 facecolor=(239/256,239/256,239/256),
 edgecolor=(82/256,101/256,155/256),
 linewidth=10.0,
 frameon=True,
 subplotpars=None, 
 tight_layout=tl, 
 constrained_layout=False
 )

canvas = FigureCanvasAgg(fig)

ax_fca = (249/256,244/256,206/256)
ax_fcb = (138/256,176/256,209/256)
pl_cb = (8/256,89/256,156/256)
pl_cr = (239/256,8/256,8/256)

ax_a = fig.add_subplot(121,facecolor=ax_fca)
ax_b = fig.add_subplot(122,facecolor=ax_fcb) 
x = np.arange(0, 2*math.pi, 0.001)
y = np.sin(x)
ax_a.plot(x, y, color=pl_cr)
ax_b.plot(x, y, color=pl_cb) 
ax_a.plot(x, np.cos(x), color='g')
ax_b.plot(x, np.cos(x), color='r') 

s, (width, height) = canvas.print_to_buffer() 

from PIL import Image 
im = Image.frombytes("RGBA", (width, height), s)
im.show() 

有意将tight_layout的一些参数设置得很夸张,以突出效果:
Matplotlib学习手册A003_Figure对象解析
constrained_layout: 布尔值,如果"True",使用约束布局来调整绘图元素的位置。与 tight_layout 有点相似,但不同。中级篇中再详细介绍。

注意: constrained_layout=True 与 subplots_adjust 和 tight_layout 不兼容,即不能同时设置为True。

下一篇将详细讨论figure的方法和属性。

(This end.)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Python草堂

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

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

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

打赏作者

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

抵扣说明:

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

余额充值