Matplotlib进阶教程:Artist讲解

7ea5d917bfddb9b811df9aaa94fed125.gif

在后台回复【阅读书籍】

即可获取python相关电子书~

Hi,我是山月。

之前给大家介绍了Matplotlib的入门教程,不知道大家对它是不是有了个基础的了解。

今天我们来介绍下Matplotlib里的Artist~

matplotlib API 共有三层:

  • matplotlib.backend_bases.FigureCanvas :绘图区

  • matplotlib.backend_bases.Renderer:渲染器,如何在 FigureCanvas 上绘图

  • matplotlib.artist.Artist:如何使用一个渲染器在画布上绘图

FigureCanvas和Renderer处理与用户界面工具包或绘图语言对话的所有细节;而Artist处理所有高级结构(如表现和布局图形、文本、线条)。

Artist有两种类型:primitives(基元)和containers(容器)。

primitives(基元)代表我们想要在画布上绘制的标准图形对象:Line2D、Rectangle、Text、AxesImage 等;

而containers(容器)是放置基元的地方(Axis、Axes 和 Figure)。

标准的用法是先创建一个 Figure 实例,然后使用 Figure 创建一个或多个 Axes 或 Subplot 实例;

最后使用 Axes 实例的辅助方法(plot()、text()、hist()、imshow())来创建一些常见的图形基元,然后将它们添加到相关容器中,并在请求时绘制它们。

如:

import matplotlib.pyplot as plt
fig = plt.figure() # 创建了一个 Figure 实例
ax = fig.add_subplot(2, 1, 1)  # 只显示选择的第1子图

如果要在任意位置创建 Axes,只需使用 add_axes() 方法:

fig2 = plt.figure()
ax2 = fig2.add_axes([0.15, 0.1, 0.7, 0.3]) # 四个值分别代表了(left,bottom,width,height),范围为0-1

继续我们的例子:

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 实例(记住 Subplot 只是 Axes 的子类)。

当调用 ax.plot 时,它会创建一个 Line2D 实例并将其添加到 Axes.lines 列表中。

可以看到 Axes.lines 列表的长度为 1 ,与line, = ax.plot() 返回值相同:

print(ax.lines) # >>> <Axes.ArtistList of 1 lines>
print(ax.lines[0])  # >>> Line2D(_child0)
print(line)  # >>> Line2D(_child0)

删除Line2D 实例的方法:

ax.lines.remove(line)

每个 Axes 实例包含一个 XAxis 和一个 YAxis 实例,它们处理刻度、刻度标签和轴标签的布局和绘制。

xtext = ax.set_xlabel('my xdata') # 设置x轴标签
ytext = ax.set_ylabel('my ydata') # 设置y轴标签

完整示例:

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)

# 修复随机状态以实现可重复性
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()

效果:

d3c6c238f7cd7af0ae8b1179a8a37556.png

1、自定义对象

图形中的每个元素都由一个Artist 表示,并且每个元素都有一个广泛的属性列表来配置其外观。

图形本身包含一个与图形大小完全相同的 Rectangle,你可以使用它来设置图形的背景颜色和透明度。

同样,每个 Axes 边界框(典型 matplotlib 图中带有黑边的标准白框)都有一个 Rectangle 实例,该实例确定 Axes 的颜色、透明度和其他属性。

这些实例存储为变量 Figure.patch 和 Axes .patch。

每个 matplotlib Artist都具有以下属性:

642fd48fbe0d401a672df4df26f212db.png

每个属性都使用 setter 或 getter 访问。例如,将当前 alpha 乘以一半:

a = o.get_alpha()
o.set_alpha(0.5*a)

如果要一次设置多个属性,可以使用带有关键字参数的 set 方法。例如:

o.set(alpha=0.5, zorder=2)

matplotlib.artist.getp() 函数(在 pyplot 中可以简单地写成 getp() )可以检查 Artist 属性:

import matplotlib.pyplot as plt
fig = plt.figure()
print(plt.getp(fig.patch))
'''
    agg_filter = None
    alpha = None
    angle = 0.0
    animated = False
    antialiased or aa = False
    bbox = Bbox(x0=0.0, y0=0.0, x1=1.0, y1=1.0)
    capstyle = CapStyle.butt
    children = []
    clip_box = None
    clip_on = True
    clip_path = 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 = 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 = False
    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
None
'''

