-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
DOC: add tutorial explaining imshow *origin* and *extent* #10947
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
519c1dc
to
1124ec9
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A couple of suggestions for improvement.
from matplotlib.gridspec import GridSpec | ||
|
||
|
||
def generate_imshow_demo_grid(auto_limits, extents): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might be worth having these as keyword arguments? When I read the tutorial I scrolled past this big block of code, and then was confused as to what generate_imshow_demo_grid(True...)
did, but I think generate_imshow_demo_grid(auto_limits=True...)
would be much better.
# ``np.arange(42).reshape(6, 7)`` with varying parameters. | ||
# | ||
|
||
generate_imshow_demo_grid(True, extents[:1]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There isn't a massive change in these images from L --> R, but a clear different from top to bottom. Maybe a good place to use a colourmap that isn't perceptually uniform to illustrate changes in orientation?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At least when I look a these what I see is the direction of highest-lowest vector, changed to a diagonal gradient.
Geat tutorial! I did suggest to have such example around in #10982 without seeing this one being created. I used triangular shaped data to explain a point I wanted to make in that PR, something like This would make it easier to grasp at which corner the data is shown compared to the original array. Would this be an option here? |
|
||
d = np.arange(42).reshape(6, 7) | ||
x, y = np.ogrid[0:6, 0:7] | ||
d = x + y |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 yes, that's what I meant!
# ``(left, bottom)`` corner of the bounding box and moving closer to | ||
# ``(left, top)`` moves along the ``[:, 0]`` axis of the array to | ||
# higher indexed rows and moving towards ``(right, bottom)`` moves you | ||
# along the ``[0, :]`` axis of the array to higher indexed columns |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Possibly better as a bullet list or table than plain text:
Generally, for an array of shape (M,N), the first index runs along the vertical, the second index runs along the horizontal. origin determines how to the data is filled in the bounding box.
For origin='lower'
:
- [0, 0] is at
(left, bottom)
- [M, 0] is at
(left, top)
- [0, N] is at
(right, bottom)
- [M, N] is at
(right, top)
origin='upper'
reverses the vertical filling:
- [0, 0] is at
(left, top)
- [M, 0] is at
(left, bottom)
- [0, N] is at
(right, top)
- [M, N] is at
(right, bottom)
# is ``(-0.5, numcols-0.5, numrows-0.5, -0.5)`` when ``origin == | ||
# 'upper'`` and ``(-0.5, numcols-0.5, -0.5, numrows-0.5)`` when ``origin | ||
# == 'lower'`` which puts the pixel centers on integer positions and the | ||
# ``[0, 0]`` pixel at ``(0, 0)`` in dataspace. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's simpler to understand if this was a table with colums 'origin == upper', 'origin == lower' and rows
- [0, 0] pixel position
- default extent
- maybe more.
'xy': (1, .5)} | ||
if extent is None: | ||
ax.annotate('None', **text_kwargs) | ||
ax.set_title('`extent=`') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Backticks don't work here. We can just leave them out.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
man, talk about muscle memory....
from matplotlib.gridspec import GridSpec | ||
|
||
|
||
def generate_imshow_demo_grid(extents, auto_limits): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I find it more natural with a reversed logic that uses explicit_limits=False
instead of auto_limits
, or alternatively, xlims=None, ylims=None
.
|
||
############################################################################### | ||
# | ||
# If we fix the axes limits so ``(0, 0)`` is at the bottom left and |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we fix the axes limits by explicity setting set_xlim
/ set_ylim
, we force a certain orientation of the axes. This can decouple the 'left-right' and 'top-bottom' sense of the image from the orientation on the screen.
In the example below (0, 0) is explicitly put at the bottom left and values increase to up and to the right (from the viewer point of view). We can see that:
Also it helps to display the indices in the plots:
and in the inner for loop:
|
Just mind the notation. In the imshow docs (#10982), arrays are of shape
|
@ImportanceOfBeingErnest Agreed on all points.
|
Probably the best solution is using boxes for the indices as well:
and code:
|
@timhoffm @ImportanceOfBeingErnest feel free to push directly to this branch, I think all of these suggestions are great 👍 Would probably push the index labels in a bit or give them some alpha, they are covering the tick labels and the arrow. The index labels make also make the arrow superfluous. |
@ImportanceOfBeingErnest Why is the convention (N, M)? Is this only for images? I find it quite confusing--why use reversed-alphabetical order? What about indices--are they (i, j), or (j, i)? |
@efiring Good point. For some reason we're using this convention, but upon reflection and googling, I did not find profound evidence for it being "widely used". I was then somehow confirmed by the recently proposed changes to the imshow docs (#10982). (@timhoffm Might this be a typical german thing?) So restart from scratch: the From a bit of googling and also looking at wikipedia it seems |
f1b481b
to
d1e307a
Compare
You are right. Changed. |
I think this is good to go. For reviewers, here's how it looks like: |
(-0.5, 6.5, 5.5, -0.5), | ||
(6.5, -0.5, -0.5, 5.5), | ||
(6.5, -0.5, 5.5, -0.5)] | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This set of examples doesn't really help me because the "extents" is still the same as the extents I'd expect from the underlying data array size. Wouldn't it be more illustrative to go from 0-15 or something? The phrase "...a bounding box in data space" is also mysterious. I think of the matrix as being the data and a bounding box on the data means a clip to me. But what you mean is that the extents are the x and y co-ordinates over which the matrix is placed.
The docs say "The location, in data-coordinates, of the lower-left and upper-right corners" ; I prefer "data-coordinates"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The point is to show how inverting the left vs right or top vs bottom changes the image around. Using different limits would make that a harder apples-to-apples comparison.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes But it didn’t help me understand what extents actually is on the first place
I’ll admit this flipping the axes seems like the wrong behaviour. I’d have expected the matrix to flip. But I doubt I’ll get that changed here. ;-)
I really like the changes! Thanks @ImportanceOfBeingErnest and @timhoffm ! I am 👍 on merging this, but don't want to push the button as I have commits in this and can not approve is github things this is my PR. |
d1e307a
to
dcb18e0
Compare
dcb18e0
to
206c3ca
Compare
Probably this example could be improved even further, but that would require significant restructuring of code and description. I'm pushing this forward to have a reference to point to from the imshow docstring and get my associated PR #10982 approved. As a first step this PR is now good enough for that. Further improvements can be added later. |
I merged as a stand-alone improvement. Can be refined upon... |
Backport PR #10947 on branch v2.2.2-doc
PR Summary
Sort out how origin and 'extent interact.
attn @efiring
PR Checklist