|
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