|
5 | 5 |
|
6 | 6 | Like any graphics packages, Matplotlib is built on top of a
|
7 | 7 | transformation framework to easily move between coordinate systems,
|
8 |
| -the userland `data` coordinate system, the `axes` coordinate system, |
9 |
| -the `figure` coordinate system, and the `display` coordinate system. |
| 8 | +the userland *data* coordinate system, the *axes* coordinate system, |
| 9 | +the *figure* coordinate system, and the *display* coordinate system. |
10 | 10 | In 95% of your plotting, you won't need to think about this, as it
|
11 | 11 | happens under the hood, but as you push the limits of custom figure
|
12 | 12 | generation, it helps to have an understanding of these objects so you
|
13 | 13 | can reuse the existing transformations Matplotlib makes available to
|
14 | 14 | you, or create your own (see :mod:`matplotlib.transforms`). The table
|
15 | 15 | below summarizes the some useful coordinate systems, the transformation
|
16 | 16 | object you should use to work in that coordinate system, and the
|
17 |
| -description of that system. In the `Transformation Object` column, |
| 17 | +description of that system. In the ``Transformation Object`` column, |
18 | 18 | ``ax`` is a :class:`~matplotlib.axes.Axes` instance, and ``fig`` is a
|
19 | 19 | :class:`~matplotlib.figure.Figure` instance.
|
20 | 20 |
|
|
52 | 52 | +----------------+-----------------------------+-----------------------------------+
|
53 | 53 |
|
54 | 54 | All of the transformation objects in the table above take inputs in
|
55 |
| -their coordinate system, and transform the input to the ``display`` |
56 |
| -coordinate system. That is why the ``display`` coordinate system has |
| 55 | +their coordinate system, and transform the input to the *display* |
| 56 | +coordinate system. That is why the *display* coordinate system has |
57 | 57 | ``None`` for the ``Transformation Object`` column -- it already is in
|
58 |
| -display coordinates. The transformations also know how to invert |
59 |
| -themselves, to go from ``display`` back to the native coordinate system. |
| 58 | +*display* coordinates. The transformations also know how to invert |
| 59 | +themselves, to go from *display* back to the native coordinate system. |
60 | 60 | This is particularly useful when processing events from the user
|
61 | 61 | interface, which typically occur in display space, and you want to
|
62 |
| -know where the mouse click or key-press occurred in your data |
| 62 | +know where the mouse click or key-press occurred in your *data* |
63 | 63 | coordinate system.
|
64 | 64 |
|
65 |
| -Note that specifying objects in ``display`` coordinates will change their |
| 65 | +Note that specifying objects in *display* coordinates will change their |
66 | 66 | location if the ``dpi`` of the figure changes. This can cause confusion when
|
67 | 67 | printing or changing screen resolution, because the object can change location
|
68 | 68 | and size. Therefore it is most common
|
69 | 69 | for artists placed in an axes or figure to have their transform set to
|
70 | 70 | something *other* than the `~.transforms.IdentityTransform()`; the default when
|
71 |
| -an artist is placed on an axes using `~.Axes.axes.add_artist` is for the |
| 71 | +an artist is placed on an axes using `~.axes.Axes.add_artist` is for the |
72 | 72 | transform to be ``ax.transData``.
|
73 | 73 |
|
74 | 74 | .. _data-coords:
|
75 | 75 |
|
76 | 76 | Data coordinates
|
77 | 77 | ================
|
78 | 78 |
|
79 |
| -Let's start with the most commonly used coordinate, the `data` |
80 |
| -coordinate system. Whenever you add data to the axes, Matplotlib |
81 |
| -updates the datalimits, most commonly updated with the |
82 |
| -:meth:`~matplotlib.axes.Axes.set_xlim` and |
83 |
| -:meth:`~matplotlib.axes.Axes.set_ylim` methods. For example, in the |
84 |
| -figure below, the data limits stretch from 0 to 10 on the x-axis, and |
85 |
| --1 to 1 on the y-axis. |
| 79 | +Let's start with the most commonly used coordinate, the *data* coordinate |
| 80 | +system. Whenever you add data to the axes, Matplotlib updates the datalimits, |
| 81 | +most commonly updated with the :meth:`~matplotlib.axes.Axes.set_xlim` and |
| 82 | +:meth:`~matplotlib.axes.Axes.set_ylim` methods. For example, in the figure |
| 83 | +below, the data limits stretch from 0 to 10 on the x-axis, and -1 to 1 on the |
| 84 | +y-axis. |
86 | 85 | """
|
87 | 86 |
|
88 | 87 | import numpy as np
|
|
101 | 100 |
|
102 | 101 | ###############################################################################
|
103 | 102 | # You can use the ``ax.transData`` instance to transform from your
|
104 |
| -# `data` to your `display` coordinate system, either a single point or a |
| 103 | +# *data* to your *display* coordinate system, either a single point or a |
105 | 104 | # sequence of points as shown below:
|
106 | 105 | #
|
107 | 106 | # .. sourcecode:: ipython
|
|
118 | 117 | # [ 132.435, 642.2 ]])
|
119 | 118 | #
|
120 | 119 | # You can use the :meth:`~matplotlib.transforms.Transform.inverted`
|
121 |
| -# method to create a transform which will take you from display to data |
| 120 | +# method to create a transform which will take you from *display* to *data* |
122 | 121 | # coordinates:
|
123 | 122 | #
|
124 | 123 | # .. sourcecode:: ipython
|
|
132 | 131 | # Out[43]: array([ 5., 0.])
|
133 | 132 | #
|
134 | 133 | # If your are typing along with this tutorial, the exact values of the
|
135 |
| -# display coordinates may differ if you have a different window size or |
| 134 | +# *display* coordinates may differ if you have a different window size or |
136 | 135 | # dpi setting. Likewise, in the figure below, the display labeled
|
137 | 136 | # points are probably not the same as in the ipython session because the
|
138 | 137 | # documentation figure size defaults are different.
|
|
170 | 169 | # .. note::
|
171 | 170 | #
|
172 | 171 | # If you run the source code in the example above in a GUI backend,
|
173 |
| -# you may also find that the two arrows for the `data` and `display` |
| 172 | +# you may also find that the two arrows for the *data* and *display* |
174 | 173 | # annotations do not point to exactly the same point. This is because
|
175 | 174 | # the display point was computed before the figure was displayed, and
|
176 | 175 | # the GUI backend may slightly resize the figure when it is created.
|
177 | 176 | # The effect is more pronounced if you resize the figure yourself.
|
178 |
| -# This is one good reason why you rarely want to work in display |
| 177 | +# This is one good reason why you rarely want to work in *display* |
179 | 178 | # space, but you can connect to the ``'on_draw'``
|
180 |
| -# :class:`~matplotlib.backend_bases.Event` to update figure |
| 179 | +# :class:`~matplotlib.backend_bases.Event` to update *figure* |
181 | 180 | # coordinates on figure draws; see :ref:`event-handling-tutorial`.
|
182 | 181 | #
|
183 | 182 | # When you change the x or y limits of your axes, the data limits are
|
|
210 | 209 | # Axes coordinates
|
211 | 210 | # ================
|
212 | 211 | #
|
213 |
| -# After the `data` coordinate system, `axes` is probably the second most |
| 212 | +# After the *data* coordinate system, *axes* is probably the second most |
214 | 213 | # useful coordinate system. Here the point (0, 0) is the bottom left of
|
215 | 214 | # your axes or subplot, (0.5, 0.5) is the center, and (1.0, 1.0) is the
|
216 | 215 | # top right. You can also refer to points outside the range, so (-0.1,
|
|
230 | 229 | plt.show()
|
231 | 230 |
|
232 | 231 | ###############################################################################
|
233 |
| -# You can also make lines or patches in the axes coordinate system, but |
| 232 | +# You can also make lines or patches in the *axes* coordinate system, but |
234 | 233 | # this is less useful in my experience than using ``ax.transAxes`` for
|
235 | 234 | # placing text. Nonetheless, here is a silly example which plots some
|
236 |
| -# random dots in `data` space, and overlays a semi-transparent |
| 235 | +# random dots in data space, and overlays a semi-transparent |
237 | 236 | # :class:`~matplotlib.patches.Circle` centered in the middle of the axes
|
238 | 237 | # with a radius one quarter of the axes -- if your axes does not
|
239 | 238 | # preserve aspect ratio (see :meth:`~matplotlib.axes.Axes.set_aspect`),
|
240 | 239 | # this will look like an ellipse. Use the pan/zoom tool to move around,
|
241 | 240 | # or manually change the data xlim and ylim, and you will see the data
|
242 |
| -# move, but the circle will remain fixed because it is not in `data` |
| 241 | +# move, but the circle will remain fixed because it is not in *data* |
243 | 242 | # coordinates and will always remain at the center of the axes.
|
244 | 243 |
|
245 | 244 | fig, ax = plt.subplots()
|
|
257 | 256 | # Blended transformations
|
258 | 257 | # =======================
|
259 | 258 | #
|
260 |
| -# Drawing in `blended` coordinate spaces which mix `axes` with `data` |
| 259 | +# Drawing in *blended* coordinate spaces which mix *axes* with *data* |
261 | 260 | # coordinates is extremely useful, for example to create a horizontal
|
262 | 261 | # span which highlights some region of the y-data but spans across the
|
263 | 262 | # x-axis regardless of the data limits, pan or zoom level, etc. In fact
|
|
300 | 299 | ###############################################################################
|
301 | 300 | # .. note::
|
302 | 301 | #
|
303 |
| -# The blended transformations where x is in data coords and y in axes |
| 302 | +# The blended transformations where x is in *data* coords and y in *axes* |
304 | 303 | # coordinates is so useful that we have helper methods to return the
|
305 | 304 | # versions Matplotlib uses internally for drawing ticks, ticklabels, etc.
|
306 | 305 | # The methods are :meth:`matplotlib.axes.Axes.get_xaxis_transform` and
|
|
357 | 356 | #
|
358 | 357 | # trans = ScaledTranslation(xt, yt, scale_trans)
|
359 | 358 | #
|
360 |
| -# where `xt` and `yt` are the translation offsets, and `scale_trans` is |
361 |
| -# a transformation which scales `xt` and `yt` at transformation time |
| 359 | +# where *xt* and *yt* are the translation offsets, and *scale_trans* is |
| 360 | +# a transformation which scales *xt* and *yt* at transformation time |
362 | 361 | # before applying the offsets.
|
363 | 362 | #
|
364 | 363 | # Note the use of the plus operator on the transforms below.
|
365 | 364 | # This code says: first apply the scale transformation ``fig.dpi_scale_trans``
|
366 | 365 | # to make the ellipse the proper size, but still centered at (0, 0),
|
367 |
| -# and then translate the data to `xdata[0]` and `ydata[0]` in data space. |
| 366 | +# and then translate the data to ``xdata[0]`` and ``ydata[0]`` in data space. |
368 | 367 | #
|
369 | 368 | # In interactive use, the ellipse stays the same size even if the
|
370 | 369 | # axes limits are changed via zoom.
|
|
392 | 391 | # in data space to the correct spot.
|
393 | 392 | # If we had done the ``ScaledTranslation`` first, then
|
394 | 393 | # ``xdata[0]`` and ``ydata[0]`` would
|
395 |
| -# first be transformed to ``display`` coordinates (``[ 358.4 475.2]`` on |
| 394 | +# first be transformed to *display* coordinates (``[ 358.4 475.2]`` on |
396 | 395 | # a 200-dpi monitor) and then those coordinates
|
397 | 396 | # would be scaled by ``fig.dpi_scale_trans`` pushing the center of
|
398 | 397 | # the ellipse well off the screen (i.e. ``[ 71680. 95040.]``).
|
|
406 | 405 | # a new transformation that is
|
407 | 406 | # offset from another transformation, e.g., to place one object shifted a
|
408 | 407 | # bit relative to another object. Typically you want the shift to be in
|
409 |
| -# some physical dimension, like points or inches rather than in data |
| 408 | +# some physical dimension, like points or inches rather than in *data* |
410 | 409 | # coordinates, so that the shift effect is constant at different zoom
|
411 | 410 | # levels and dpi settings.
|
412 | 411 | #
|
|
418 | 417 | # Here we apply the transforms in the *opposite* order to the use of
|
419 | 418 | # :class:`~matplotlib.transforms.ScaledTranslation` above. The plot is
|
420 | 419 | # first made in data units (``ax.transData``) and then shifted by
|
421 |
| -# ``dx`` and ``dy`` points using `fig.dpi_scale_trans`. (In typography, |
422 |
| -# a`point <https://en.wikipedia.org/wiki/Point_%28typography%29>`_ is |
| 420 | +# ``dx`` and ``dy`` points using ``fig.dpi_scale_trans``. (In typography, |
| 421 | +# a `point <https://en.wikipedia.org/wiki/Point_%28typography%29>`_ is |
423 | 422 | # 1/72 inches, and by specifying your offsets in points, your figure
|
424 | 423 | # will look the same regardless of the dpi resolution it is saved in.)
|
425 | 424 |
|
|
464 | 463 | #
|
465 | 464 | # The ``ax.transData`` transform we have been working with in this
|
466 | 465 | # tutorial is a composite of three different transformations that
|
467 |
| -# comprise the transformation pipeline from `data` -> `display` |
| 466 | +# comprise the transformation pipeline from *data* -> *display* |
468 | 467 | # coordinates. Michael Droettboom implemented the transformations
|
469 | 468 | # framework, taking care to provide a clean API that segregated the
|
470 | 469 | # nonlinear projections and scales that happen in polar and logarithmic
|
|
485 | 484 | #
|
486 | 485 | # We've been introduced to the ``transAxes`` instance above in
|
487 | 486 | # :ref:`axes-coords`, which maps the (0, 0), (1, 1) corners of the
|
488 |
| -# axes or subplot bounding box to `display` space, so let's look at |
| 487 | +# axes or subplot bounding box to *display* space, so let's look at |
489 | 488 | # these other two pieces.
|
490 | 489 | #
|
491 | 490 | # ``self.transLimits`` is the transformation that takes you from
|
492 |
| -# ``data`` to ``axes`` coordinates; i.e., it maps your view xlim and ylim |
| 491 | +# *data* to *axes* coordinates; i.e., it maps your view xlim and ylim |
493 | 492 | # to the unit space of the axes (and ``transAxes`` then takes that unit
|
494 | 493 | # space to display space). We can see this in action here
|
495 | 494 | #
|
|
516 | 515 | # Out[87]: array([ 0.5, 0.5])
|
517 | 516 | #
|
518 | 517 | # and we can use this same inverted transformation to go from the unit
|
519 |
| -# `axes` coordinates back to `data` coordinates. |
| 518 | +# *axes* coordinates back to *data* coordinates. |
520 | 519 | #
|
521 | 520 | # .. sourcecode:: ipython
|
522 | 521 | #
|
|
0 commit comments