weird behaviour in x axis

Im trying to do a very simple x vs y plot. Where the x values range between
3247 and 3256 and y between 0 and 1. This data is stored in data.dat. I plot
it using the code below, the resulting plot is shown in the first of the two
plots below. Everything goes well except for the x axis, for some reason
tickmarks from 0 up to 9 appear. At the far end of the axis my xmin is
printed: 3.247e3.
I started looking for the cause and it turns out that as long as my range in
x is lower than 10, this happens. If I change the xlimits to xlim(3246,3256)
I get the plot at the bottom of this page, everything is fine. But if I
change this to for instance xlim(3246.01,3256) or xlim(3245, 3254.99) I get
the same behaviour as in the first graph.

Does any one have any experience with this/ know the reason for this
happening? Thanks!

from numpy import *
from pylab import *

datafile = mlab.load('./data.dat')
xx=datafile[:,0]
yy=datafile[:,1]

plot(xx,yy,'black')
xlim(3247,3256)
ylim(0,1.2)

show()

http://old.nabble.com/file/p29687404/wrong.png
http://old.nabble.com/file/p29687404/right.png

···

--
View this message in context: http://old.nabble.com/weird-behaviour-in-x-axis-tp29687404p29687404.html
Sent from the matplotlib - users mailing list archive at Nabble.com.

What is happening isn’t a bug, it is a feature, although it probably could be done a little bit better.

When the range of values to display for ticks is fairly small compared to the size of the values, then matplotlib displays only the part that changes as a value relative to some constant offset. In your case, the constant offset is the +3.247e3 on the right hand side of the axis. This can also happen for the y-axis as well.

This is similar to the idea of how matplotlib would display very large numbers like range(1e7, 10e7, 1e7) as “1 2 3 4 5 6 7 8 9” with a 1e7 at the end of the axis.

I hope this makes sense.

Ben Root

···

On Sat, Sep 11, 2010 at 6:57 PM, freeeeeekk <freeeeeekk@…1972…> wrote:

Im trying to do a very simple x vs y plot. Where the x values range between

3247 and 3256 and y between 0 and 1. This data is stored in data.dat. I plot

it using the code below, the resulting plot is shown in the first of the two

plots below. Everything goes well except for the x axis, for some reason

tickmarks from 0 up to 9 appear. At the far end of the axis my xmin is

printed: 3.247e3.

I started looking for the cause and it turns out that as long as my range in

x is lower than 10, this happens. If I change the xlimits to xlim(3246,3256)

I get the plot at the bottom of this page, everything is fine. But if I

change this to for instance xlim(3246.01,3256) or xlim(3245, 3254.99) I get

the same behaviour as in the first graph.

Does any one have any experience with this/ know the reason for this

happening? Thanks!

from numpy import *

from pylab import *

datafile = mlab.load(‘./data.dat’)

xx=datafile[:,0]

yy=datafile[:,1]

plot(xx,yy,‘black’)

xlim(3247,3256)

ylim(0,1.2)

show()

http://old.nabble.com/file/p29687404/wrong.png

http://old.nabble.com/file/p29687404/right.png

Im trying to do a very simple x vs y plot. Where the x values range between
3247 and 3256 and y between 0 and 1. This data is stored in data.dat. I plot
it using the code below, the resulting plot is shown in the first of the two
plots below. Everything goes well except for the x axis, for some reason
tickmarks from 0 up to 9 appear. At the far end of the axis my xmin is
printed: 3.247e3.
I started looking for the cause and it turns out that as long as my range in
x is lower than 10, this happens. If I change the xlimits to xlim(3246,3256)
I get the plot at the bottom of this page, everything is fine. But if I
change this to for instance xlim(3246.01,3256) or xlim(3245, 3254.99) I get
the same behaviour as in the first graph.

Does any one have any experience with this/ know the reason for this
happening? Thanks!

from numpy import *
from pylab import *

