plot() with a nearly-constant sequence doesn't always work

Hello matplotlib developers,

In Sage, we've run into a problem with plotting a sequence whose
y-values change by very small amounts. Here's an example that doesn't
use anything from Sage:

import pylab
pylab.plot([0, 1], [0, 1e-14])
pylab.savefig("works.png")
pylab.close()
pylab.plot([0, 1], [1, 1+1e-14])
pylab.savefig("fails.png")
pylab.close()

We're using matplotlib 1.1. Here's a trac ticket where we are working on
this: http://trac.sagemath.org/sage_trac/ticket/11973. One of our
developers suspects matplotlib.ticker.MaxNLocator.bin_boundaries but we
don't really know.

Thanks for any help or comments!

Dan

···

--
--- Dan Drake
----- http://mathsci.kaist.ac.kr/~drake
-------

Hello matplotlib developers,

In Sage, we've run into a problem with plotting a sequence whose
y-values change by very small amounts. Here's an example that doesn't
use anything from Sage:

import pylab
pylab.plot([0, 1], [0, 1e-14])
pylab.savefig("works.png")
pylab.close()
pylab.plot([0, 1], [1, 1+1e-14])
pylab.savefig("fails.png")
pylab.close()

We're using matplotlib 1.1. Here's a trac ticket where we are working on
this: http://trac.sagemath.org/sage_trac/ticket/11973. One of our
developers suspects matplotlib.ticker.MaxNLocator.bin_boundaries but we
don't really know.

Dan,

I think the behavior is coming from a threshold value of 1e-12 in ticker.scale_range. This needs more thought than I can give it at the moment, but perhaps you could file a ticket on the github mpl site.

Note that even if this threshold behavior is removed, there is another one waiting in the wings behind it, with a default value of 1e-16, used to decide whether a range is singular; if it is, then it gets expanded.

Eric

···

On 05/25/2012 12:46 PM, Dan Drake wrote:

Thanks for any help or comments!

Dan

Hello matplotlib developers,

In Sage, we've run into a problem with plotting a sequence whose
y-values change by very small amounts. Here's an example that doesn't
use anything from Sage:

import pylab
pylab.plot([0, 1], [0, 1e-14])
pylab.savefig("works.png")
pylab.close()
pylab.plot([0, 1], [1, 1+1e-14])
pylab.savefig("fails.png")
pylab.close()

We're using matplotlib 1.1. Here's a trac ticket where we are working on
this: http://trac.sagemath.org/sage_trac/ticket/11973. One of our
developers suspects matplotlib.ticker.MaxNLocator.bin_boundaries but we
don't really know.

Dan,

It is easy enough to remove the immediate roadblock in scale_range, but that just opens up a can of floating point worms. The axis spines start getting misplaced, for example, as the range being plotted gets too small relative to the offset. Straightening all this out, or even substantially improving it, is potentially tricky. To the extent that it can be done, it will have to be in master, which already includes one cleanup of a floating point kluge.

Note that part of the problem here is that in your example we are running out of precision. The best way to handle it is to subtract an offset first, and just plot the deviation from that offset. I think this is best done at the application level. We can probably make mpl's handling of the problem degrade more gracefully, however, than it does at present.

Eric

···

On 05/25/2012 12:46 PM, Dan Drake wrote:

Thanks for any help or comments!

Dan

--
--- Dan Drake
----- http://mathsci.kaist.ac.kr/~drakes
-------

Hello matplotlib developers,

In Sage, we've run into a problem with plotting a sequence whose
y-values change by very small amounts. Here's an example that doesn't
use anything from Sage:

import pylab
pylab.plot([0, 1], [0, 1e-14])
pylab.savefig("works.png")
pylab.close()
pylab.plot([0, 1], [1, 1+1e-14])
pylab.savefig("fails.png")
pylab.close()

We're using matplotlib 1.1. Here's a trac ticket where we are working on
this: http://trac.sagemath.org/sage_trac/ticket/11973. One of our
developers suspects matplotlib.ticker.MaxNLocator.bin_boundaries but we
don't really know.

See Improve handling of data ranges near the limit of double precision resolution by efiring · Pull Request #904 · matplotlib/matplotlib · GitHub

Eric

···

On 05/25/2012 12:46 PM, Dan Drake wrote:

Thanks for any help or comments!

Dan

--
--- Dan Drake
----- http://mathsci.kaist.ac.kr/~drake
-------

Thanks for your help. I'll look at your links and see what we can do.

Dan

···

On Sat, 26 May 2012 at 03:30PM -1000, Eric Firing wrote:

It is easy enough to remove the immediate roadblock in scale_range,
but that just opens up a can of floating point worms. The axis spines
start getting misplaced, for example, as the range being plotted gets
too small relative to the offset. Straightening all this out, or even
substantially improving it, is potentially tricky. To the extent that
it can be done, it will have to be in master, which already includes
one cleanup of a floating point kluge.

Note that part of the problem here is that in your example we are
running out of precision. The best way to handle it is to subtract an
offset first, and just plot the deviation from that offset. I think
this is best done at the application level. We can probably make
mpl's handling of the problem degrade more gracefully, however, than
it does at present.

--
--- Dan Drake
----- http://mathsci.kaist.ac.kr/~drake
-------