14
14
**data coordinates**, the *origin* kwarg controls how the image fills
15
15
that bounding box, and the orientation in the final rendered image is
16
16
also affected by the axes limits.
17
+
18
+ .. hint:: For the moment, you may want to skip the code details below and
19
+ directly continue with the discussion of the results.
17
20
"""
18
21
import numpy as np
19
22
import matplotlib .pyplot as plt
@@ -80,7 +83,7 @@ def set_extent_None_text(ax):
80
83
ha = 'center' , va = 'center' , color = 'w' )
81
84
82
85
83
- def generate_imshow_demo_grid (extents , auto_limits ):
86
+ def generate_imshow_demo_grid (extents , xlim = None , ylim = None ):
84
87
N = len (extents )
85
88
fig = plt .figure (tight_layout = True )
86
89
fig .set_size_inches (6 , N * (11.25 ) / 5 )
@@ -98,12 +101,12 @@ def generate_imshow_demo_grid(extents, auto_limits):
98
101
im = ax .imshow (d , origin = origin , extent = extent )
99
102
left , right , bottom , top = im .get_extent ()
100
103
101
- if auto_limits or top > bottom :
104
+ if xlim is None or top > bottom :
102
105
upper_string , lower_string = 'top' , 'bottom'
103
106
else :
104
107
upper_string , lower_string = 'bottom' , 'top'
105
108
106
- if auto_limits or left < right :
109
+ if ylim is None or left < right :
107
110
port_string , starboard_string = 'left' , 'right'
108
111
inverted_xindex = False
109
112
else :
@@ -135,9 +138,10 @@ def generate_imshow_demo_grid(extents, auto_limits):
135
138
ax .text (tx , ty , index , color = 'white' , ha = halign , va = 'center' ,
136
139
bbox = {'boxstyle' : 'square' , 'facecolor' : facecolor })
137
140
138
- if not auto_limits :
139
- ax .set_xlim (- 1 , 7 )
140
- ax .set_ylim (- 1 , 6 )
141
+ if xlim :
142
+ ax .set_xlim (* xlim )
143
+ if ylim :
144
+ ax .set_ylim (* ylim )
141
145
142
146
for ax , extent in zip (columns ['label' ], extents ):
143
147
text_kwargs = {'ha' : 'right' ,
@@ -158,71 +162,92 @@ def generate_imshow_demo_grid(extents, auto_limits):
158
162
return columns
159
163
160
164
161
- extents = (None ,
162
- (- 0.5 , 6.5 , - 0.5 , 5.5 ),
163
- (- 0.5 , 6.5 , 5.5 , - 0.5 ),
164
- (6.5 , - 0.5 , - 0.5 , 5.5 ),
165
- (6.5 , - 0.5 , 5.5 , - 0.5 ))
166
165
166
+ ###############################################################################
167
+ #
168
+ # Default extent
169
+ # --------------
170
+ #
171
+ # First, let's have a look at the default `extent=None`
167
172
173
+ generate_imshow_demo_grid (extents = [None ])
168
174
169
175
###############################################################################
170
176
#
177
+ # Generally, for an array of shape (N, M), the first index runs along the
178
+ # vertical, the second index runs along the horizontal.
179
+ # The pixel centers are at integer positions ranging from 0 to `N' = N - 1``
180
+ # vertically and from 0 to ``M' = M - 1`` horizontally.
181
+ # *origin* determines how to the data is filled in the bounding box.
171
182
#
172
- # First, using *extent* we pick a bounding box in dataspace that the
173
- # image will fill and then interpolate/resample the underlying data to
174
- # fill that box.
183
+ # For ``origin='lower'``:
175
184
#
176
- # - If ``origin='lower'`` than the ``[0, 0]`` entry is closest to the
177
- # ``(left, bottom)`` corner of the bounding box and moving closer to
178
- # ``(left, top)`` moves along the ``[:, 0]`` axis of the array to
179
- # higher indexed rows and moving towards ``(right, bottom)`` moves you
180
- # along the ``[0, :]`` axis of the array to higher indexed columns
185
+ # - [0, 0] is at (left, bottom)
186
+ # - [N', 0] is at (left, top)
187
+ # - [0, M'] is at (right, bottom)
188
+ # - [N', M'] is at (right, top)
181
189
#
182
- # - If ``origin='upper'`` then the ``[-1, 0]`` entry is closest to the
183
- # ``(left, bottom)`` corner of the bounding box and moving towards
184
- # ``(left, top)`` moves along the ``[:, 0]`` axis of the array to
185
- # lower index rows and moving towards ``(right, bottom)`` moves you
186
- # along the ``[-1, :]`` axis of the array to higher indexed columns
187
-
188
- generate_imshow_demo_grid (extents [:1 ], auto_limits = True )
189
-
190
- ###############################################################################
190
+ # ``origin='upper'`` reverses the vertical axes direction and filling:
191
+ #
192
+ # - [0, 0] is at (left, top)
193
+ # - [N', 0] is at (left, bottom)
194
+ # - [0, M'] is at (right, top)
195
+ # - [N', M'] is at (right, bottom)
191
196
#
192
- # If we only specify *origin* we can see why it is so named. For
193
- # ``origin='upper'`` the ``[0, 0]`` pixel is on the upper left and for
194
- # ``origin='lower'`` the ``[0, 0]`` pixel is in the lower left [#]_.
195
- # The gray arrows are attached to the ``(left, bottom)`` corner of the
196
- # image. There are two tricky things going on here: first the default
197
- # value of *extent* depends on the value of *origin* and second the x
198
- # and y limits are adjusted to match the extent. The default *extent*
199
- # is ``(-0.5, numcols-0.5, numrows-0.5, -0.5)`` when ``origin ==
200
- # 'upper'`` and ``(-0.5, numcols-0.5, -0.5, numrows-0.5)`` when ``origin
201
- # == 'lower'`` which puts the pixel centers on integer positions and the
202
- # ``[0, 0]`` pixel at ``(0, 0)`` in dataspace.
197
+ # In summary, the position of the [0, 0] index as well as the extent are
198
+ # influenced by *origin*:
203
199
#
200
+ # ====== =============== ==========================================
201
+ # origin [0, 0] position extent
202
+ # ====== =============== ==========================================
203
+ # upper top left ``(-0.5, numcols-0.5, numrows-0.5, -0.5)``
204
+ # lower bottom left ``(-0.5, numcols-0.5, -0.5, numrows-0.5)``
205
+ # ====== =============== ==========================================
204
206
#
205
- # .. [#] The default value of *origin* is set by :rc:`image.origin`
206
- # which defaults to ``'upper'`` to match the matrix indexing
207
- # conventions in math and computer graphics image indexing
208
- # conventions.
207
+ # The default value of *origin* is set by :rc:`image.origin` which defaults
208
+ # to ``'upper'`` to match the matrix indexing conventions in math and
209
+ # computer graphics image indexing conventions.
210
+ #
211
+ #
212
+ # Explicit extent
213
+ # ---------------
214
+ #
215
+ # By setting *extent* we pick a bounding box in dataspace that the image will
216
+ # fill. Then, the underlying data is interpolated/resampled to fill that box.
209
217
#
210
218
# If the axes is set to autoscale, then view limits of the axes are set
211
219
# to match the *extent* which ensures that the coordinate set by
212
220
# ``(left, bottom)`` is at the bottom left of the axes! However, this
213
221
# may invert the axis so they do not increase in the 'natural' direction.
214
222
#
215
223
216
- columns = generate_imshow_demo_grid (extents [1 :], auto_limits = True )
224
+ extents = [(- 0.5 , 6.5 , - 0.5 , 5.5 ),
225
+ (- 0.5 , 6.5 , 5.5 , - 0.5 ),
226
+ (6.5 , - 0.5 , - 0.5 , 5.5 ),
227
+ (6.5 , - 0.5 , 5.5 , - 0.5 )]
228
+
229
+ columns = generate_imshow_demo_grid (extents )
217
230
set_extent_None_text (columns ['upper' ][1 ])
218
231
set_extent_None_text (columns ['lower' ][0 ])
219
232
220
233
221
234
###############################################################################
222
235
#
223
- # If we fix the axes limits so ``(0, 0)`` is at the bottom left and
224
- # increases to up and to the right (from the viewer point of view) then
225
- # we can see that:
236
+ # Explicit extent and axes limits
237
+ # -------------------------------
238
+ #
239
+ # If we fix the axes limits by explicity setting `set_xlim` / `set_ylim`, we
240
+ # force a certain size and orientation of the axes.
241
+ # This can decouple the 'left-right' and 'top-bottom' sense of the image from
242
+ # the orientation on the screen.
243
+ #
244
+ # In the example below we have chosen the limits slightly larger than the
245
+ # the extent (note the white areas within the Axes.
246
+ #
247
+ # While we keep the extents as in the examples before, (0, 0) is now
248
+ # explicitly put at the bottom left and values
249
+ # increase to up and to the right (from the viewer point of view).
250
+ # We can see that:
226
251
#
227
252
# - The ``(left, bottom)`` anchors the image which then fills the
228
253
# box going towards the ``(right, top)`` point in data space.
@@ -232,6 +257,5 @@ def generate_imshow_demo_grid(extents, auto_limits):
232
257
# - The 'left-right' and 'top-bottom' sense of the image is uncoupled from
233
258
# the orientation on the screen.
234
259
235
- columns = generate_imshow_demo_grid (extents , auto_limits = False )
236
- set_extent_None_text (columns ['upper' ][2 ])
237
- set_extent_None_text (columns ['lower' ][1 ])
260
+ generate_imshow_demo_grid (extents = [None ] + extents ,
261
+ xlim = (- 2 , 8 ), ylim = (- 1 , 6 ))
0 commit comments