datafile = mlab.load('./data.dat')
xx=datafile[:,0]
yy=datafile[:,1]

plot(xx,yy,'black')
xlim(3247,3256)
ylim(0,1.2)

with older mpl, try this:

gca().xaxis.set_major_formatter(ScalarFormatter(useOffset=False))

with 1.0 or later try the following instead:

ticklabel_format(useOffset=False)

Eric

···

On 09/11/2010 11:12 AM, freeeeeekk wrote:

show()

http://old.nabble.com/file/p29687404/wrong.png
http://old.nabble.com/file/p29687404/right.png

Hi,
apropos this offset discussion.
matplotlib makes offsets not aligned to the full tens or some other
easy number with small amount of non-zero digits in front?

For example having ticks:
4917, 4918, 4919, 4920, 4921, 4922

it will now display:
1, 2, 3, 4, 5, 6 with offset 4916 (of even +4.916e3)

this makes reading values on the axis really really hard as every time
one have to perform not obvious summations with all digits of length.
It would be beneficial to have as a default behaviour some
optimization of offsets to have it as some basic number for easy
reading instead of current behaviour that tries to minimize the number
of digits in the ticks and starts from a low number like 1 or 0.05 or
so.
In our case the best display would be:

17, 18, 19, 20, 21, 22 with offset 4900

So we minimize the number of non-zero digits in offset and not a
number of digits in tick labels.

Another more ridiculous example (from life) are ticks with values:

4916.25, 4916.30, 4916.35, 4916.40, 4916.45

are displayed as:

0.05, 0.10, 0.15, 0.20, 0.25 with offset +4.9162e3

and with good algorithm should be displayed as:

0.25, 0.30, 0.35, 0.40, 0.45 with offset 4962 (nottice that not
+4.962e3 as it usually displays now)

and if we would cross the boundary between 4962 and 4963 than ticks
should look like:
2.80, 2.85, 2.90, 2.95, 3.00, 3.05 with offset 4960

In my opinion the current behaviour of offsets really hampers the
usability of these at all, and probably 90% of users spent some time
on nothing but trying to figure out how to turn this thing off (thanks
for sending this solutions here).

So this is message to signal or show the need for fixing this
algorithm. For now I think that the title of this post: "weird
behaviour in x axis", really summarize current offset algorithm
nicely.

Thanks for your comments,
Jan

···

On Mon, Sep 13, 2010 at 18:35, Eric Firing <efiring@...202...> wrote:

On 09/11/2010 11:12 AM, freeeeeekk wrote:

Im trying to do a very simple x vs y plot. Where the x values range between
3247 and 3256 and y between 0 and 1. This data is stored in data.dat. I plot
it using the code below, the resulting plot is shown in the first of the two
plots below. Everything goes well except for the x axis, for some reason
tickmarks from 0 up to 9 appear. At the far end of the axis my xmin is
printed: 3.247e3.
I started looking for the cause and it turns out that as long as my range in
x is lower than 10, this happens. If I change the xlimits to xlim(3246,3256)
I get the plot at the bottom of this page, everything is fine. But if I
change this to for instance xlim(3246.01,3256) or xlim(3245, 3254.99) I get
the same behaviour as in the first graph.

Does any one have any experience with this/ know the reason for this
happening? Thanks!

from numpy import *
from pylab import *

datafile = mlab.load('./data.dat')
xx=datafile[:,0]
yy=datafile[:,1]

plot(xx,yy,'black')
xlim(3247,3256)
ylim(0,1.2)

with older mpl, try this:

gca().xaxis.set_major_formatter(ScalarFormatter(useOffset=False))

with 1.0 or later try the following instead:

ticklabel_format(useOffset=False)

Eric

show()

http://old.nabble.com/file/p29687404/wrong.png
http://old.nabble.com/file/p29687404/right.png

