Thanks to visit codestin.com
Credit goes to github.com

Skip to content

DOC: explain non-linear scales and imshow (closes #7661) #7800

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

Merged
merged 4 commits into from
Jan 16, 2017

Conversation

phobson
Copy link
Member

@phobson phobson commented Jan 11, 2017

No description provided.

@phobson phobson added this to the 2.0 (style change major release) milestone Jan 11, 2017
Copy link
Contributor

@afvincent afvincent left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not very used to RST language, but from what I read here, I guess the whole literal block (meaning even the even the if 1: line) should be indented to be correctly rendered. Personally, I would simply remove if 1: line as the example is short and clean, but maybe it is a matter of personal taste :).

Log-scale on image plots
------------------------

:func:`imshow` not properly displays data on log-scales.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not <- now?

Copy link
Member Author

@phobson phobson Jan 11, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right on both accounts (the if 1: trick is there so can I be lazy when copy/pasting into jupyter -- oops)

@phobson phobson force-pushed the doc-imshow-logscale branch from 6c407a4 to 25158c2 Compare January 11, 2017 08:46
@codecov-io
Copy link

codecov-io commented Jan 11, 2017

Current coverage is 62.10% (diff: 100%)

Merging #7800 into master will decrease coverage by 0.01%

@@             master      #7800   diff @@
==========================================
  Files           174        174          
  Lines         56028      56051    +23   
  Methods           0          0          
  Messages          0          0          
  Branches          0          0          
==========================================
+ Hits          34803      34810     +7   
- Misses        21225      21241    +16   
  Partials          0          0          

Powered by Codecov. Last update c676432...68230b2

@phobson
Copy link
Member Author

phobson commented Jan 11, 2017

Cleaned up based on comments from @afvincent and squashed/force-pushed

@@ -0,0 +1,31 @@
Log-scale on image plots
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"nonlinear scales"? (also applies to logit, etc. I guess)

Log-scale on image plots
------------------------

:func:`imshow` now properly displays data on log-scales.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Properly" and "correct" below don't really help describing the behavior. Something like "draws values at the requested points in data space after application of the scale"?

