|
47 | 47 | # 'data' use the axes data coordinate system
|
48 | 48 | # ================== ========================================================
|
49 | 49 | #
|
50 |
| -# For example to place the text coordinates in fractional axes |
51 |
| -# coordinates, one could do:: |
| 50 | +# The following strings are also valid arguments for *textcoords* |
52 | 51 | #
|
53 |
| -# ax.annotate('local max', xy=(3, 1), xycoords='data', |
54 |
| -# xytext=(0.8, 0.95), textcoords='axes fraction', |
55 |
| -# arrowprops=dict(facecolor='black', shrink=0.05), |
56 |
| -# horizontalalignment='right', verticalalignment='top', |
57 |
| -# ) |
| 52 | +# ================== ======================================================== |
| 53 | +# argument coordinate system |
| 54 | +# ================== ======================================================== |
| 55 | +# 'offset points' offset (in points) from the xy value |
| 56 | +# 'offset pixels' offset (in pixels) from the xy value |
| 57 | +# ================== ======================================================== |
58 | 58 | #
|
59 | 59 | # For physical coordinate systems (points or pixels) the origin is the
|
60 |
| -# bottom-left of the figure or axes. |
| 60 | +# bottom-left of the figure or axes. Points are |
| 61 | +# `typographic points <https://en.wikipedia.org/wiki/Point_(typography)>`_ |
| 62 | +# meaning that they are a physical unit measuring 1/72 of an inch. Points and |
| 63 | +# pixels are discussed in further detail in :ref:`transforms-fig-scale-dpi`. |
61 | 64 | #
|
62 |
| -# Optionally, you can enable drawing of an arrow from the text to the annotated |
63 |
| -# point by giving a dictionary of arrow properties in the optional keyword |
64 |
| -# argument *arrowprops*. |
| 65 | +# .. _annotation-data: |
| 66 | +# |
| 67 | +# Annotating data |
| 68 | +# ~~~~~~~~~~~~~~~ |
| 69 | +# |
| 70 | +# For example to place the text coordinates in fractional axes |
| 71 | +# coordinates, one could do : |
| 72 | + |
| 73 | +fig, ax = plt.subplots() |
| 74 | +ax.scatter(3, 1, s=20) |
| 75 | +ax.annotate('local max', |
| 76 | + xy=(3, 1), xycoords='data', |
| 77 | + xytext=(0.8, 0.95), textcoords='axes fraction', |
| 78 | + horizontalalignment='right', verticalalignment='top') |
| 79 | + |
| 80 | +################################################################### |
| 81 | +# |
| 82 | +# .. _annotation-with-arrow: |
| 83 | +# |
| 84 | +# Annotating with arrows |
| 85 | +# ~~~~~~~~~~~~~~~~~~~~~~ |
65 | 86 | #
|
| 87 | +# You can enable drawing of an arrow from the text to the annotated point |
| 88 | +# by giving a dictionary of arrow properties in the optional keyword |
| 89 | +# argument *arrowprops*. |
66 | 90 | #
|
67 | 91 | # ==================== =====================================================
|
68 | 92 | # *arrowprops* key description
|
|
77 | 101 | # e.g., ``facecolor``
|
78 | 102 | # ==================== =====================================================
|
79 | 103 | #
|
80 |
| -# |
81 |
| -# In the example below, the *xy* point is in native coordinates |
82 |
| -# (*xycoords* defaults to 'data'). For a polar axes, this is in |
83 |
| -# (theta, radius) space. The text in this example is placed in the |
| 104 | +# In the example below, the *xy* point is in the data coordinate system |
| 105 | +# since *xycoords* defaults to 'data'. For a polar axes, this is in |
| 106 | +# (theta, radius) space. The text in this example is placed in the |
84 | 107 | # fractional figure coordinate system. :class:`matplotlib.text.Text`
|
85 | 108 | # keyword arguments like *horizontalalignment*, *verticalalignment* and
|
86 | 109 | # *fontsize* are passed from `~matplotlib.axes.Axes.annotate` to the
|
|
94 | 117 | # annotations, including fancy arrows, see :ref:`plotting-guide-annotation`
|
95 | 118 | # and :doc:`/gallery/text_labels_and_annotations/annotation_demo`.
|
96 | 119 | #
|
| 120 | +# .. _annotations-offset-text: |
97 | 121 | #
|
98 |
| -# Do not proceed unless you have already read :ref:`annotations-tutorial`, |
99 |
| -# :func:`~matplotlib.pyplot.text` and :func:`~matplotlib.pyplot.annotate`! |
100 |
| -# |
| 122 | +# Placing text annotations relative to data |
| 123 | +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 124 | +# Annotations can be positioned at a relative offset to the *xy* input to |
| 125 | +# annotation by setting the *textcoords* keyword argument to 'offset points' or |
| 126 | +# 'offset pixels'. |
| 127 | + |
| 128 | +fig, ax = plt.subplots() |
| 129 | +x = [1, 3, 5, 7, 9] |
| 130 | +y = [2, 4, 6, 8, 10] |
| 131 | +annotations = ["A", "B", "C", "D", "E"] |
| 132 | +ax.scatter(x, y, s=20) |
| 133 | + |
| 134 | +for xi, yi, text in zip(x, y, annotations): |
| 135 | + ax.annotate(text, |
| 136 | + xy=(xi, yi), xycoords='data', |
| 137 | + xytext=(1.5, 1.5), textcoords='offset points') |
| 138 | + |
| 139 | +############################################################################### |
| 140 | +# The annotations are offset 1.5 points (1.5*1/72 inches) from the *xy* values. |
101 | 141 | #
|
102 | 142 | # .. _plotting-guide-annotation:
|
103 | 143 | #
|
104 |
| -# Advanced Annotations |
105 |
| -# -------------------- |
| 144 | +# Advanced annotation |
| 145 | +# ------------------- |
106 | 146 | #
|
107 |
| -# Annotating with Text with Box |
108 |
| -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 147 | +# We recommend reading :ref:`annotations-tutorial`, :func:`~matplotlib.pyplot.text` |
| 148 | +# and :func:`~matplotlib.pyplot.annotate` before reading this section. |
| 149 | +# |
| 150 | +# Annotating with boxed text |
| 151 | +# ~~~~~~~~~~~~~~~~~~~~~~~~~~ |
109 | 152 | #
|
110 | 153 | # Let's start with a simple example.
|
111 | 154 | #
|
|
116 | 159 | # `~.Axes.text` takes a *bbox* keyword argument, which draws a box around the
|
117 | 160 | # text::
|
118 | 161 | #
|
119 |
| -# t = ax.text( |
120 |
| -# 0, 0, "Direction", ha="center", va="center", rotation=45, size=15, |
121 |
| -# bbox=dict(boxstyle="rarrow,pad=0.3", fc="cyan", ec="b", lw=2)) |
| 162 | +# t = ax.text(0, 0, "Direction", |
| 163 | +# ha="center", va="center", rotation=45, size=15, |
| 164 | +# bbox=dict(boxstyle="rarrow,pad=0.3", fc="cyan", ec="b", lw=2)) |
122 | 165 | #
|
123 | 166 | # The patch object associated with the text can be accessed by::
|
124 | 167 | #
|
|
155 | 198 | # name with separating comma (this form can be used as "boxstyle" value
|
156 | 199 | # of bbox argument when initializing the text instance) ::
|
157 | 200 | #
|
158 |
| -# bb.set_boxstyle("rarrow,pad=0.6") |
| 201 | +# bb.set_boxstyle("rarrow, pad=0.6") |
159 | 202 | #
|
160 |
| -# Annotating with Arrow |
161 |
| -# ~~~~~~~~~~~~~~~~~~~~~ |
| 203 | +# Customizing annotation arrows |
| 204 | +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
162 | 205 | #
|
163 | 206 | # `~.Axes.annotate` draws an arrow connecting two points in an Axes::
|
164 | 207 | #
|
165 | 208 | # ax.annotate("Annotation",
|
166 | 209 | # xy=(x1, y1), xycoords='data',
|
167 |
| -# xytext=(x2, y2), textcoords='offset points', |
168 |
| -# ) |
| 210 | +# xytext=(x2, y2), textcoords='offset points') |
169 | 211 | #
|
170 | 212 | # This annotates a point at *xy* in the given coordinate (*xycoords*)
|
171 | 213 | # with the text at *xytext* given in *textcoords*. Often, the
|
|
180 | 222 | # ax.annotate("",
|
181 | 223 | # xy=(0.2, 0.2), xycoords='data',
|
182 | 224 | # xytext=(0.8, 0.8), textcoords='data',
|
183 |
| -# arrowprops=dict(arrowstyle="->", |
184 |
| -# connectionstyle="arc3"), |
185 |
| -# ) |
| 225 | +# arrowprops=dict(arrowstyle="->", connectionstyle="arc3")) |
186 | 226 | #
|
187 | 227 | # .. figure:: ../../gallery/userdemo/images/sphx_glr_annotate_simple01_001.png
|
188 | 228 | # :target: ../../gallery/userdemo/annotate_simple01.html
|
|
292 | 332 | from matplotlib.offsetbox import AnchoredText
|
293 | 333 |
|
294 | 334 | fig, ax = plt.subplots()
|
295 |
| -at = AnchoredText( |
296 |
| - "Figure 1a", prop=dict(size=15), frameon=True, loc='upper left') |
| 335 | +at = AnchoredText("Figure 1a", |
| 336 | + prop=dict(size=15), frameon=True, loc='upper left') |
297 | 337 | at.patch.set_boxstyle("round,pad=0.,rounding_size=0.2")
|
298 | 338 | ax.add_artist(at)
|
299 | 339 |
|
|
348 | 388 | ax.add_artist(box)
|
349 | 389 |
|
350 | 390 | ###############################################################################
|
351 |
| -# As in the legend, the bbox_to_anchor argument can be set. Using the |
352 |
| -# HPacker and VPacker, you can have an arrangement(?) of artist as in the |
353 |
| -# legend (as a matter of fact, this is how the legend is created). |
| 391 | +# Another method of anchoring an artist relative to a parent axes or anchor |
| 392 | +# point is via the *bbox_to_anchor* argument of `.AnchoredOffsetbox`. This |
| 393 | +# artist can then be automatically positioned relative to another artist using |
| 394 | +# `.HPacker` and `.VPacker`. :: |
| 395 | +# |
| 396 | +# from matplotlib.offsetbox import (AnchoredOffsetbox, DrawingArea, HPacker, |
| 397 | +# TextArea) |
| 398 | +# |
| 399 | +# box1 = TextArea(" Test: ", textprops=dict(color="k")) |
| 400 | +# box2 = DrawingArea(60, 20, 0, 0) |
| 401 | +# # see gallery example for ellipse drawing code |
| 402 | +# box = HPacker(children=[box1, box2], align="center", pad=0, sep=5) |
| 403 | +# anchored_box = AnchoredOffsetbox(loc='lower left', child=box, pad=0., |
| 404 | +# frameon=True, borderpad=0., |
| 405 | +# bbox_to_anchor=(0., 1.02), |
| 406 | +# bbox_transform=ax.transAxes) |
354 | 407 | #
|
355 | 408 | # .. figure:: ../../gallery/userdemo/images/sphx_glr_anchored_box04_001.png
|
356 | 409 | # :target: ../../gallery/userdemo/anchored_box04.html
|
357 | 410 | # :align: center
|
358 | 411 | #
|
359 |
| -# Note that unlike the legend, the ``bbox_transform`` is set |
360 |
| -# to IdentityTransform by default. |
| 412 | +# Note that, unlike in `.Legend`, the ``bbox_transform`` is set to |
| 413 | +# IdentityTransform by default. The full example can be found at |
| 414 | +# :doc:`/gallery/userdemo/anchored_box04`. |
361 | 415 | #
|
362 |
| -# Coordinate systems for Annotations |
363 |
| -# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 416 | +# Defining custom box styles |
| 417 | +# ~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 418 | +# |
| 419 | +# You can use a custom box style. The value for the ``boxstyle`` can be a |
| 420 | +# callable object in the following forms. :: |
| 421 | +# |
| 422 | +# def __call__(self, x0, y0, width, height, mutation_size, |
| 423 | +# aspect_ratio=1.): |
| 424 | +# ''' |
| 425 | +# Given the location and size of the box, return the path of |
| 426 | +# the box around it. |
| 427 | +# |
| 428 | +# - *x0*, *y0*, *width*, *height* : location and size of the box |
| 429 | +# - *mutation_size* : a reference scale for the mutation. |
| 430 | +# - *aspect_ratio* : aspect-ratio for the mutation. |
| 431 | +# ''' |
| 432 | +# path = ... |
| 433 | +# return path |
| 434 | +# |
| 435 | +# Here is a complete example. |
| 436 | +# |
| 437 | +# .. figure:: ../../gallery/userdemo/images/sphx_glr_custom_boxstyle01_001.png |
| 438 | +# :target: ../../gallery/userdemo/custom_boxstyle01.html |
| 439 | +# :align: center |
| 440 | +# |
| 441 | +# Similarly, you can define a custom `.ConnectionStyle` and a custom |
| 442 | +# `.ArrowStyle`. View the source code at `.patches` to learn how each class |
| 443 | +# is defined. |
| 444 | +# |
| 445 | +# .. _annotating_coordinate_systems: |
| 446 | +# |
| 447 | +# Coordinate systems for annotations |
| 448 | +# ---------------------------------- |
364 | 449 | #
|
365 | 450 | # Matplotlib Annotations support several types of coordinates. Some are
|
366 | 451 | # described in :ref:`annotations-tutorial`; more advanced options are
|
|
376 | 461 | # This allows annotating a point in another axes::
|
377 | 462 | #
|
378 | 463 | # fig, (ax1, ax2) = plt.subplots(1, 2)
|
379 |
| -# ax2.annotate("Test", xy=(0.5, 0.5), xycoords=ax1.transData, |
| 464 | +# ax2.annotate("Test", |
| 465 | +# xy=(0.5, 0.5), xycoords=ax1.transData, |
380 | 466 | # xytext=(0.5, 0.5), textcoords=ax2.transData,
|
381 | 467 | # arrowprops=dict(arrowstyle="->"))
|
382 | 468 | #
|
383 | 469 | # 2. An `.Artist` instance. The *xy* value (or *xytext*) is interpreted as a
|
384 | 470 | # fractional coordinate of the bbox (return value of *get_window_extent*) of
|
385 |
| -# the artist:: |
| 471 | +# the artist: :: |
386 | 472 | #
|
387 |
| -# an1 = ax.annotate("Test 1", xy=(0.5, 0.5), xycoords="data", |
| 473 | +# an1 = ax.annotate("Test 1", |
| 474 | +# xy=(0.5, 0.5), xycoords="data", |
388 | 475 | # va="center", ha="center",
|
389 | 476 | # bbox=dict(boxstyle="round", fc="w"))
|
390 |
| -# an2 = ax.annotate("Test 2", xy=(1, 0.5), xycoords=an1, # (1, 0.5) of the an1's bbox |
| 477 | +# |
| 478 | +# an2 = ax.annotate("Test 2", |
| 479 | +# xy=(1, 0.5), xycoords=an1, # (1, 0.5) of the an1's bbox |
391 | 480 | # xytext=(30, 0), textcoords="offset points",
|
392 | 481 | # va="center", ha="left",
|
393 | 482 | # bbox=dict(boxstyle="round", fc="w"),
|
|
405 | 494 | # returns either a `.Transform` or a `.BboxBase`. The return value is then
|
406 | 495 | # handled as in (1), for transforms, or in (2), for bboxes. For example, ::
|
407 | 496 | #
|
408 |
| -# an2 = ax.annotate("Test 2", xy=(1, 0.5), xycoords=an1, |
| 497 | +# an2 = ax.annotate("Test 2", |
| 498 | +# xy=(1, 0.5), xycoords=an1, |
409 | 499 | # xytext=(30, 0), textcoords="offset points")
|
410 | 500 | #
|
411 | 501 | # is identical to::
|
412 | 502 | #
|
413 |
| -# an2 = ax.annotate("Test 2", xy=(1, 0.5), xycoords=an1.get_window_extent, |
| 503 | +# an2 = ax.annotate("Test 2", |
| 504 | +# xy=(1, 0.5), xycoords=an1.get_window_extent, |
414 | 505 | # xytext=(30, 0), textcoords="offset points")
|
415 | 506 | #
|
416 | 507 | # 4. A pair of coordinate specifications -- the first for the x-coordinate, and
|
|
434 | 525 | # :target: ../../gallery/userdemo/annotate_simple_coord03.html
|
435 | 526 | # :align: center
|
436 | 527 | #
|
437 |
| -# You may take a look at this example |
| 528 | +# This example can be found at |
438 | 529 | # :doc:`/gallery/text_labels_and_annotations/annotation_demo`.
|
439 | 530 | #
|
440 | 531 | # Using ConnectionPatch
|
441 | 532 | # ~~~~~~~~~~~~~~~~~~~~~
|
442 | 533 | #
|
443 | 534 | # ConnectionPatch is like an annotation without text. While `~.Axes.annotate`
|
444 |
| -# is sufficient in most situations, ConnectionPatch is useful when you want to |
| 535 | +# is sufficient in most situations, `.ConnectionPatch` is useful when you want to |
445 | 536 | # connect points in different axes. ::
|
446 | 537 | #
|
447 | 538 | # from matplotlib.patches import ConnectionPatch
|
448 |
| -# xy = (0.2, 0.2) |
| 539 | +# xy = (0.3, 0.2) |
449 | 540 | # con = ConnectionPatch(xyA=xy, coordsA=ax1.transData,
|
450 | 541 | # xyB=xy, coordsB=ax2.transData)
|
451 | 542 | # fig.add_artist(con)
|
|
462 | 553 | # and is also necessary if using :doc:`constrained_layout
|
463 | 554 | # </tutorials/intermediate/constrainedlayout_guide>` for positioning the axes.
|
464 | 555 | #
|
465 |
| -# Advanced Topics |
466 |
| -# --------------- |
467 |
| -# |
468 | 556 | # Zoom effect between Axes
|
469 | 557 | # ~~~~~~~~~~~~~~~~~~~~~~~~
|
470 | 558 | #
|
|
475 | 563 | # .. figure:: ../../gallery/subplots_axes_and_figures/images/sphx_glr_axes_zoom_effect_001.png
|
476 | 564 | # :target: ../../gallery/subplots_axes_and_figures/axes_zoom_effect.html
|
477 | 565 | # :align: center
|
478 |
| -# |
479 |
| -# Define Custom BoxStyle |
480 |
| -# ~~~~~~~~~~~~~~~~~~~~~~ |
481 |
| -# |
482 |
| -# You can use a custom box style. The value for the ``boxstyle`` can be a |
483 |
| -# callable object in the following forms.:: |
484 |
| -# |
485 |
| -# def __call__(self, x0, y0, width, height, mutation_size, |
486 |
| -# aspect_ratio=1.): |
487 |
| -# ''' |
488 |
| -# Given the location and size of the box, return the path of |
489 |
| -# the box around it. |
490 |
| -# |
491 |
| -# - *x0*, *y0*, *width*, *height* : location and size of the box |
492 |
| -# - *mutation_size* : a reference scale for the mutation. |
493 |
| -# - *aspect_ratio* : aspect-ratio for the mutation. |
494 |
| -# ''' |
495 |
| -# path = ... |
496 |
| -# return path |
497 |
| -# |
498 |
| -# Here is a complete example. |
499 |
| -# |
500 |
| -# .. figure:: ../../gallery/userdemo/images/sphx_glr_custom_boxstyle01_001.png |
501 |
| -# :target: ../../gallery/userdemo/custom_boxstyle01.html |
502 |
| -# :align: center |
503 |
| -# |
504 |
| -# Similarly, you can define a custom ConnectionStyle and a custom ArrowStyle. |
505 |
| -# See the source code of ``lib/matplotlib/patches.py`` and check |
506 |
| -# how each style class is defined. |
|
0 commit comments