|
| 1 | +# 3.9 轴域标注 |
| 2 | + |
| 3 | +> 原文:[Annotating Axes](http://matplotlib.org/users/annotations_guide.html) |
| 4 | +
|
| 5 | +> 译者:[飞龙](https://github.com/) |
| 6 | +
|
| 7 | +> 协议:[CC BY-NC-SA 4.0](http://creativecommons.org/licenses/by-nc-sa/4.0/) |
| 8 | +
|
| 9 | +## 轴域标注 |
| 10 | + |
| 11 | +除非你已经读过了[文本标注](http://matplotlib.org/users/annotations_intro.html#annotations-tutorial)、[`text()`](http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.text)和[`annotate()`](http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.annotate),否则不要继续往下看。 |
| 12 | + |
| 13 | +## 使用框和文本来标注 |
| 14 | + |
| 15 | +让我们以一个简单的例子来开始。 |
| 16 | + |
| 17 | +[源代码](http://matplotlib.org/users/plotting/examples/annotate_text_arrow.py) |
| 18 | + |
| 19 | + |
| 20 | + |
| 21 | +在`pyplot`模块(或`Axes`类的`text`方法)中的`text()`函数接受`bbox`关键字参数,并且在提供时,在文本周围绘制一个框。 |
| 22 | + |
| 23 | +与文本相关联的`patch`对象可以通过以下方式访问: |
| 24 | + |
| 25 | +```py |
| 26 | +bb = t.get_bbox_patch() |
| 27 | +``` |
| 28 | + |
| 29 | +返回值是`FancyBboxPatch`的一个实例,并且`patch`属性(如`facecolor`,`edgewidth`等)可以像平常一样访问和修改。 为了更改框的形状,请使用`set_boxstyle`方法。 |
| 30 | + |
| 31 | +```py |
| 32 | +bb.set_boxstyle("rarrow", pad=0.6) |
| 33 | +``` |
| 34 | + |
| 35 | +该参数是框样式的名称与其作为关键字参数的属性。 目前,实现了以下框样式。 |
| 36 | + |
| 37 | +| 类 | 名称 | 属性 | |
| 38 | +| --- | --- | |
| 39 | +| Circle | `circle` | `pad=0.3` | |
| 40 | +| DArrow | `darrow` | `pad=0.3` | |
| 41 | +| LArrow | `larrow` | `pad=0.3` | |
| 42 | +| RArrow | `rarrow` | `pad=0.3` | |
| 43 | +| Round | `round` | `pad=0.3,rounding_size=None` | |
| 44 | +| Round4 | `round4` | `pad=0.3,rounding_size=None` | |
| 45 | +| Roundtooth | `roundtooth` | `pad=0.3,tooth_size=None` | |
| 46 | +| Sawtooth | `sawtooth` | `pad=0.3,tooth_size=None` | |
| 47 | +| Square | `square` | `pad=0.3` | |
| 48 | + |
| 49 | +[源代码](http://matplotlib.org/mpl_examples/pylab_examples/fancybox_demo2.py) |
| 50 | + |
| 51 | + |
| 52 | + |
| 53 | +注意,属性参数可以在样式名称中用逗号分隔(在初始化文本实例时,此形式可以用作`bbox`参数的`boxstyle`的值)。 |
| 54 | + |
| 55 | +```py |
| 56 | +bb.set_boxstyle("rarrow,pad=0.6") |
| 57 | +``` |
| 58 | + |
| 59 | +## 使用箭头来标注 |
| 60 | + |
| 61 | + |
| 62 | +`pyplot`模块(或`Axes`类的`annotate`方法)中的`annotate()`函数用于绘制连接图上两点的箭头。 |
| 63 | + |
| 64 | +```py |
| 65 | +ax.annotate("Annotation", |
| 66 | + xy=(x1, y1), xycoords='data', |
| 67 | + xytext=(x2, y2), textcoords='offset points', |
| 68 | + ) |
| 69 | +``` |
| 70 | + |
| 71 | +这会使用`textcoords`中提供的,`xytext`处的文本标注提供坐标(`xycoords`)中的`xy`处的点。 通常,数据坐标中规定了标注点,偏移点中规定了标注文本。 请参阅`annotate()`了解可用的坐标系。 |
| 72 | + |
| 73 | +连接两个点(`xy`和`xytext`)的箭头可以通过指定`arrowprops`参数可选地绘制。 为了仅绘制箭头,请使用空字符串作为第一个参数。 |
| 74 | + |
| 75 | +```py |
| 76 | +ax.annotate("", |
| 77 | + xy=(0.2, 0.2), xycoords='data', |
| 78 | + xytext=(0.8, 0.8), textcoords='data', |
| 79 | + arrowprops=dict(arrowstyle="->", |
| 80 | + connectionstyle="arc3"), |
| 81 | + ) |
| 82 | +``` |
| 83 | + |
| 84 | +[源代码](http://matplotlib.org/users/plotting/examples/annotate_simple01.py) |
| 85 | + |
| 86 | + |
| 87 | + |
| 88 | +箭头的绘制需要几个步骤。 |
| 89 | + |
| 90 | ++ 创建两个点之间的连接路径。 这由`connectionstyle`键值控制。 |
| 91 | ++ 如果提供了`patch`对象(`patchA`和`patchB`),则会剪切路径以避开该`patch`。 |
| 92 | ++ 路径进一步由提供的像素总量来缩小(`shirnkA`&`shrinkB`) |
| 93 | ++ 路径转换为箭头`patch`,由`arrowstyle`键值控制。 |
| 94 | + |
| 95 | +[源代码](http://matplotlib.org/users/plotting/examples/annotate_explain.py) |
| 96 | + |
| 97 | + |
| 98 | + |
| 99 | +两个点之间的连接路径的创建由`connectionstyle `键控制,并且可用以下样式。 |
| 100 | + |
| 101 | +| 名称 | 属性 | |
| 102 | +| --- | --- | |
| 103 | +| angle | `angleA=90,angleB=0,rad=0.0` | |
| 104 | +| angle3 | `angleA=90,angleB=0` | |
| 105 | +| arc | `angleA=0,angleB=0,armA=None,armB=None,rad=0.0` | |
| 106 | +| arc3 | `rad=0.0` | |
| 107 | +| bar | `armA=0.0,armB=0.0,fraction=0.3,angle=None` | |
| 108 | + |
| 109 | +注意,`angle3`和`arc3`中的`3`意味着所得到的路径是二次样条段(三个控制点)。 如下面将讨论的,当连接路径是二次样条时,可以使用一些箭头样式选项。 |
| 110 | + |
| 111 | +每个连接样式的行为在下面的示例中(有限地)演示。 (警告:条形样式的行为当前未定义好,将来可能会更改)。 |
| 112 | + |
| 113 | +[源代码](http://matplotlib.org/users/plotting/examples/connectionstyle_demo.py) |
| 114 | + |
| 115 | + |
| 116 | + |
| 117 | +然后根据给定的箭头样式将连接路径(在剪切和收缩之后)变换为箭头`patch`。 |
| 118 | + |
| 119 | +| 名称 | 属性 | |
| 120 | +| --- | --- | |
| 121 | +| - | `None` | |
| 122 | +| -> | `head_length=0.4,head_width=0.2` | |
| 123 | +| -[ | `widthB=1.0,lengthB=0.2,angleB=None` | |
| 124 | +| |-| | `widthA=1.0,widthB=1.0` | |
| 125 | +| -|> | `head_length=0.4,head_width=0.2` | |
| 126 | +| <- | `head_length=0.4,head_width=0.2` | |
| 127 | +| <-> | `head_length=0.4,head_width=0.2` | |
| 128 | +| <|- | `head_length=0.4,head_width=0.2` | |
| 129 | +| <|-|> | `head_length=0.4,head_width=0.2` | |
| 130 | +| fancy | `head_length=0.4,head_width=0.4,tail_width=0.4` | |
| 131 | +| simple | `head_length=0.5,head_width=0.5,tail_width=0.2` | |
| 132 | +| wedge | `tail_width=0.3,shrink_factor=0.5` | |
| 133 | + |
| 134 | +[源代码](http://matplotlib.org/mpl_examples/pylab_examples/fancyarrow_demo.py) |
| 135 | + |
| 136 | + |
| 137 | + |
| 138 | +一些箭头仅适用于生成二次样条线段的连接样式。 他们是`fancy`,`simple`,`wedge`。 对于这些箭头样式,必须使用`angle3`或`arc3`连接样式。 |
| 139 | + |
| 140 | +如果提供了标注字符串,则`patchA`默认设置为文本的`bbox patch`。 |
| 141 | + |
| 142 | +[源代码](http://matplotlib.org/users/plotting/examples/annotate_simple02.py) |
| 143 | + |
| 144 | + |
| 145 | + |
| 146 | +与`text`命令一样,可以使用`bbox`参数来绘制文本周围的框。 |
| 147 | + |
| 148 | +[源代码](http://matplotlib.org/users/plotting/examples/annotate_simple03.py) |
| 149 | + |
| 150 | + |
| 151 | + |
| 152 | +默认情况下,起点设置为文本范围的中心。 可以使用`relpos`键值进行调整。 这些值根据文本的范围进行归一化。 例如,`(0,0)`表示左下角,`(1,1)`表示右上角。 |
| 153 | + |
| 154 | +[源代码](http://matplotlib.org/users/plotting/examples/annotate_simple04.py) |
| 155 | + |
| 156 | + |
| 157 | + |
| 158 | +## 将 artist 放置在轴域的锚定位置 |
| 159 | + |
| 160 | +有一类 artist 可以放置在轴域的锚定位置。 一个常见的例子是图例。 这种类型的 artist 可以使用`OffsetBox`类创建。 `mpl_toolkits.axes_grid.anchored_artists`中有几个预定义类。 |
| 161 | + |
| 162 | +```py |
| 163 | +from mpl_toolkits.axes_grid.anchored_artists import AnchoredText |
| 164 | +at = AnchoredText("Figure 1a", |
| 165 | + prop=dict(size=8), frameon=True, |
| 166 | + loc=2, |
| 167 | + ) |
| 168 | +at.patch.set_boxstyle("round,pad=0.,rounding_size=0.2") |
| 169 | +ax.add_artist(at) |
| 170 | +``` |
| 171 | + |
| 172 | +[源代码](http://matplotlib.org/users/plotting/examples/anchored_box01.py) |
| 173 | + |
| 174 | + |
| 175 | + |
| 176 | +`loc`关键字与`legend`命令中含义相同。 |
| 177 | + |
| 178 | +一个简单的应用是当 artist (或 artist 的集合)的像素大小在创建时已知。 例如,如果要绘制一个固定大小为 20 像素 ×20 像素(半径为 10 像素)的圆,则可以使用`AnchoredDrawingArea`。 实例使用绘图区域的大小创建(以像素为单位)。 用户可以在绘图区任意添加 artist。 注意,添加到绘图区域的 artist 的范围与绘制区域本身的位置无关,只和初始大小有关。 |
| 179 | + |
| 180 | +```py |
| 181 | +from mpl_toolkits.axes_grid.anchored_artists import AnchoredDrawingArea |
| 182 | + |
| 183 | +ada = AnchoredDrawingArea(20, 20, 0, 0, |
| 184 | + loc=1, pad=0., frameon=False) |
| 185 | +p1 = Circle((10, 10), 10) |
| 186 | +ada.drawing_area.add_artist(p1) |
| 187 | +p2 = Circle((30, 10), 5, fc="r") |
| 188 | +ada.drawing_area.add_artist(p2) |
| 189 | +``` |
| 190 | + |
| 191 | +添加到绘图区域的 artist 不应该具有变换集(它们将被重写),并且那些 artist 的尺寸被解释为像素坐标,即,上述示例中的圆的半径分别是 10 像素和 5 像素。 |
| 192 | + |
| 193 | +[源代码](http://matplotlib.org/users/plotting/examples/anchored_box02.py) |
| 194 | + |
| 195 | + |
| 196 | + |
| 197 | +有时,你想让你的 artist 按数据坐标(或其他坐标,而不是画布像素)缩放。 你可以使用`AnchoredAuxTransformBox`类。 这类似于`AnchoredDrawingArea`,除了 artist 的范围在绘制时由指定的变换确定。 |
| 198 | + |
| 199 | +```py |
| 200 | +from mpl_toolkits.axes_grid.anchored_artists import AnchoredAuxTransformBox |
| 201 | + |
| 202 | +box = AnchoredAuxTransformBox(ax.transData, loc=2) |
| 203 | +el = Ellipse((0,0), width=0.1, height=0.4, angle=30) # in data coordinates! |
| 204 | +box.drawing_area.add_artist(el) |
| 205 | +``` |
| 206 | + |
| 207 | +上述示例中的椭圆具有在数据坐标中对应于 0.1 和 0.4 的宽度和高度,并且当轴域的视图限制改变时将自动缩放。 |
| 208 | + |
| 209 | +[源代码](http://matplotlib.org/users/plotting/examples/anchored_box03.py) |
| 210 | + |
| 211 | + |
| 212 | + |
| 213 | +如图例所示,可以设置`bbox_to_anchor`参数。 使用`HPacker`和`VPacker`,你可以像图例中一样排列 artist(事实上,这是图例的创建方式)。 |
| 214 | + |
| 215 | +[源代码](http://matplotlib.org/users/plotting/examples/anchored_box04.py) |
| 216 | + |
| 217 | + |
| 218 | + |
| 219 | +请注意,与图例不同,默认情况下,`bbox_transform`设置为`IdentityTransform`。 |
| 220 | + |
| 221 | +## 使用复杂坐标来标注 |
| 222 | + |
| 223 | +matplotlib 中的标注支持[标注文本](http://matplotlib.org/users/annotations_intro.html#annotations-tutorial)中描述的几种类型的坐标。 对于想要更多控制的高级用户,它支持几个其他选项。 |
| 224 | + |
| 225 | +1. `Transform`实例,例如: |
| 226 | + |
| 227 | + ```py |
| 228 | + ax.annotate("Test", xy=(0.5, 0.5), xycoords=ax.transAxes) |
| 229 | + ``` |
| 230 | + |
| 231 | + 相当于: |
| 232 | + |
| 233 | + ```py |
| 234 | + ax.annotate("Test", xy=(0.5, 0.5), xycoords="axes fraction") |
| 235 | + ``` |
| 236 | + |
| 237 | + 使用它,你可以在其他轴域内标注一个点: |
| 238 | + |
| 239 | + ```py |
| 240 | + ax1, ax2 = subplot(121), subplot(122) |
| 241 | + ax2.annotate("Test", xy=(0.5, 0.5), xycoords=ax1.transData, |
| 242 | + xytext=(0.5, 0.5), textcoords=ax2.transData, |
| 243 | + arrowprops=dict(arrowstyle="->")) |
| 244 | + ``` |
| 245 | + |
| 246 | +2. `Artist`实例。`xy`值(或`xytext`)被解释为 artist 的`bbox`(`get_window_extent`的返回值)的小数坐标。 |
| 247 | + |
| 248 | + ```py |
| 249 | + an1 = ax.annotate("Test 1", xy=(0.5, 0.5), xycoords="data", |
| 250 | + va="center", ha="center", |
| 251 | + bbox=dict(boxstyle="round", fc="w")) |
| 252 | + an2 = ax.annotate("Test 2", xy=(1, 0.5), xycoords=an1, # (1,0.5) of the an1's bbox |
| 253 | + xytext=(30,0), textcoords="offset points", |
| 254 | + va="center", ha="left", |
| 255 | + bbox=dict(boxstyle="round", fc="w"), |
| 256 | + arrowprops=dict(arrowstyle="->")) |
| 257 | + ``` |
| 258 | + |
| 259 | + [源代码](http://matplotlib.org/users/plotting/examples/annotate_simple_coord01.py) |
| 260 | + |
| 261 | +  |
| 262 | + |
| 263 | + 请注意,你的责任是在绘制`an2`之前确定坐标 artist(上例中的`an1`)的范围。 在大多数情况下,这意味着`an2`需要晚于`an1`。 |
| 264 | + |
| 265 | +3. 一个返回`BboxBase`或`Transform`的实例的可调用对象。 如果返回一个变换,它与 1 相同,如果返回`bbox`,它与 2 相同。可调用对象应该接受`renderer`实例的单个参数。 例如,以下两个命令产生相同的结果: |
| 266 | + |
| 267 | + ```py |
| 268 | + an2 = ax.annotate("Test 2", xy=(1, 0.5), xycoords=an1, |
| 269 | + xytext=(30,0), textcoords="offset points") |
| 270 | + an2 = ax.annotate("Test 2", xy=(1, 0.5), xycoords=an1.get_window_extent, |
| 271 | + xytext=(30,0), textcoords="offset points") |
| 272 | + ``` |
| 273 | + |
| 274 | +4. 指定二元坐标的元组。 第一项用于`x`坐标,第二项用于`y`坐标。 例如, |
| 275 | + |
| 276 | + ```py |
| 277 | + annotate("Test", xy=(0.5, 1), xycoords=("data", "axes fraction")) |
| 278 | + ``` |
| 279 | + |
| 280 | + 0.5 的单位是数据坐标,1 的单位是归一化轴域坐标。 你可以像使用元组一样使用 artist 或转换。 例如, |
| 281 | + |
| 282 | + ```py |
| 283 | + import matplotlib.pyplot as plt |
| 284 | + |
| 285 | + plt.figure(figsize=(3,2)) |
| 286 | + ax=plt.axes([0.1, 0.1, 0.8, 0.7]) |
| 287 | + an1 = ax.annotate("Test 1", xy=(0.5, 0.5), xycoords="data", |
| 288 | + va="center", ha="center", |
| 289 | + bbox=dict(boxstyle="round", fc="w")) |
| 290 | + |
| 291 | + an2 = ax.annotate("Test 2", xy=(0.5, 1.), xycoords=an1, |
| 292 | + xytext=(0.5,1.1), textcoords=(an1, "axes fraction"), |
| 293 | + va="bottom", ha="center", |
| 294 | + bbox=dict(boxstyle="round", fc="w"), |
| 295 | + arrowprops=dict(arrowstyle="->")) |
| 296 | + plt.show() |
| 297 | + ``` |
| 298 | + |
| 299 | + [源代码](http://matplotlib.org/users/plotting/examples/annotate_simple_coord02.py) |
| 300 | + |
| 301 | +  |
| 302 | + |
| 303 | + |
0 commit comments