@phobson phobson force-pushed the doc-imshow-logscale branch from 595603b to 82c4aab Compare January 11, 2017 19:10
@phobson phobson changed the title DOC: explain logscales and imshow (closes #7661) DOC: explain non-linear scales and imshow (closes #7661) Jan 11, 2017
@anntzer
Copy link
Contributor

anntzer commented Jan 11, 2017

Actually, this should probably go into the same subheader as http://matplotlib.org/devdocs/users/whats_new.html#improved-image-support.

@phobson
Copy link
Member Author

phobson commented Jan 11, 2017

@anntzer great point

@phobson phobson closed this Jan 11, 2017
@phobson phobson reopened this Jan 11, 2017
@efiring
Copy link
Member

efiring commented Jan 11, 2017

I'm concerned about this because I think that using imshow for anything other than linear scales is a terrible idea, confusing in the extreme. At this stage we should strongly discourage it in the documentation, and a real improvement would be to block it in later releases after the usual warning period.

Try changing the example to:

ax1.imshow(data, origin='bottom', aspect="auto", extent=(5, 0, 1e5, 1e0), interpolation='nearest')

and see if you think people will be happy with it, and will understand what it is doing without a long bout of head-scratching.
imshow simply doesn't have the right interface for anything other than normal, simple images. Even the existing extent kwarg is a pain--it gives no clue as to which of the many possible sets and permutations of 4 numbers it needs.

@efiring
Copy link
Member

efiring commented Jan 11, 2017

Specific advice for the present PR: state that the behavior of imshow with other than linear axes has changed, but it remains undefined and should not be used. And I would omit the plots.

@tacaswell
Copy link
Member

@efiring I disagree about not using imshow on non-linear axes. If you have evenly spaced bins it is a more efficient way than using pcolormesh to get the same effect.

Agree extent could be clearer.

@efiring
Copy link
Member

efiring commented Jan 11, 2017

@tacaswell, are you volunteering to explain to puzzled users why the result of the example change that I gave above looks the way it does? And why this is an acceptable API? We can do this right, but imshow doesn't do so, by design. What do we lose by my suggestion of acknowledging that imshow was never designed for log scales, and now, by accident, happens to do what one might want, sometimes, with the right combination of obscure arguments? I think this acknowledgement would be doing users a favor.

@tacaswell
Copy link
Member

The issue with flipping extent around like that seems to be more about bottom and non-increasing values in extent being confusing as it is just as puzzilng in linear scale as with log.

import numpy as np
import matplotlib.pyplot as plt

data = np.arange(30).reshape(5, 6)
x = np.linspace(0, 6, 7)
y = 10**np.linspace(0, 5, 6)
X, Y = np.meshgrid(x, y)

fig, (ax1, ax2) = plt.subplots(ncols=2, figsize=(8, 4))

ax1.imshow(data, origin='bottom', aspect="auto", extent=(6, 0, 1e5, 1e0),
           interpolation='nearest')



ax2.imshow(data, origin='bottom', aspect="auto", extent=(6, 0, 1e5, 1e0),
           interpolation='nearest')
ax2.set_yscale('log')

plt.show()

so

@efiring
Copy link
Member

efiring commented Jan 11, 2017

The log scale adds another dimension to the confusion, as illustrated by the fact that this discussion started when a user had been relying on the old behavior and considered that to be correct.


fig, (ax1, ax2) = plt.subplots(ncols=2, figsize=(8, 4))

ax1.imshow(data, aspect="auto", extent=(0, 5, 1e0, 1e5), interpolation='nearest')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the 5 should be a 6

@tacaswell
Copy link
Member

And the gap on the right is dependent on figure size...

@tacaswell
Copy link
Member

tacaswell commented Jan 11, 2017

In my personal use I have used imshow almost exclusively for data extracted from imaging detectors where the pixel value is a measure of how many photons hit that pixel (ie, a 2D histogram). The pixel edges moving with the scale seems very natural to me.

For example

import numpy as np
import matplotlib.pyplot as plt

data = np.arange(30).reshape(5, 6)
x = np.linspace(0, 6, 7)
y = 10**np.linspace(0, 5, 6)
X, Y = np.meshgrid(x, y)

fig, (ax1, ax2) = plt.subplots(ncols=2, figsize=(8, 4))
ax1.hist(np.random.rand(5000)*50000, bins=10, edgecolor='k')
ax2.hist(np.random.rand(5000)*50000, bins=10, edgecolor='k')
ax2.set_xscale('log')

plt.show()

so

which although it seems to expose yet another bug in log handling, seems very natural. As does

import numpy as np
import matplotlib.pyplot as plt

data = np.arange(30).reshape(5, 6)
x = np.linspace(0, 6, 7)
y = 10**np.linspace(0, 5, 6)
X, Y = np.meshgrid(x, y)

fig, (ax1, ax2) = plt.subplots(ncols=2, figsize=(8, 4))
ax1.hist(np.random.rand(5000)*100000, bins=np.logspace(0, 5, 10), edgecolor='k')
ax2.hist(np.random.rand(5000)*100000, bins=np.logspace(0, 5, 10), edgecolor='k')
ax2.set_xscale('log')

plt.show()

so



This can be understood by analogy to plotting a histogram with linearly spaced bins
with a logarithmic x-axis. Equal sized bins at will be displayed as wider for small
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand this sentence "Equal sized bins at will be displayed …"

@phobson phobson force-pushed the doc-imshow-logscale branch from 30e579b to a9530f6 Compare January 16, 2017 20:49
@efiring efiring merged commit 54b120f into matplotlib:master Jan 16, 2017
@tacaswell
Copy link
Member

@efiring you mind if I do the backport of this? I have it ready to push, but don't want mess you up if you are doing it.

tacaswell pushed a commit that referenced this pull request Jan 16, 2017
DOC: explain non-linear scales and imshow (closes #7661)
@tacaswell
Copy link
Member

backported to v2.x as cfafd3d

@phobson phobson deleted the doc-imshow-logscale branch January 23, 2017 22:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants