第一次看到我的演绎文章的小伙伴,如果需要,可以先看一下我这篇文章的前三篇,包括准备环境等等:
政安晨:在Jupyter中【示例演绎】Matplotlib的官方指南(一){Pyplot tutorial}https://blog.csdn.net/snowdenkeke/article/details/136096870政安晨:在Jupyter中【示例演绎】Matplotlib的官方指南(二){Image tutorial}·{Python语言}https://blog.csdn.net/snowdenkeke/article/details/136100806政安晨:在Jupyter中【示例演绎】Matplotlib的官方指南(三){Plot全工作流程展示}·{Python语言}https://blog.csdn.net/snowdenkeke/article/details/136101342如果大家准备好啦,就让咱们开始吧。
Start
使用Artist对象在画布上进行渲染。
Matplotlib API有三个层次:
1. matplotlib.backend_bases.FigureCanvas是绘制图形的区域;
2. matplotlib.backend_bases.Renderer是一个对象,它知道如何在FigureCanvas上绘制;
3. matplotlib.artist.Artist是一个对象,它知道如何使用渲染器在画布上进行绘画。
FigureCanvas和Renderer处理与用户界面工具包(如wxPython)或绘图语言(如PostScript®)的交互的所有细节,而Artist处理表示和布局图形、文本和线条等高级结构的所有工作,典型用户的工作中,95%的时间都会与Artist进行交互。
有两种类型的Artists:原生态和容器态。
原生态代表我们想要绘制到画布上的标准图形对象:Line2D、Rectangle、Text、AxesImage等,而容器态是放置它们的位置(Axis、Axes和Figure)。
标准用法是创建一个Figure实例,使用Figure创建一个或多个Axes实例,然后使用Axes实例的辅助方法创建原生态的Artist。
在下面的示例中,我们使用matplotlib.pyplot.figure()创建一个Figure实例,这是一个方便的方法,用于实例化Figure实例并将其与用户界面或绘图工具包的FigureCanvas连接。正如我们将在下面讨论的那样,这并不是必需的-您可以直接使用PostScript、PDF Gtk+或wxPython FigureCanvas实例进行操作,直接实例化您自己的Figures并连接它们-但由于我们在这里关注的是Artist API,我们将让pyplot为我们处理其中的一些细节。
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot(2, 1, 1) # two rows, one column, first plot
Axes是Matplotlib API中可能是最重要的类,也是你在大部分时间里将要使用的类。
这是因为Axes是绘图区域,其中大部分对象都会放置在其中,而且Axes有许多特殊的辅助方法(plot(),text(),hist(),imshow())来创建最常见的图形基元(Line2D,Text,Rectangle,AxesImage)。
这些辅助方法会获取你的数据(例如numpy数组和字符串),根据需要创建基本的Artist实例(例如Line2D),将它们添加到相应的容器中,并在需要时绘制它们。
如果你想在任意位置创建一个Axes,只需使用add_axes()方法,该方法接受一个包含[left,bottom,width,height]值的列表,这些值是以0-1的相对图形坐标表示的。
fig2 = plt.figure()
ax2 = fig2.add_axes([0.15, 0.1, 0.7, 0.3])
继续举例说明:
import numpy as np
t = np.arange(0.0, 1.0, 0.01)
s = np.sin(2*np.pi*t)
line, = ax.plot(t, s, color='blue', lw=2)
在这个例子中,ax是通过上面的fig.add_subplot调用创建的Axes实例,当你调用ax.plot时,它会创建一个Line2D实例并将其添加到Axes中。
在下面的交互式IPython会话中,你可以看到Axes.lines列表的长度为1,并包含了通过line, = ax.plot...调用返回的相同的线条:
In [101]: ax.lines[0]
Out[101]: <matplotlib.lines.Line2D at 0x19a95710>In [102]: line
Out[102]: <matplotlib.lines.Line2D at 0x19a95710>
如果您对ax.plot进行后续调用(并且保持状态为默认的“on”),那么将会将附加的线条添加到列表中。
您可以通过调用其remove方法来删除一条线条:
line = ax.lines[0]
line.remove()
Axes还具有一些辅助方法,用于配置和装饰x轴和y轴的刻度、刻度标签和坐标轴标签:
xtext = ax.set_xlabel('my xdata') # returns a Text instance
ytext = ax.set_ylabel('my ydata')
在调用ax.set_xlabel时,它会将信息传递给XAxis的Text实例,每个Axes实例包含一个XAxis和一个YAxis实例,它们负责处理刻度、刻度标签和轴标签的布局和绘制。
现在,咱们请尝试创建下面的图形:
import matplotlib.pyplot as plt
import numpy as npfig = plt.figure()
fig.subplots_adjust(top=0.8)
ax1 = fig.add_subplot(211)
ax1.set_ylabel('Voltage [V]')
ax1.set_title('A sine wave')t = np.arange(0.0, 1.0, 0.01)
s = np.sin(2*np.pi*t)
line, = ax1.plot(t, s, color='blue', lw=2)# Fixing random state for reproducibility
np.random.seed(19680801)ax2 = fig.add_axes([0.15, 0.1, 0.7, 0.3])
n, bins, patches = ax2.hist(np.random.randn(1000), 50,facecolor='yellow', edgecolor='yellow')
ax2.set_xlabel('Time [s]')plt.show()
自定义您的对象
在图中,每个元素都由Matplotlib Artist表示,并且每个元素都有一个广泛的属性列表来配置其外观。
图本身包含一个与图大小完全相同的矩形,您可以使用它来设置图的背景颜色和透明度。
同样,每个Axes bounding box(在典型的Matplotlib绘图中有黑边的标准白色框)都有一个Rectangle实例,用于确定Axes的颜色、透明度和其他属性。这些实例存储为成员变量Figure.patch和Axes.patch("Patch"是从MATLAB继承的名称,是图上的一个二维颜色"patch",例如矩形、圆和多边形)。
每个Matplotlib Artist都具有以下属性:
Property | Description |
---|---|
alpha | 透明度-一个从0-1的标量 |
animated | 一个用于方便动画绘制的布尔值 |
axes | The Axes that the Artist lives in, possibly None |
clip_box | The bounding box that clips the Artist |
clip_on | Whether clipping is enabled |
clip_path | The path the artist is clipped to |
contains | A picking function to test whether the artist contains the pick point |
figure | The figure instance the artist lives in, possibly None |
label | A text label (e.g., for auto-labeling) |
picker | A python object that controls object picking |
transform | The transformation |
visible | A boolean whether the artist should be drawn |
zorder | A number which determines the drawing order |
rasterized | Boolean; Turns vectors into raster graphics (for compression & EPS transparency) |
每个属性都是通过一种老式的setter或getter进行访问的(是的,我们知道这会让Python爱好者感到恼火,我们计划支持直接通过属性或特性进行访问,但目前还没有完成)。
例如,要将当前的alpha值乘以一半:
a = o.get_alpha()
o.set_alpha(0.5*a)
如果您想一次设置多个属性,也可以使用带有关键字参数的 set 方法。
例如:
o.set(alpha=0.5, zorder=2)
如果您在python shell上进行交互工作,检查Artist属性的一种方便方式是使用matplotlib.artist.getp()函数(在pyplot中是直接使用getp()),该函数会列出属性及其值。
这也适用于从Artist派生的类,例如Figure和Rectangle,以下是上述提到的Figure矩形属性:
In [149]: matplotlib.artist.getp(fig.patch)
agg_filter = None
alpha = None
animated = False
antialiased or aa = False
bbox = Bbox(x0=0.0, y0=0.0, x1=1.0, y1=1.0)
capstyle = butt
children = []
clip_box = None
clip_on = True
clip_path = None
contains = None
data_transform = BboxTransformTo( TransformedBbox( Bbox...
edgecolor or ec = (1.0, 1.0, 1.0, 1.0)
extents = Bbox(x0=0.0, y0=0.0, x1=640.0, y1=480.0)
facecolor or fc = (1.0, 1.0, 1.0, 1.0)
figure = Figure(640x480)
fill = True
gid = None
hatch = None
height = 1
in_layout = False
joinstyle = miter
label =
linestyle or ls = solid
linewidth or lw = 0.0
patch_transform = CompositeGenericTransform( BboxTransformTo( ...
path = Path(array([[0., 0.], [1., 0.], [1.,...
path_effects = []
picker = None
rasterized = None
sketch_params = None
snap = None
transform = CompositeGenericTransform( CompositeGenericTra...
transformed_clip_path_and_affine = (None, None)
url = None
verts = [[ 0. 0.] [640. 0.] [640. 480.] [ 0. 480....
visible = True
width = 1
window_extent = Bbox(x0=0.0, y0=0.0, x1=640.0, y1=480.0)
x = 0
xy = (0, 0)
y = 0
zorder = 1
所有类的docstrings还包含了Artist属性,因此您可以查询交互式的"help"或matplotlib.artist来获取给定对象的属性列表。
对象容器
现在我们知道如何检查和设置要配置的给定对象的属性,我们需要知道如何获取该对象。
正如在介绍中提到的,有两种类型的对象:
原生对象和容器对象。原生对象通常是您要配置的东西(例如Text实例的字体,Line2D的宽度),尽管容器对象也有一些属性——例如Axes Artist是一个容器,包含了绘图中的许多原生对象,但它也具有一些属性,如xscale来控制x轴是“线性”还是“对数”。在本节中,我们将回顾各种容器对象存储要获取的Artist的位置。
图形容器
最顶层的容器是matplotlib.figure.Figure,它包含了图形中的所有内容。
图形的背景是一个存储在Figure.patch中的矩形,当你向图形中添加子图(add_subplot())和坐标轴(add_axes())时,它们将被附加到Figure.axes中,这些对象也会被它们的创建方法返回:
In [156]: fig = plt.figure()
In [157]: ax1 = fig.add_subplot(211)
In [158]: ax2 = fig.add_axes([0.1, 0.1, 0.7, 0.3])
In [159]: ax1
Out[159]: <Axes:>In [160]: print(fig.axes)
[<Axes:>, <matplotlib.axes._axes.Axes object at 0x7f0768702be0>]
由于该图保持了'current Axes'的概念(参见Figure.gca和Figure.sca)以支持pylab/pyplot状态机,所以不应直接在Axes列表中插入或删除Axes,而应使用add_subplot()和add_axes()方法进行插入,并使用Axes.remove方法进行删除。
但是,您可以自由地遍历Axes列表或索引它以访问要自定义的Axes实例。
以下是一个示例,打开了所有Axes的网格:
for ax in fig.axes:ax.grid(True)
该图形还具有自己的图像、线条、路径和文本属性,您可以使用这些属性直接添加基本图形。
在这样做时,图形的默认坐标系统将简单地以像素为单位(通常不是您想要的),如果您使用图形级别的方法添加Artist(例如使用Figure.text添加文本),那么默认的坐标系统将是"figure coordinates",其中(0, 0)是图形的左下角,(1, 1)是图形的右上角。
与所有Artist一样,您可以通过设置transform属性来控制这个坐标系统,您可以通过将Artist的transform设置为fig.transFigure来明确使用"figure coordinates":
import matplotlib.lines as linesfig = plt.figure()l1 = lines.Line2D([0, 1], [0, 1], transform=fig.transFigure, figure=fig)
l2 = lines.Line2D([0, 1], [1, 0], transform=fig.transFigure, figure=fig)
fig.lines.extend([l1, l2])plt.show()
以下是图形容器的Artist汇总:
Figure attribute | Description |
---|---|
axes | A list of Axes instances |
patch | The Rectangle background |
images | A list of FigureImage patches - useful for raw pixel display |
legends | A list of Figure Legend instances (different from |
lines | A list of Figure Line2D instances (rarely used, see |
patches | A list of Figure Patchs (rarely used, see |
texts | A list Figure Text instances |
Axes(轴)容器
matplotlib.axes.
Axes是Matplotlib体系的核心 - 它包含了图中使用的几乎所有的Artists,并提供了许多辅助方法来创建和添加这些Artists到自身,以及访问和自定义它包含的Artists的辅助方法。
与Figure一样,它包含一个Patch, patch,用于笛卡尔坐标系为矩形,用于极坐标系为圆形;这个patch决定了绘图区域的形状、背景和边框。
ax = fig.add_subplot()
rect = ax.patch # a Rectangle instance
rect.set_facecolor('green')
当您调用绘图方法时,例如传入数组或列表值的标准绘图方法:
该方法将创建一个matplotlib.lines.Line2D实例,使用传递的关键字参数更新线条的所有Line2D属性,将线条添加到Axes中,并将其返回给您。
In [213]: x, y = np.random.rand(2, 100)
In [214]: line, = ax.plot(x, y, '-', color='blue', linewidth=2)
plot返回一组线条,因为您可以传入多个x,y对进行绘图,并且我们正在将长度为一的列表的第一个元素解包到line变量中,该线条已添加到Axes.lines列表中。
In [229]: print(ax.lines)
[<matplotlib.lines.Line2D at 0xd378b0c>]
同样,像bar()这样创建补丁的方法会将补丁添加到Axes.patches列表中:
In [233]: n, bins, rectangles = ax.hist(np.random.randn(1000), 50)
In [234]: rectangles
Out[234]: <BarContainer object of 50 artists>In [235]: print(len(ax.patches))
Out[235]: 50
您不应将对象直接添加到Axes.lines或Axes.patches列表中,因为Axes在创建和添加对象时需要执行一些操作:
它设置了Artist的figure和axes属性;
它设置默认的Axes转换(除非已经设置了转换);
它检查Artist中包含的数据,更新控制自动缩放的数据结构,以便调整视图限制以包含绘制的数据。
然而,您仍然可以自己创建对象,并使用add_line和add_patch等辅助方法直接将它们添加到Axes。
以下是一个注释的交互式会话,演示了正在进行的操作:
In [262]: fig, ax = plt.subplots()
# create a rectangle instance
In [263]: rect = matplotlib.patches.Rectangle((1, 1), width=5, height=12)# by default the axes instance is None
In [264]: print(rect.axes)
None# and the transformation instance is set to the "identity transform"
In [265]: print(rect.get_data_transform())
IdentityTransform()# now we add the Rectangle to the Axes
In [266]: ax.add_patch(rect)# and notice that the ax.add_patch method has set the axes
# instance
In [267]: print(rect.axes)
Axes(0.125,0.1;0.775x0.8)# and the transformation has been set too
In [268]: print(rect.get_data_transform())
CompositeGenericTransform(
TransformWrapper(
BlendedAffine2D(
IdentityTransform(),
IdentityTransform())),
CompositeGenericTransform(
BboxTransformFrom(
TransformedBbox(
Bbox(x0=0.0, y0=0.0, x1=1.0, y1=1.0),
TransformWrapper(
BlendedAffine2D(
IdentityTransform(),
IdentityTransform())))),
BboxTransformTo(
TransformedBbox(
Bbox(x0=0.125, y0=0.10999999999999999, x1=0.9, y1=0.88),
BboxTransformTo(
TransformedBbox(
Bbox(x0=0.0, y0=0.0, x1=6.4, y1=4.8),
Affine2D(
[[100. 0. 0.]
[ 0. 100. 0.]
[ 0. 0. 1.]])))))))# the default axes transformation is ax.transData
In [269]: print(ax.transData)
CompositeGenericTransform(
TransformWrapper(
BlendedAffine2D(
IdentityTransform(),
IdentityTransform())),
CompositeGenericTransform(
BboxTransformFrom(
TransformedBbox(
Bbox(x0=0.0, y0=0.0, x1=1.0, y1=1.0),
TransformWrapper(
BlendedAffine2D(
IdentityTransform(),
IdentityTransform())))),
BboxTransformTo(
TransformedBbox(
Bbox(x0=0.125, y0=0.10999999999999999, x1=0.9, y1=0.88),
BboxTransformTo(
TransformedBbox(
Bbox(x0=0.0, y0=0.0, x1=6.4, y1=4.8),
Affine2D(
[[100. 0. 0.]
[ 0. 100. 0.]
[ 0. 0. 1.]])))))))# notice that the xlimits of the Axes have not been changed
In [270]: print(ax.get_xlim())
(0.0, 1.0)# but the data limits have been updated to encompass the rectangle
In [271]: print(ax.dataLim.bounds)
(1.0, 1.0, 5.0, 12.0)# we can manually invoke the auto-scaling machinery
In [272]: ax.autoscale_view()# and now the xlim are updated to encompass the rectangle, plus margins
In [273]: print(ax.get_xlim())
(0.75, 6.25)# we have to manually force a figure draw
In [274]: fig.canvas.draw()
有很多很多的Axes辅助方法可以创建原始的Artist并将它们添加到相应的容器中。
下表总结了其中一小部分方法,以及它们创建的Artist的种类和存储位置。
Axes helper method | Artist | Container |
---|---|---|
annotate - text annotations | Annotation | ax.texts |
bar - bar charts | Rectangle | ax.patches |
errorbar - error bar plots | Line2D and Rectangle | ax.lines and ax.patches |
fill - shared area | Polygon | ax.patches |
hist - histograms | Rectangle | ax.patches |
imshow - image data | AxesImage | ax.images |
legend - Axes legend | Legend | ax.get_legend() |
plot - xy plots | Line2D | ax.lines |
scatter - scatter charts | PolyCollection | ax.collections |
text - text | Text | ax.texts |
除了所有这些艺术家之外,轴还包含两个重要的艺术家容器:
X轴和Y轴,它们处理刻度和标签的绘制。它们存储为实例变量xaxis和yaxis。下面将详细介绍XAxis和YAxis容器,但请注意,Axes包含许多辅助方法,可以将调用转发给Axis实例,因此通常不需要直接使用它们,除非您需要。
例如,您可以使用Axes辅助方法设置X轴刻度标签的字体颜色:
ax.tick_params(axis='x', labelcolor='orange')
下面是Axes容器的汇总:
Axes attribute | Description |
---|---|
artists | An ArtistList of Artist instances |
patch | Rectangle instance for Axes background |
collections | An ArtistList of Collection instances |
images | An ArtistList of AxesImage |
lines | An ArtistList of Line2D instances |
patches | An ArtistList of Patch instances |
texts | An ArtistList of Text instances |
xaxis | A matplotlib.axis.XAxis instance |
yaxis | A matplotlib.axis.YAxis instance |
比如, legend 能被 get_legend 所访问。
Axis容器
Matplotlib.axis.Axis实例负责绘制刻度线、网格线、刻度标签和坐标轴标签。
您可以独立配置y轴的左侧和右侧刻度,以及x轴的上方和下方刻度,Axis还存储了用于自动缩放、平移和缩放的数据和视图间隔,以及控制刻度放置位置和字符串表示方式的Locator和Formatter实例。
每个Axis对象都包含一个label属性(这是pyplot在调用xlabel和ylabel时修改的内容),以及一个主要和次要刻度的列表。刻度是axis.XTick和axis.YTick的实例,它们包含了绘制刻度和刻度标签的实际线条和文本元素,由于刻度是根据需要动态创建的(例如,当平移和缩放时),您应该通过它们的访问方法axis.Axis.get_major_ticks和axis.Axis.get_minor_ticks来访问主要和次要刻度的列表,尽管刻度包含了所有的原语,并且将在下面详细介绍,但是Axis实例有访问方法来返回刻度线、刻度标签、刻度位置等。
fig, ax = plt.subplots()
axis = ax.xaxis
axis.get_ticklocs()
axis.get_ticklabels()
请注意:
刻度线的数量是标签数量的两倍,因为默认情况下,在顶部和底部都有刻度线,但只有在x轴下方有刻度标签;然而这可以自定义。
使用上述方法,默认情况下只会返回主刻度的列表,但您也可以请求次刻度:
axis.get_ticklabels(minor=True)
axis.get_ticklines(minor=True)
这里是 Axis 的一些有用的访问器方法的摘要(其中一些有对应的设置器方法,如 set_major_formatter())。
Axis accessor method | Description |
---|---|
get_scale | The scale of the Axis, e.g., 'log' or 'linear' |
get_view_interval | The interval instance of the Axis view limits |
get_data_interval | The interval instance of the Axis data limits |
get_gridlines | A list of grid lines for the Axis |
get_label | The Axis label - a Text instance |
get_offset_text | The Axis offset text - a Text instance |
get_ticklabels | A list of Text instances - keyword minor=True|False |
get_ticklines | A list of Line2D instances - keyword minor=True|False |
get_ticklocs | A list of Tick locations - keyword minor=True|False |
get_major_locator | The ticker.Locator instance for major ticks |
get_major_formatter | The ticker.Formatter instance for major ticks |
get_minor_locator | The ticker.Locator instance for minor ticks |
get_minor_formatter | The ticker.Formatter instance for minor ticks |
get_major_ticks | A list of Tick instances for major ticks |
get_minor_ticks | A list of Tick instances for minor ticks |
grid | Turn the grid on or off for the major or minor ticks |
以下是一个示例,不建议以它的美丽为目标,它自定义了Axes和Tick的属性。
# plt.figure creates a matplotlib.figure.Figure instance
fig = plt.figure()
rect = fig.patch # a rectangle instance
rect.set_facecolor('lightgoldenrodyellow')ax1 = fig.add_axes([0.1, 0.3, 0.4, 0.4])
rect = ax1.patch
rect.set_facecolor('lightslategray')for label in ax1.xaxis.get_ticklabels():# label is a Text instancelabel.set_color('red')label.set_rotation(45)label.set_fontsize(16)for line in ax1.yaxis.get_ticklines():# line is a Line2D instanceline.set_color('green')line.set_markersize(25)line.set_markeredgewidth(3)plt.show()
Tick容器
matplotlib.axis.Tick是我们从Figure到Axes到Axis到Tick的下降过程中的最终容器对象,Tick包含刻度线和网格线实例,以及上下刻度标签的标签实例,每个实例都可以直接作为Tick的属性进行访问。
Tick attribute | Description |
---|---|
tick1line | A Line2D instance |
tick2line | A Line2D instance |
gridline | A Line2D instance |
label1 | A Text instance |
label2 | A Text instance |
下面是一个示例,它用$符号设置了右侧刻度的格式,并将它们颜色设置为绿色,显示在y轴的右侧。
import matplotlib.pyplot as plt
import numpy as np# Fixing random state for reproducibility
np.random.seed(19680801)fig, ax = plt.subplots()
ax.plot(100*np.random.rand(20))# Use automatic StrMethodFormatter
ax.yaxis.set_major_formatter('${x:1.2f}')ax.yaxis.set_tick_params(which='major', labelcolor='green',labelleft=False, labelright=True)plt.show()
我的演绎如下:
这就是作者政安晨演绎的官方入门指南的全部啦,共四篇文章分4各主题演绎完。