------------------------------------------------------------------------------
Start uncovering the many advantages of virtual appliances
and start using them to simplify application deployment and
accelerate your shift to cloud computing.
http://p.sf.net/sfu/novell-sfdev2dev
_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
matplotlib-users List Signup and Options

Thanks!

This got it working. Also thanks to the other for explaining why python does
it. I understand the reason, but I think its weird to have that as the
default setting.

efiring wrote:

···

On 09/11/2010 11:12 AM, freeeeeekk wrote:

Im trying to do a very simple x vs y plot. Where the x values range
between
3247 and 3256 and y between 0 and 1. This data is stored in data.dat. I
plot
it using the code below, the resulting plot is shown in the first of the
two
plots below. Everything goes well except for the x axis, for some reason
tickmarks from 0 up to 9 appear. At the far end of the axis my xmin is
printed: 3.247e3.
I started looking for the cause and it turns out that as long as my range
in
x is lower than 10, this happens. If I change the xlimits to
xlim(3246,3256)
I get the plot at the bottom of this page, everything is fine. But if I
change this to for instance xlim(3246.01,3256) or xlim(3245, 3254.99) I
get
the same behaviour as in the first graph.

Does any one have any experience with this/ know the reason for this
happening? Thanks!

from numpy import *
from pylab import *

datafile = mlab.load('./data.dat')
xx=datafile[:,0]
yy=datafile[:,1]

plot(xx,yy,'black')
xlim(3247,3256)
ylim(0,1.2)

with older mpl, try this:

gca().xaxis.set_major_formatter(ScalarFormatter(useOffset=False))

with 1.0 or later try the following instead:

ticklabel_format(useOffset=False)

Eric

show()

http://old.nabble.com/file/p29687404/wrong.png
http://old.nabble.com/file/p29687404/right.png

------------------------------------------------------------------------------
Start uncovering the many advantages of virtual appliances
and start using them to simplify application deployment and
accelerate your shift to cloud computing.
http://p.sf.net/sfu/novell-sfdev2dev
_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
matplotlib-users List Signup and Options

--
View this message in context: http://old.nabble.com/weird-behaviour-in-x-axis-tp29687404p29718992.html
Sent from the matplotlib - users mailing list archive at Nabble.com.

I like that idea as it is certainly more intuitive. Essentially, it would find the most significant bits that are common to all ticks and use that for the offset.

Does anybody know where the current code is? I would be willing to take a look at it today and see what I can do.

Thanks,
Ben Root

···

On Tue, Sep 14, 2010 at 11:12 AM, Jan Skowron <jan.skowron@…878…287…> wrote:

Hi,

apropos this offset discussion.

matplotlib makes offsets not aligned to the full tens or some other

easy number with small amount of non-zero digits in front?

For example having ticks:

4917, 4918, 4919, 4920, 4921, 4922

it will now display:

1, 2, 3, 4, 5, 6 with offset 4916 (of even +4.916e3)

this makes reading values on the axis really really hard as every time

one have to perform not obvious summations with all digits of length.

It would be beneficial to have as a default behaviour some

optimization of offsets to have it as some basic number for easy

reading instead of current behaviour that tries to minimize the number

of digits in the ticks and starts from a low number like 1 or 0.05 or

so.

In our case the best display would be:

17, 18, 19, 20, 21, 22 with offset 4900

So we minimize the number of non-zero digits in offset and not a

number of digits in tick labels.

Another more ridiculous example (from life) are ticks with values:

4916.25, 4916.30, 4916.35, 4916.40, 4916.45

are displayed as:

0.05, 0.10, 0.15, 0.20, 0.25 with offset +4.9162e3

and with good algorithm should be displayed as:

0.25, 0.30, 0.35, 0.40, 0.45 with offset 4962 (nottice that not

+4.962e3 as it usually displays now)

and if we would cross the boundary between 4962 and 4963 than ticks

should look like:

2.80, 2.85, 2.90, 2.95, 3.00, 3.05 with offset 4960

In my opinion the current behaviour of offsets really hampers the

usability of these at all, and probably 90% of users spent some time

on nothing but trying to figure out how to turn this thing off (thanks

for sending this solutions here).

So this is message to signal or show the need for fixing this

algorithm. For now I think that the title of this post: "weird

behaviour in x axis", really summarize current offset algorithm

nicely.

Thanks for your comments,

Jan

    Hi,
    apropos this offset discussion.
    matplotlib makes offsets not aligned to the full tens or some other
    easy number with small amount of non-zero digits in front?

    For example having ticks:
    4917, 4918, 4919, 4920, 4921, 4922

    it will now display:
    1, 2, 3, 4, 5, 6 with offset 4916 (of even +4.916e3)

    this makes reading values on the axis really really hard as every time
    one have to perform not obvious summations with all digits of length.
    It would be beneficial to have as a default behaviour some
    optimization of offsets to have it as some basic number for easy
    reading instead of current behaviour that tries to minimize the number
    of digits in the ticks and starts from a low number like 1 or 0.05 or
    so.
    In our case the best display would be:

    17, 18, 19, 20, 21, 22 with offset 4900

    So we minimize the number of non-zero digits in offset and not a
    number of digits in tick labels.

    Another more ridiculous example (from life) are ticks with values:

    4916.25, 4916.30, 4916.35, 4916.40, 4916.45

    are displayed as:

    0.05, 0.10, 0.15, 0.20, 0.25 with offset +4.9162e3

    and with good algorithm should be displayed as:

    0.25, 0.30, 0.35, 0.40, 0.45 with offset 4962 (nottice that not
    +4.962e3 as it usually displays now)

    and if we would cross the boundary between 4962 and 4963 than ticks
    should look like:
    2.80, 2.85, 2.90, 2.95, 3.00, 3.05 with offset 4960

    In my opinion the current behaviour of offsets really hampers the
    usability of these at all, and probably 90% of users spent some time
    on nothing but trying to figure out how to turn this thing off (thanks
    for sending this solutions here).

    So this is message to signal or show the need for fixing this
    algorithm. For now I think that the title of this post: "weird
    behaviour in x axis", really summarize current offset algorithm
    nicely.

    Thanks for your comments,
    Jan

I like that idea as it is certainly more intuitive. Essentially, it
would find the most significant bits that are common to all ticks and
use that for the offset.

Does anybody know where the current code is? I would be willing to take
a look at it today and see what I can do.

In ticker.ScalarFormatter._setOffset (or something like that). Be careful not to make it too complicated; maybe it can even be made simpler. I think that as a first shot, something like adding +3 (or maybe it would be -3) to a couple lines of code might be a step in the right direction--and maybe adequate.

Thank you.

Eric

···

On 09/15/2010 04:55 AM, Benjamin Root wrote:

On Tue, Sep 14, 2010 at 11:12 AM, Jan Skowron <jan.skowron@...287... > <mailto:jan.skowron@…287…>> wrote:

Thanks,
Ben Root

------------------------------------------------------------------------------
Start uncovering the many advantages of virtual appliances
and start using them to simplify application deployment and
accelerate your shift to cloud computing.
http://p.sf.net/sfu/novell-sfdev2dev

_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
matplotlib-users List Signup and Options

Here is what I came up with. In ticker.ScalarFormatter._setOffset, I set a variable called “common_oom” to the same value as ‘range_oom’. This order of magnitude should be the smallest possible magnitude where there all the significant digits are the same. Then, I do:

tickdiff = np.sum(np.diff(np.trunc(locs * 10**-common_oom)))
while tickdiff >= 1.0 :
common_oom += 1.0
tickdiff = np.sum(np.diff(np.trunc(locs * 10**-common_oom)))

Essentially, I find increment common_oom until the differences in the rounded versions of the locs become significant. Then, I use common_oom instead of range_oom in calculating the offset.

I suspect it could be done better, and I am not certain that there are no edge cases regarding the use of trunc.

Thoughts, concerns?

Ben Root

cleanoffsets.patch (1.43 KB)

···

On Wed, Sep 15, 2010 at 12:37 PM, Eric Firing <efiring@…202…> wrote:

On 09/15/2010 04:55 AM, Benjamin Root wrote:

On Tue, Sep 14, 2010 at 11:12 AM, Jan Skowron <jan.skowron@…287… > > mailto:jan.skowron@...287...> wrote:

Hi,
apropos this offset discussion.
matplotlib makes offsets not aligned to the full tens or some other
easy number with small amount of non-zero digits in front?
For example having ticks:
4917, 4918, 4919, 4920, 4921, 4922
it will now display:
1, 2, 3, 4, 5, 6   with offset 4916  (of even +4.916e3)
this makes reading values on the axis really really hard as every time
one have to perform not obvious summations with all digits of length.
It would be beneficial to have as a default behaviour some
optimization of offsets to have it as some basic number for easy
reading instead of current behaviour that tries to minimize the number
of digits in the ticks and starts from a low number like 1 or 0.05 or
so.
In our case the best display would be:
17, 18, 19, 20, 21, 22  with offset 4900
So we minimize the number of non-zero digits in offset and not a
number of digits in tick labels.
Another more ridiculous example (from life) are ticks with values:
4916.25, 4916.30, 4916.35, 4916.40, 4916.45
are displayed as:
0.05, 0.10, 0.15, 0.20, 0.25   with offset +4.9162e3
and with good algorithm should be displayed as:
0.25, 0.30, 0.35, 0.40, 0.45  with offset 4962  (nottice that not
+4.962e3 as it usually displays now)
and if we would cross the boundary between 4962 and 4963 than ticks
should look like:
2.80, 2.85, 2.90, 2.95, 3.00, 3.05   with offset 4960
In my opinion the current behaviour of offsets really hampers the
usability of these at all, and probably 90% of users spent some time
on nothing but trying to figure out how to turn this thing off (thanks
for sending this solutions here).
So this is message to signal or show the need for fixing this
algorithm. For now I think that the title of this post: "weird
behaviour in x axis", really summarize current offset algorithm
nicely.
Thanks for your comments,
Jan

I like that idea as it is certainly more intuitive. Essentially, it

would find the most significant bits that are common to all ticks and

use that for the offset.

Does anybody know where the current code is? I would be willing to take

a look at it today and see what I can do.

In ticker.ScalarFormatter._setOffset (or something like that). Be

careful not to make it too complicated; maybe it can even be made

simpler. I think that as a first shot, something like adding +3 (or

maybe it would be -3) to a couple lines of code might be a step in the

right direction–and maybe adequate.

Thank you.

