Matplotlib画图标注annotate详解
标注
原⽂:
译者:
协议:
基本标注
使⽤text()会将⽂本放置在轴域的任意位置。⽂本的⼀个常见⽤例是标注绘图的某些特征,⽽annotate()⽅法提供辅助函数,使标注变得容易。在标注中,有两个要考虑的点:由参数xy表⽰的标注位置和xytext的⽂本位置。这两个参数都是(x, y)元组。
import numpy as np
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot(111)
t = np.arange(0.0, 5.0, 0.01)
s = np.cos(2*np.pi*t)
line, = ax.plot(t, s, lw=2)
ax.annotate('local max', xy=(2, 1), xytext=(3, 1.5),
arrowprops=dict(facecolor='black', shrink=0.05),
)
ax.set_ylim(-2,2)
plt.show()
在该⽰例中,xy(箭头尖端)和xytext位置(⽂本位置)都以数据坐标为单位。有多种可以选择的其他坐标系 - 你可以使
⽤xycoords和textcoords以及下列字符串之⼀(默认为data)指定xy和xytext的坐标系。
| 参数 | 坐标系 |
| 'figure points' | 距离图形左下⾓的点数量 |
| 'figure pixels' | 距离图形左下⾓的像素数量 |
| 'figure fraction' | 0,0 是图形左下⾓,1,1 是右上⾓ |
| 'axes points' | 距离轴域左下⾓的点数量 |
| 'axes pixels' | 距离轴域左下⾓的像素数量 |
| 'axes fraction' | 0,0 是轴域左下⾓,1,1 是右上⾓ |
| 'data' | 使⽤轴域数据坐标系 |
例如将⽂本以轴域⼩数坐标系来放置,我们可以:
ax.annotate('local max', xy=(3, 1), xycoords='data',
xytext=(0.8, 0.95), textcoords='axes fraction',
arrowprops=dict(facecolor='black', shrink=0.05),
horizontalalignment='right', verticalalignment='top',
)
对于物理坐标系(点或像素),原点是图形或轴的左下⾓。
或者,你可以通过在可选关键字参数arrowprops中提供箭头属性字典来绘制从⽂本到注释点的箭头。
arrowprops键描述
width箭头宽度,以点为单位
frac箭头头部所占据的⽐例
headwidth箭头的底部的宽度,以点为单位
shrink移动提⽰,并使其离注释点和⽂本⼀些距离
**kwargs matplotlib.patches.Polygon的任何键,例如facecolor
在下⾯的⽰例中,xy点是原始坐标(xycoords默认为'data')。对于极坐标轴,它在(theta, radius)空间中。此⽰例中的⽂本放置在图形⼩数坐标系中。Text关键字args,例如horizontalalignment,verticalalignment和fontsize,从annotate传给Text实例。
注释(包括花式箭头)的所有⾼上⼤的内容的更多信息,请参阅和。
不要继续,除⾮你已经阅读了,和。
⾼级标注
使⽤框和⽂本来标注
让我们以⼀个简单的例⼦来开始。
在pyplot模块(或Axes类的text⽅法)中的text()函数接受bbox关键字参数,并且在提供时,在⽂本周围绘制⼀个框。
与⽂本相关联的补丁对象可以通过以下⽅式访问:
bb = t.get_bbox_patch()
返回值是FancyBboxPatch的⼀个实例,并且补丁属性(如facecolor,edgewidth等)可以像平常⼀样访问和修改。为了更改框的形状,请使
⽤set_boxstyle⽅法。
bb.set_boxstyle("rarrow", pad=0.6)
该参数是框样式的名称与其作为关键字参数的属性。⽬前,实现了以下框样式。
类名称属性
Circle circle pad=0.3
DArrow darrow pad=0.3
LArrow larrow pad=0.3
RArrow rarrow pad=0.3
Round round pad=0.3,rounding_size=None
Round4round4pad=0.3,rounding_size=None
Roundtooth roundtooth pad=0.3,tooth_size=None
Sawtooth sawtooth pad=0.3,tooth_size=None
Square square pad=0.3
注意,属性参数可以在样式名称中⽤逗号分隔(在初始化⽂本实例时,此形式可以⽤作bbox参数的boxstyle的值)。
bb.set_boxstyle("rarrow,pad=0.6")
使⽤箭头来标注
pyplot模块(或Axes类的annotate⽅法)中的annotate()函数⽤于绘制连接图上两点的箭头。
ax.annotate("Annotation",
xy=(x1, y1), xycoords='data',
xytext=(x2, y2), textcoords='offset points',
)
这会使⽤textcoords中提供的,xytext处的⽂本标注提供坐标(xycoords)中的xy处的点。通常,数据坐标中规定了标注点,偏移点中规定了标注⽂本。请参阅annotate()了解可⽤的坐标系。
连接两个点(xy和xytext)的箭头可以通过指定arrowprops参数可选地绘制。为了仅绘制箭头,请使⽤空字符串作为第⼀个参数。
ax.annotate("",
xy=(0.2, 0.2), xycoords='data',
xytext=(0.8, 0.8), textcoords='data',
arrowprops=dict(arrow,
connection),
)
箭头的绘制需要⼏个步骤。
创建两个点之间的连接路径。这由connectionstyle键值控制。
如果提供了补丁对象(patchA和patchB),则会剪切路径以避开该补丁。
路径进⼀步由提供的像素总量来缩⼩(shirnkA&shrinkB)
路径转换为箭头补丁,由arrowstyle键值控制。
两个点之间的连接路径的创建由connectionstyle键控制,并且可⽤以下样式。
名称属性
angle angleA=90,angleB=0,rad=0.0
angle3angleA=90,angleB=0
名称属性
arc angleA=0,angleB=0,armA=None,armB=None,rad=0.0
arc3rad=0.0
bar armA=0.0,armB=0.0,fraction=0.3,angle=None
注意,angle3和arc3中的3意味着所得到的路径是⼆次样条段(三个控制点)。如下⾯将讨论的,当连接路径是⼆次样条时,可以使⽤⼀些箭头样式选项。
每个连接样式的⾏为在下⾯的⽰例中(有限地)演⽰。(警告:条形样式的⾏为当前未定义好,将来可能会更改)。
然后根据给定的箭头样式将连接路径(在剪切和收缩之后)变换为箭头补丁。
名称属性
-None
->head_length=0.4,head_width=0.2
-[widthB=1.0,lengthB=0.2,angleB=None
|-|widthA=1.0,widthB=1.0
-|>head_length=0.4,head_width=0.2
<-head_length=0.4,head_width=0.2
<->head_length=0.4,head_width=0.2
<|-head_length=0.4,head_width=0.2
<-|>
fancy head_length=0.4,head_width=0.4,tail_width=0.4
simple head_length=0.5,head_width=0.5,tail_width=0.2
wedge tail_width=0.3,shrink_factor=0.5
⼀些箭头仅适⽤于⽣成⼆次样条线段的连接样式。他们是fancy,simple,wedge。对于这些箭头样式,必须使⽤angle3或arc3连接样式。
如果提供了标注字符串,则patchA默认设置为⽂本的bbox补丁。
与text命令⼀样,可以使⽤bbox参数来绘制⽂本周围的框。
默认情况下,起点设置为⽂本范围的中⼼。可以使⽤relpos键值进⾏调整。这些值根据⽂本的范围进⾏归⼀化。例如,(0,0)表⽰左下
⾓,(1,1)表⽰右上⾓。
将艺术家放置在轴域的锚定位置
有⼀类艺术家可以放置在轴域的锚定位置。⼀个常见的例⼦是图例。这种类型的艺术家可以使⽤OffsetBox类创建。
mpl_toolkits.axes_grid.anchored_artists中有⼏个预定义类。
from mpl_toolkits.axes_grid.anchored_artists import AnchoredText
at = AnchoredText("Figure 1a",
prop=dict(size=8), frameon=True,
loc=2,
)
at.patch.set_boxstyle("round,pad=0.,rounding_size=0.2")
ax.add_artist(at)
loc关键字与legend命令中含义相同。
⼀个简单的应⽤是当艺术家(或艺术家的集合)的像素⼤⼩在创建时已知。例如,如果要绘制⼀个固定⼤⼩为 20 像素 ×20 像素(半径为10 像素)的圆,则可以使⽤AnchoredDrawingArea。实例使⽤绘图区域的⼤⼩创建(以像素为单位)。⽤户可以在绘图区任意添加艺术家。注意,添加到绘图区域的艺术家的范围与绘制区域本⾝的位置⽆关,只和初始⼤⼩有关。
from mpl_toolkits.axes_grid.anchored_artists import AnchoredDrawingArea
ada = AnchoredDrawingArea(20, 20, 0, 0,
loc=1, pad=0., frameon=False)
p1 = Circle((10, 10), 10)
ada.drawing_area.add_artist(p1)
p2 = Circle((30, 10), 5, fc="r")
ada.drawing_area.add_artist(p2)
添加到绘图区域的艺术家不应该具有变换集(它们将被重写),并且那些艺术家的尺⼨被解释为像素坐标,即,上述⽰例中的圆的半径分别是 10 像素和 5 像素。
有时,你想让你的艺术家按数据坐标(或其他坐标,⽽不是画布像素)缩放。你可以使⽤AnchoredAuxTransformBox类。这类似
于AnchoredDrawingArea,除了艺术家的范围在绘制时由指定的变换确定。
from mpl_toolkits.axes_grid.anchored_artists import AnchoredAuxTransformBox
box = ansData, loc=2)
el = Ellipse((0,0), width=0.1, height=0.4, angle=30) # in data coordinates!
box.drawing_area.add_artist(el)
上述⽰例中的椭圆具有在数据坐标中对应于 0.1 和 0.4 的宽度和⾼度,并且当轴域的视图限制改变时将⾃动缩放。
如图例所⽰,可以设置bbox_to_anchor参数。使⽤HPacker和VPacker,你可以像图例中⼀样排列艺术家(事实上,这是图例的创建⽅式)。
请注意,与图例不同,默认情况下,bbox_transform设置为IdentityTransform。
使⽤复杂坐标来标注
matplotlib 中的标注⽀持中描述的⼏种类型的坐标。对于想要更多控制的⾼级⽤户,它⽀持⼏个其他选项。
1. Transform实例,例如:
ax.annotate("Test", xy=(0.5, 0.5), ansAxes)
2. 相当于:
ax.annotate("Test", xy=(0.5, 0.5), xycoords="axes fraction")
3. 使⽤它,你可以在其他轴域内标注⼀个点:
ax1, ax2 = subplot(121), subplot(122)
ax2.annotate("Test", xy=(0.5, 0.5), ansData,
xytext=(0.5, 0.5), ansData,
arrowprops=dict(arrow))
4.Artist实例。xy值(或xytext)被解释为艺术家的bbox(get_window_extent的返回值)的⼩数坐标。
an1 = ax.annotate("Test 1", xy=(0.5, 0.5), xycoords="data",
va="center", ha="center",
bbox=dict(box, fc="w"))
an2 = ax.annotate("Test 2", xy=(1, 0.5), xycoords=an1, # (1,0.5) of the an1's bbox
xytext=(30,0), textcoords="offset points",
va="center", ha="left",
bbox=dict(box, fc="w"),
arrowprops=dict(arrow))
请注意,你的责任是在绘制an2之前确定坐标艺术家(上例中的an1)的范围。在⼤多数情况下,这意味着an2需要晚于an1。
1. ⼀个返回BboxBase或Transform的实例的可调⽤对象。如果返回⼀个变换,它与 1 相同,如果返回bbox,它与 2 相同。可调⽤对象
应该接受renderer实例的单个参数。例如,以下两个命令产⽣相同的结果:
an2 = ax.annotate("Test 2", xy=(1, 0.5), xycoords=an1,
xytext=(30,0), textcoords="offset points")
an2 = ax.annotate("Test 2", xy=(1, 0.5), _window_extent,
xytext=(30,0), textcoords="offset points")
指定⼆元坐标的元组。第⼀项⽤于
x
坐标,第⼆项⽤于
y
坐标。例如,
1. annotate("Test", xy=(0.5, 1), xycoords=("data", "axes fraction"))
2. 0.5 的单位是数据坐标,1 的单位是归⼀化轴域坐标。你可以像使⽤元组⼀样使⽤艺术家或变换。例如,
import matplotlib.pyplot as plt
plt.figure(figsize=(3,2))
ax=plt.axes([0.1, 0.1, 0.8, 0.7])
an1 = ax.annotate("Test 1", xy=(0.5, 0.5), xycoords="data",
va="center", ha="center",
bbox=dict(box, fc="w"))
an2 = ax.annotate("Test 2", xy=(0.5, 1.), xycoords=an1,
xytext=(0.5,1.1), textcoords=(an1, "axes fraction"),
va="bottom", ha="center",
matplotlib中subplotbbox=dict(box, fc="w"),
arrowprops=dict(arrow))
plt.show()
3.
4. 有时,您希望您的注释带有⼀些“偏移点”,不是距离注释点,⽽是距离某些其他点。OffsetFrom是这种情况下的辅助类。
import matplotlib.pyplot as plt
plt.figure(figsize=(3,2))
ax=plt.axes([0.1, 0.1, 0.8, 0.7])
an1 = ax.annotate("Test 1", xy=(0.5, 0.5), xycoords="data",
va="center", ha="center",
bbox=dict(box, fc="w"))
import OffsetFrom
offset_from = OffsetFrom(an1, (0.5, 0))
an2 = ax.annotate("Test 2", xy=(0.1, 0.1), xycoords="data",
xytext=(0, -10), textcoords=offset_from,
# xytext is offset points from "xy=(0.5, 0), xycoords=an1"
va="top", ha="center",
bbox=dict(box, fc="w"),
arrowprops=dict(arrow))
plt.show()
5.
你可以参考这个链接:。
使⽤ConnectorPatch
ConnectorPatch类似于没有⽂本的标注。虽然在⼤多数情况下建议使⽤标注函数,但是当您想在不同的轴上连接点时,ConnectorPatch很有⽤。from matplotlib.patches import ConnectionPatch
xy = (0.2, 0.2)
con = ConnectionPatch(xyA=xy, xyB=xy, coordsA="data", coordsB="data",
axesA=ax1, axesB=ax2)
ax2.add_artist(con)
上述代码连接了ax1中数据坐标的xy点,与ax2中数据坐标的xy点。这是个简单的例⼦。
虽然ConnectorPatch实例可以添加到任何轴,但您可能需要将其添加到绘图顺序中最新的轴,以防⽌与其他轴重叠。
⾼级话题
轴域之间的缩放效果
mpl_toolkits.axes_grid.inset_locator定义了⼀些补丁类,⽤于互连两个轴域。理解代码需要⼀些 mpl 转换如何⼯作的知识。但是,利⽤它的⽅式很直接。
定义⾃定义盒样式
你可以使⽤⾃定义盒样式,boxstyle的值可以为如下形式的可调⽤对象:
def__call__(self, x0, y0, width, height, mutation_size,
aspect_ratio=1.):
"""
Given the location and size of the box, return the path of
the box around it.
- *x0*, *y0*, *width*, *height* : location and size of the box
- *mutation_size* : a reference scale for the mutation.
- *aspect_ratio* : aspect-ratio for the mutation.
"""
path = ...
return path
这⾥是个复杂的例⼦:
但是,推荐你从matplotlib.patches.BoxStyle._Base派⽣,像这样:
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论