2、对象容器

容器也有一些属性,比如 Axes 是一个容器,它包含了许多基元,但它也有像 xscale 这样的属性来控制 xaxis 是“线性”还是“对数”。

1、Figure容器

Artist顶级容器是 matplotlib.figure.Figure,它包含图中的所有内容。

Figure的背景是存储在 Figure.patch 中的 Rectangle,当你向图中添加子图 和axes时,这些将附加到 Figure.axes。

import matplotlib.pyplot as plt

fig = plt.figure()
ax1 = fig.add_subplot(211)
ax2 = fig.add_axes([0.1, 0.1, 0.7, 0.3])

print(ax1)  # >>> AxesSubplot(0.125,0.53;0.775x0.35)
print(fig.axes)  # >>> [<AxesSubplot:>, <Axes:>]

你可以使用 add_subplot( ) 和 add_axes() 方法插入 axes ;delaxes() 方法删除 axes 。

也可以自由地遍历axes列表或对其进行索引以访问你想要自定义的axes实例:

for ax in fig.axes:
    ax.grid(True) # 显示网格

Figure有自己的 text, lines, patches 和 images,你可以直接使用它们添加基元。

Figure 的默认坐标系是以像素为单位,但你可以通过设置transform 属性来控制它。

比如将 transform 设置为 fig.transFigure 可以把坐标变成图形坐标,图形坐标的 (0, 0) 是图形的左下角, (1, 1) 是图形的右上角:

import matplotlib.pyplot as plt
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()

效果:

1e8cc04c42e0d46ca9e8cab99a041d61.png

Figure 中包含的Artists总结:

74c1661144cb55ab972240a7373894a6.png


2、Axes容器

matplotlib.axes.Axes 是 matplotlib 的核心:它包含了figure中绝大多数的Artist ,以及创建、访问和自定义这些Artist的函数方法。

和figure一样,它有一个Patch对象(笛卡尔坐标下是个Rectangle对象,极坐标下是个 Circle对象)。

patch决定了绘图区域的形状、背景和边框:

import matplotlib.pyplot as plt

fig = plt.figure()
ax = fig.add_subplot(111)
rect = ax.patch  # 一个Rectangle 实例
rect.set_facecolor('green')

plt.show()

效果:

432f4dc65a79a5d6c163c8396eb207ea.png

当你调用绘图方法(比如plot())时,它会创建一个 matplotlib.lines.Line2D() 实例。

可以使用作为关键字参数传递的所有Line2D属性来更新线条,并将线条添加到Axes.lines容器:

x, y = np.random.rand(2, 100)
line, = ax.plot(x, y, '-', color='blue', linewidth=2)

plot 返回一个 lines列表,因为我们可以传入多组 x, y 来绘图:

print(ax.lines) # <Axes.ArtistList of 1 lines>

创建patches的方法类似于创建一个矩形列表,并且patches也会被添加到 Axes.patches 列表中:

import matplotlib.pyplot as plt
import numpy as np

fig = plt.figure()
ax = fig.add_subplot(111)

n, bins, rectangles = ax.hist(np.random.randn(1000), 50, facecolor='yellow')
print(rectangles)   #  <BarContainer object of 50 artists>
print(len(ax.patches))  # 50

一般我们不将对象直接添加到 Axes.lines 或 Axes.patches 列表中,而是自己创建对象并使用 add_line() 和 add_patch() 等辅助方法将它们添加到 Axes。

import matplotlib.pyplot as plt
import matplotlib

fig, ax = plt.subplots()
rect = matplotlib.patches.Rectangle((1, 1), width=5, height=12) # 创建一个矩形实例
print(rect.axes)   # >>> None. 默认情况下,axes实例为 None

ax.add_patch(rect) # 把矩形添加到Axes上
print(rect.axes)    # >>> AxesSubplot(0.125,0.11;0.775x0.77)

# ax.get_xlim():获得Axes的x坐标范围,默认是 (0.0, 1.0)
print(ax.get_xlim())    # >>> (0.0, 1.0)

