笔记
单击此处 下载完整的示例代码
艺术家教程#
使用 Artist 对象在画布上渲染。
Matplotlib API 共有三层。
是
matplotlib.backend_bases.FigureCanvas
绘制图形的区域是
matplotlib.backend_bases.Renderer
知道如何在FigureCanvas
并且
matplotlib.artist.Artist
是知道如何使用渲染器在画布上绘画的对象。
FigureCanvas
和
Renderer
处理与用户界面工具包(如wxPython)或绘图语言(如 PostScript®)对话的所有细节,并处理Artist
所有高级构造,如表示和布置图形、文本和线条。典型用户将花费 95% 的时间使用Artists
.
有两种类型Artists
:原语和容器。原语代表我们想要在画布上绘制的标准图形对象:
Line2D
、Rectangle
、
Text
、AxesImage
等,而容器是放置它们的地方(Axis
和
Axes
)Figure
。标准用法是创建一个Figure
实例,使用Figure
创建一个或多个Axes
或
多个Subplot
实例,并使用Axes
实例辅助方法创建基元。在下面的示例中,我们使用 来创建一个
Figure
实例,这是一种用于实例化实例并将它们与您的用户界面或绘图工具包连接起来matplotlib.pyplot.figure()
的便捷方法Figure
FigureCanvas
. 正如我们将在下面讨论的那样,这不是必需的——您可以直接使用 PostScript、PDF Gtk+ 或 wxPythonFigureCanvas
实例,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
),将它们添加到相关容器中,并在请求时绘制它们。Subplot
你们中的大多数Axes
人可能熟悉Subplot
实例。如果要Axes
在任意位置创建一个,只需使用
在 0-1 相对图形坐标add_axes()
中获取值列表的方法:[left, bottom, width, height]
fig2 = plt.figure()
ax2 = fig2.add_axes([0.15, 0.1, 0.7, 0.3])
继续我们的例子:
在这个例子中,ax
是上面调用Axes
创建的实例
fig.add_subplot
(记住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
方法删除一行:
Axes 也有辅助方法来配置和装饰 x 轴和 y 轴刻度、刻度标签和轴标签:
xtext = ax.set_xlabel('my xdata') # returns a Text instance
ytext = ax.set_ylabel('my ydata')
当你调用时ax.set_xlabel
,它会传递关于Text
实例的信息XAxis
。每个Axes
实例都包含一个XAxis
和一个
YAxis
实例,它们处理刻度、刻度标签和轴标签的布局和绘制。
尝试创建下图。
import numpy as np
import matplotlib.pyplot as plt
fig = plt.figure()
fig.subplots_adjust(top=0.8)
ax1 = fig.add_subplot(211)
ax1.set_ylabel('volts')
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
都有一个广泛的属性列表来配置其外观。图形本身包含一个
Rectangle
与图形大小完全相同的图形,您可以使用它来设置图形的背景颜色和透明度。同样,每个Axes
边界框(典型的 Matplotlib 图中带有黑边的标准白框,都有一个Rectangle
实例来确定轴的颜色、透明度和其他属性。这些实例存储为成员变量Figure.patch
,并且Axes.patch
(“补丁”是名称继承自 MATLAB,是图形上的 2D 颜色“补丁”,例如矩形、圆形和多边形)。每个 MatplotlibArtist
都具有以下属性
财产 |
描述 |
---|---|
α |
透明度 - 0-1 的标量 |
动画 |
用于促进动画绘制的布尔值 |
轴 |
艺术家居住的斧头,可能没有 |
剪辑框 |
剪辑艺术家的边界框 |
夹上 |
是否启用剪辑 |
剪辑路径 |
艺术家被剪辑到的路径 |
包含 |
用于测试艺术家是否包含拾取点的拾取函数 |
数字 |
艺术家居住的人物实例,可能没有 |
标签 |
文本标签(例如,用于自动标记) |
拣货员 |
一个控制对象拾取的python对象 |
转换 |
转型 |
可见的 |
是否应绘制艺术家的布尔值 |
佐德 |
决定绘制顺序的数字 |
光栅化 |
布尔值;将矢量转换为光栅图形(用于压缩和 EPS 透明度) |
每个属性都使用老式的 setter 或 getter 访问(是的,我们知道这会激怒 Pythonistas,我们计划支持通过属性或特征直接访问,但尚未完成)。例如,将当前 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()
函数(仅
getp()
在 pyplot 中),它列出了属性及其值。这也适用于派生自的类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
所有类的文档字符串也包含Artist
属性,因此您可以查阅交互式“帮助”或
matplotlib.artist以获取给定对象的属性列表。
对象容器#
现在我们知道如何检查和设置我们想要配置的给定对象的属性,我们需要知道如何获取该对象。正如介绍中提到的,有两种对象:基元和容器。基元通常是您要配置的东西(Text
实例的字体, a 的宽度Line2D
),尽管容器也有一些属性 - 例如,它
是一个容器,其中包含绘图中的许多基元,但是它还具有控制 xaxis 是“线性”还是“对数”等属性。在本节中,我们将回顾各种容器对象存储您想要获取的对象的位置。Axes
Artist
xscale
Artists
图容器#
顶级容器Artist
是
matplotlib.figure.Figure
,它包含图中的所有内容。图形的背景
Rectangle
是存储在 中的
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]: <AxesSubplot:>
In [160]: print(fig.axes)
[<AxesSubplot:>, <matplotlib.axes._axes.Axes object at 0x7f0768702be0>]
因为图中维护了“当前Axes”的概念(见
Figure.gca
and
Figure.sca
)来支持pylab/pyplot状态机,所以不应该直接从Axes列表中插入或者移除Axes,而是使用
add_subplot()
and
add_axes()
方法插入,
Axes.remove
方法删除。但是,您可以自由地遍历 Axes 列表或对其进行索引以访问Axes
您想要自定义的实例。这是一个打开所有轴网格的示例:
for ax in fig.axes:
ax.grid(True)
该图窗还具有自己的images
、和属性lines
,
您可以使用它们直接添加基元。这样做时,默认坐标系将简单地以像素为单位(这通常不是您想要的)。如果您改为使用图形级别的方法来添加艺术家(例如,用于添加文本),那么默认坐标系将是“图形坐标”,其中 (0, 0) 是图形的左下角, (1, 1 ) 是图的右上角。patches
text
Figure
Figure.text
和所有Artist
的s一样,你可以通过设置transform属性来控制这个坐标系。Artist
您可以通过将转换设置为显式使用“图形坐标” fig.transFigure
:
import matplotlib.lines as lines
fig = 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()
这是图中包含的艺术家的摘要
图属性 |
描述 |
---|---|
轴 |
实例列表 |
修补 |
|
图片 |
补丁列表 |
传说 |
Figure |
线条 |
Figure |
补丁 |
Figure |
文本 |
一个列表图 |
轴容器#
这matplotlib.axes.Axes
是 Matplotlib 世界的中心——它包含了图形中使用的绝大多数内容,其中包含Artists
许多帮助方法来创建和添加这些
内容Artists
,以及访问和自定义Artists
其中包含的帮助方法。与 一样
Figure
,它包含 a
,它是
笛卡尔坐标的 a
和极坐标的 a ;这个补丁决定了绘图区域的形状、背景和边框:Patch
patch
Rectangle
Circle
ax = fig.add_subplot()
rect = ax.patch # a Rectangle instance
rect.set_facecolor('green')
当您调用绘图方法时,例如,canonical
plot
并传入数组或值列表,该方法将创建一个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 对来绘图,并且我们将长度为一个列表的第一个元素解包到行变量中。该行已添加到
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
orAxes.patches
列表中,因为在Axes
创建和添加对象时需要做一些事情:
它设置;的
figure
andaxes
属性Artist
它设置默认
Axes
转换(除非已经设置);它检查包含在 中的
Artist
数据以更新控制自动缩放的数据结构,以便可以调整视图限制以包含绘制的数据。
不过,您可以自己创建对象并将它们直接添加到
Axes
using 辅助方法中,例如add_line
和
add_patch
。这是一个带注释的交互式会话,说明了正在发生的事情:
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
辅助方法用于创建原语
Artists
并将它们添加到各自的容器中。下表总结了它们的一小部分样本、Artist
它们创建的类型以及它们的存储位置
轴辅助方法 |
艺术家 |
容器 |
---|---|---|
|
斧头文本 |
|
|
斧头补丁 |
|
|
ax.lines 和 ax.patches |
|
|
斧头补丁 |
|
|
斧头补丁 |
|
|
斧头图像 |
|
|
ax.get_legend() |
|
|
轴线 |
|
|
ax.collections |
|
|
斧头文本 |
除了所有这些之外Artists
,Axes
还包含两个重要Artist
的容器:XAxis
和YAxis
,它们处理刻度和标签的绘制。这些存储为实例变量
xaxis
和
yaxis
. XAxis
和YAxis
容器将在下面详细介绍,但请注意,其中包含Axes
许多将调用转发到
Axis
实例的辅助方法,因此您通常不需要直接使用它们,除非您愿意。例如,您可以XAxis
使用Axes
辅助方法设置刻度标签的字体颜色:
ax.tick_params(axis='x', labelcolor='orange')
以下是Axes
包含的艺术家的摘要
轴属性 |
描述 |
---|---|
艺术家 |
一个实例 |
修补 |
|
收藏品 |
一个实例 |
图片 |
|
线条 |
一个实例 |
补丁 |
一个实例 |
文本 |
一个实例 |
x轴 |
|
y轴 |
图例可以通过get_legend
,
轴容器#
这些matplotlib.axis.Axis
实例处理刻度线、网格线、刻度标签和轴标签的绘制。您可以为 y 轴分别配置左右刻度,为 x 轴分别配置上下刻度。Axis
还存储用于自动缩放、平移和缩放的数据和视图间隔,以及控制刻度放置位置以及如何将它们表示为字符串的和实例Locator
。
Formatter
每个Axis
对象都包含一个label
属性(这是pyplot
在调用xlabel
and
中修改的内容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()
array([0. , 0.2, 0.4, 0.6, 0.8, 1. ])
[Text(0.0, 0, '0.0'), Text(0.2, 0, '0.2'), Text(0.4, 0, '0.4'), Text(0.6000000000000001, 0, '0.6'), Text(0.8, 0, '0.8'), Text(1.0, 0, '1.0')]
请注意,刻度线的数量是标签的两倍,因为默认情况下,顶部和底部都有刻度线,但只有 xaxis 下方的刻度线;但是,这可以定制。
<a list of 12 Line2D ticklines objects>
使用上述方法,默认情况下您只能获取主要刻度的列表,但您也可以要求次要刻度:
axis.get_ticklabels(minor=True)
axis.get_ticklines(minor=True)
<a list of 0 Line2D ticklines objects>
下面是一些有用的访问器方法的摘要Axis
(这些在有用的地方都有相应的设置器,例如
set_major_formatter()
。)
轴访问器方法 |
描述 |
---|---|
轴的比例,例如“对数”或“线性” |
|
轴视图限制的间隔实例 |
|
Axis 数据限制的区间实例 |
|
轴的网格线列表 |
|
Axis 标签 - 一个 |
|
轴偏移文本 - 一个 |
|
实例列表 |
|
实例列表 |
|
Tick 位置列表 - 关键字 minor=True|False |
|
主要刻度的 |
|
主要刻度的 |
|
|
|
|
|
|
|
|
|
打开或关闭主要或次要刻度的网格 |
这是一个示例,不推荐因为它的美观,它自定义了 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 instance
label.set_color('red')
label.set_rotation(45)
label.set_fontsize(16)
for line in ax1.yaxis.get_ticklines():
# line is a Line2D instance
line.set_color('green')
line.set_markersize(25)
line.set_markeredgewidth(3)
plt.show()
勾选容器#
The是我们从到 到
到 的
下降matplotlib.axis.Tick
过程中的最后一个容器对象。包含刻度和网格线实例,以及上下刻度的标签实例。这些中的每一个都可以作为.Figure
Axes
Axis
Tick
Tick
Tick
勾选属性 |
描述 |
---|---|
滴答1线 |
一个 |
tick2line |
一个 |
网格线 |
一个 |
标签1 |
一个 |
标签2 |
一个 |
这是一个示例,它使用美元符号设置右侧刻度的格式化程序,并在 y 轴的右侧将它们着色为绿色。
import numpy as np
import matplotlib.pyplot as plt
# 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()
脚本总运行时间:(0分1.067秒)