Matplotlib学习手册A006_Figure的add_subplot()方法
Figure的add_subplot()方法本篇讨论Figure对象的另一个重要方法: add_subplot()。很多人会认为 add_subplot() 与 add_axes() 方法一样,都是向figure容器中添加axes子容器。如果你也是这样理解add_subplot()方法的,你就真的有必要认真看看本篇了。本篇将从4个方面来讨论:add_subplot()方法的调用;ad...
Figure的add_subplot()方法
本篇讨论Figure对象的另一个重要方法: add_subplot()。
很多人会认为 add_subplot() 与 add_axes() 方法一样,都是向figure容器中添加axes子容器。
如果你也是这样理解add_subplot()方法的,你就真的有必要认真看看本篇了。
本篇将从4个方面来讨论:
- add_subplot()方法的调用;
- add_subplot()方法与add_axes()方法的关系;
- 深入理解add_subplot()方法;
- 灵活使用add_subplot()方法实现复杂的图形布局。
add_suplot()方法语法
add_subplot(self, *args, **kwargs)
add_subplot()方法,“向figure添加一个Axes作为一subplot布局的一部分。”
要调用add_subplot()方法,有4种签名形式:
- add_subplot(nrows, ncols, index, **kwargs)
- add_subplot(pos, **kwargs)
- add_subplot(ax) ,这里的ax必须是作为子图布置的一部分创建的,即用add_subplot()创建的
- add_subplot() ,使用默认值创建一个子图。
add_subplot()方法的本质
add_subplot()方法本质上做了两件事:
- 将整个Figure区域划分为Row * col的网格;
- 在网格的指定格子(索引号)中创建一个Axes。
我们就可以进一步在这个axes中绘制图形元素。
add_subplot()网格有两种定义方式:
第一种是用3个参数,分别代表网格的,行数 nrows, 列数 ncols, 索引号index。它们都是位置参数。这种是第1种调用签名形式。
第二种是用一个3位数的整数,如,224,第一个2表示2行,第二个2表示2列,第3位上的4表示第4个格子。这就是第二种调用签名形式,pos为224,也是位置参数。
如果我们不提供参数,即第4种调用签名,默认pos为111。
而第三种调用签名形式,请参考一篇中的相关内容。
假如,我们要创建一个2*2的网格,参数和索引如下图所示:
add_subplot()方法的网格参数和索引
下面的代码就在figure中创建了一个2*2的网格,并在第4个格子中创建了一个axes坐标系。
from matplotlib.backends.backend_agg import FigureCanvasAgg
from matplotlib.figure import Figure
from matplotlib.axes import Axes
import numpy as np
from numpy import math
fig =Figure(
dpi=100,
facecolor=(239/256,239/256,239/256),
edgecolor=(82/256,101/256,155/256),
linewidth=6.0,
frameon=True,
)
canvas = FigureCanvasAgg(fig)
#创建一个2*2的网格,并在第4个格子中创建一个axes
fig.add_subplot(224)
s, (width, height) = canvas.print_to_buffer()
from PIL import Image
im = Image.frombytes("RGBA", (width, height), s)
im.show()
22的网格是虚拟的*
注意:2*2的网格是虚拟的,起一个定位的作用,本例在第4个格子中创建axes。
再看下例:
from matplotlib.backends.backend_agg import FigureCanvasAgg
from matplotlib.figure import Figure
from matplotlib.axes import Axes
import numpy as np
from numpy import math
fig =Figure(
dpi=100,
facecolor=(239/256,239/256,239/256),
edgecolor=(82/256,101/256,155/256),
linewidth=6.0,
frameon=True,
)
canvas = FigureCanvasAgg(fig)
fig.add_subplot(224)
#再创建一个2行3列的虚拟网格
#在这个网格的第2个格子中创建axes
fig.add_subplot(232)
s, (width, height) = canvas.print_to_buffer()
from PIL import Image
im = Image.frombytes("RGBA", (width, height), s)
im.show()
使用add_subplot()实现复杂布局
上面代码,在同一个figure中使用不同的网格定义:
- 先定义一个2*2的网格,在第4个格子中创建axes;
- 再定义一个2*3的网格,在第2个格子中创建axes。
这样就实现了,不规则的、复杂的子图布局。
这才是add_subplot()方法最重要用途。
小结:
- figure就是一个矩形容器(顶层容器),可以再划分为小方格,每个方格就是一个subplot,即子绘图区。
- 一个图形中可以有多个subplot,这些subplot又可以被看作一个整体,有一些属性如整个subplot的位置、内部(单个subplot之间)的间距等,这些属性保存在figure.SubplotParams类中。可以通过Figure的subplotpars参数来修改这些属性。
- 子图使用了subplot,而不是subfigure。fiugre仅是一个矩形容器,而plot则是具体的图形元素了,所以subplot会自动创建一个Axes,这个Axes是属于特定subplot的。
add_axes()和add_subplot()
注意官方文档的表述差异:
- add_axes() ,Add an axes to the figure. 向figure添加一个axes。
- add_subplot(), Add an Axes to the figure as part of a subplot arrangement. 向figure添加一个Axes作为 subplot 布局的一部分。
两者创建的对象不同:
- add_axes() 方法创建的对象是 <class ‘matplotlib.axes._axes.Axes’> 的实例。
- add_subplot() 方法创建的对象,是<class ‘matplotlib.axes._subplots.AxesSubplot’>的一个实例,并且作为子图布置的一部分。
add_subplot()与add_axes()两者既紧密相关,也有区别:
- add_subplot()添加一个子图,同时使用工厂函数为该子图自动创建一个坐标系区域;axes的位置由row,col,index指定;
- add_axes()直接添加一个坐标系区域到figure容器中;位置由rect参数指定。
- add_axes()从外观形式上也是生成了一个子图区域,可以进一步向这个区域添加元素;
- 但add_axes()是通过尺寸定位的;它的位置更加灵活自由;
- add_subplot()是通过网格索引定位的,则调用容易,排列整齐。
- 要向add_subplot()创建的子图添加其它plot元素,是把子图视为一个Axes对象来处理的,即需要将add_subplot()赋给一个变量,然后如同Axes中添加元素一样的操作。
深入理解 add_subplot()
add_subplot(self, *args, **kwargs)
向Figure添加一个子图subplot,add_suplot方法会自动创建一个Axes作为子图布置的一部分。
该方法是通过调用subplot_class_factory工厂函数创建子图和Axes的实例来实现上述功能的。
matplotlib有了一个axes子包,子包内有一个_subplots私有模块。_subpltos模块包含一个类和一个工厂函数:
- class SubplotBase(object):
- def subplot_class_factory(axes_class=None):
class SubplotBase(object)用于subplots的基类,它们是:class: ’ Axes ‘实例,该实例带有其他方法,以方便生成和操作figure中的一组:class:’ Axes '。
工厂函数,首先,它是个函数,但工厂函数基本上都是带有返回对象的。而这些返回对象则是通过调用一种或者多种类来创建的对象。工厂函数:能够产生类实例的内建函数。
这将生成一个继承自SubplotBase和给定axes_class(假定axes_class是axes.axes的子类)的新类。像这样动态创建一个新类可能有点迂回,但这意味着不必为每种类型的坐标系创建一个新的Subplot类。
subplot_class_factory()工厂函数,继承了SubplotBase类和axes_calss参数给定的类,默认axes_class = Axes
查看该工厂函数的源码有助于理解它
def subplot_class_factory(axes_class=None):
if axes_class is None:
axes_class = Axes
try:
# Avoid creating two different instances of GeoAxesSubplot...
# Only a temporary backcompat fix. This should be removed in
# 3.4
return next(cls for cls in SubplotBase.__subclasses__()
if cls.__bases__ == (SubplotBase, axes_class))
except StopIteration:
return type("%sSubplot" % axes_class.__name__,
(SubplotBase, axes_class),
{'_axes_class': axes_class})
关注"Python草堂",完全掌握matplotlib。
(This end.)
更多推荐
所有评论(0)