# 自动调整坐标轴范围
ax.autoscale_view()

# x坐标范围被更新
print(ax.get_xlim())    # >>> (0.75, 6.25)

plt.show()

效果:

149b6d431a4fabd76fb4315813d6f723.png

有很多 Axes 方法可以创建 Artists 对象并把它们添加到各自的容器中:

4c47c482b2db3fe171ac8961a18ddac5.png

除了这些 Artists 之外,Axes 还包含两个重要的 Artist 容器:XAxis 和 YAxis,它们可以处理刻度和绘制标签。

以下是 Axes 包含的Artist对象汇总:

fcc70ed9899c32b9ef6780376b3c8618.png

3、Axis容器

matplotlib.axis.Axis 实例处理刻度线、网格线、刻度标签和轴标签的绘制。

你可以为 y 轴分别配置左右刻度,为 x 轴分别配置上下刻度。

Axis 还存储用于自动缩放、平移和缩放的数据和视图间隔,以及控制刻度放置位置和如何将它们表示为字符串的 Locator 和 Formatter 实例。

每个 Axis 对象都包含一个标签属性以及主/次刻度的列表,其中主要和次刻度的列表可以通过get_major_ticks() 和 get_minor_ticks()方法 访问。

刻度是 XTick 和 YTick 实例,它们包含渲染刻度和刻度标签的实际线条和文本基元。

Axis 实例可以返回刻度线、刻度标签、刻度位置等:

import matplotlib.pyplot as plt

fig, ax = plt.subplots()
axis = ax.xaxis

ticklocs = axis.get_ticklocs() # 获取刻度位置
print(ticklocs) # >>> [0.  0.2 0.4 0.6 0.8 1. ]

ticklabels = axis.get_ticklabels() # 获取刻度标签
print(ticklabels)   #>>> [Text(0, 0, ''), Text(0, 0, ''), Text(0, 0, ''), Text(0, 0, ''), Text(0, 0, ''), Text(0, 0, '')]

ticklines = axis.get_ticklines() # 获取刻度线
print(ticklines)    #>>> <a list of 12 Line2D ticklines objects>

plt.show()

效果:

f6e7444d980addc4564410c9cd29fcc9.png

注意刻度线的数量是标签的两倍,因为默认情况下,顶部和底部都有刻度线,但只有 底部有刻度标签。

使用get_ticklines()默认情况下只能获取主刻度的列表,如果你想求次刻度的可以:

axis.get_ticklabels(minor=True)
axis.get_ticklines(minor=True)

一些有用的 Axis访问方法的总结:

1f3e3665482f9907316cbac24975ed3c.png

示例:

import matplotlib.pyplot as plt

# plt.figure 创建了一个 matplotlib.figure.Figure实例
fig = plt.figure()
rect = fig.patch  # 矩形实例
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是一个文本实例
    label.set_color('red')
    label.set_rotation(45)
    label.set_fontsize(16)

for line in ax1.yaxis.get_ticklines():
    # line是一个Line2D实例
    line.set_markersize(25)
    line.set_markeredgewidth(3)

plt.show()

效果:

a18add37e3984dfdf8fe515f35167ae9.png

4、Tick容器

matplotlib.axis.Tick 是我们在 Figure - Axes - Axis - Tick 过程中的最终容器对象。

Tick 包含刻度和网格线实例,以及上下刻度的标签实例,这些中的每一个都可以作为 Tick 的属性直接访问。

d8529b1b8d1a1f695d2d6386a4231519.png

示例:

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

np.random.seed(19680801)
fig, ax = plt.subplots()
ax.plot(100*np.random.rand(20))

formatter = ticker.FormatStrFormatter('$%1.2f')
ax.yaxis.set_major_formatter(formatter)

for tick in ax.yaxis.get_major_ticks():
    tick.label1.set_visible(False)
    tick.label2.set_visible(True)
    tick.label2.set_color('green')

plt.show()

效果:

2a105ba61bd709e745037894dae25848.png

好啦,关于Artist的介绍就到这~

365f0dc0a45f917d25eb0dfa49d47a6e.png

END

0059c9302001c0f33a071935d6528995.gif

您的“点赞”、“在看”和 “分享”是我们产出的动力。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值