Eric

     >
     > Hi,
     > apropos this offset discussion.
     > matplotlib makes offsets not aligned to the full tens or some
    other
     > easy number with small amount of non-zero digits in front?
     >
     > For example having ticks:
     > 4917, 4918, 4919, 4920, 4921, 4922
     >
     > it will now display:
     > 1, 2, 3, 4, 5, 6 with offset 4916 (of even +4.916e3)
     >
     > this makes reading values on the axis really really hard as
    every time
     > one have to perform not obvious summations with all digits of
    length.
     > It would be beneficial to have as a default behaviour some
     > optimization of offsets to have it as some basic number for easy
     > reading instead of current behaviour that tries to minimize
    the number
     > of digits in the ticks and starts from a low number like 1 or
    0.05 or
     > so.
     > In our case the best display would be:
     >
     > 17, 18, 19, 20, 21, 22 with offset 4900
     >
     > So we minimize the number of non-zero digits in offset and not a
     > number of digits in tick labels.
     >
     > Another more ridiculous example (from life) are ticks with
    values:
     >
     > 4916.25, 4916.30, 4916.35, 4916.40, 4916.45
     >
     > are displayed as:
     >
     > 0.05, 0.10, 0.15, 0.20, 0.25 with offset +4.9162e3
     >
     > and with good algorithm should be displayed as:
     >
     > 0.25, 0.30, 0.35, 0.40, 0.45 with offset 4962 (nottice that not
     > +4.962e3 as it usually displays now)
     >
     > and if we would cross the boundary between 4962 and 4963 than
    ticks
     > should look like:
     > 2.80, 2.85, 2.90, 2.95, 3.00, 3.05 with offset 4960
     >
     > In my opinion the current behaviour of offsets really hampers the
     > usability of these at all, and probably 90% of users spent
    some time
     > on nothing but trying to figure out how to turn this thing
    off (thanks
     > for sending this solutions here).
     >
     > So this is message to signal or show the need for fixing this
     > algorithm. For now I think that the title of this post: "weird
     > behaviour in x axis", really summarize current offset algorithm
     > nicely.
     >
     > Thanks for your comments,
     > Jan
     >
     > I like that idea as it is certainly more intuitive. Essentially, it
     > would find the most significant bits that are common to all ticks and
     > use that for the offset.
     >
     > Does anybody know where the current code is? I would be willing
    to take
     > a look at it today and see what I can do.

    In ticker.ScalarFormatter._setOffset (or something like that). Be
    careful not to make it too complicated; maybe it can even be made
    simpler. I think that as a first shot, something like adding +3 (or
    maybe it would be -3) to a couple lines of code might be a step in the
    right direction--and maybe adequate.

    Thank you.

    Eric

Here is what I came up with. In ticker.ScalarFormatter._setOffset, I
set a variable called "common_oom" to the same value as 'range_oom'.
This order of magnitude should be the smallest possible magnitude where
there all the significant digits are the same. Then, I do:

tickdiff = np.sum(np.diff(np.trunc(locs * 10**-common_oom)))
while tickdiff >= 1.0 :
     common_oom += 1.0
     tickdiff = np.sum(np.diff(np.trunc(locs * 10**-common_oom)))

Essentially, I find increment common_oom until the differences in the
rounded versions of the locs become significant. Then, I use common_oom
instead of range_oom in calculating the offset.

I suspect it could be done better, and I am not certain that there are
no edge cases regarding the use of trunc.

Thoughts, concerns?

Ben Root

Ben,

I can't look closely right now, so here are only very quick off-the-cuff comments:

1) for testing, try to come up with a good selection of cases: negative, positive, very close to, but less than 1, very close to, but greater than, 1, etc.

2) I'm concerned that the sort of approach you are describing may be slow. The process of generating a plot, and redrawing it upon zoom/pan/resize, is already badly slowed down by the ticks and tick labels, and I would hate to see this pesky offset make the situation worse.

3) Isn't there a good-enough solution involving a single math calculation?

4) Although I have complained about the ever-expanding set of rcParams, *maybe* the useOffset default should be added. Rather than a boolean, it could be a threshold.

Eric

···

On 09/15/2010 08:25 AM, Benjamin Root wrote:

On Wed, Sep 15, 2010 at 12:37 PM, Eric Firing <efiring@...202... > <mailto:efiring@…202…>> wrote:
    On 09/15/2010 04:55 AM, Benjamin Root wrote:
     > On Tue, Sep 14, 2010 at 11:12 AM, Jan Skowron > <jan.skowron@...287... <mailto:jan.skowron@…287…> > > <mailto:jan.skowron@…287…>> wrote:

------------------------------------------------------------------------------
Start uncovering the many advantages of virtual appliances
and start using them to simplify application deployment and
accelerate your shift to cloud computing.
http://p.sf.net/sfu/novell-sfdev2dev

_______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
matplotlib-users List Signup and Options