x= / y= labels default format is wrong

Indeed, but it should really be fixed in the svn.

Xavier

···

Hi Xavier,

I had the same problem and fixed it by changing just two lines of code in the axes.py (line 1812 and 1814). Just change the formatter in 'self.xaxis.major.formatter.set_scientific(sb)' to whatever you want (the same for y).

But it would really be great to see your proposal as a standard.

Greetings,

David

-------- Original-Nachricht -------- > Datum: Sun, 24 May 2009 19:15:18 +0200 > Von: Xavier Gnata <xavier.gnata@...287...> > An: matplotlib-users@...1220...sts.sourceforge.net > Betreff: [Matplotlib-users] x= / y= labels default format is wrong > Hello all, > > I routinely work with images sizes > [1000,1000]. > There is a slight annoying problem whatever the backend I use: > Pixels coordinates default format is wrong. > It does not make sense to display "x=1.42e+03,y=1.92e+03". > Pixels coordinates should be formated *by default* as integers. > > Would it be possible to fix that? > > Steps to reproduce: > import numpy > import pylab > a=numpy.random.random((2000,2000)) > pylab.imshow(a,interpolation='Nearest') > > > Xavier > > ------------------------------------------------------------------------------ > Register Now for Creativity and Technology (CaT), June 3rd, NYC. CaT > is a gathering of tech-side developers & brand creativity professionals. > Meet > the minds behind Google Creative Lab, Visual Complexity, Processing, & > iPhoneDevCamp asthey present alongside digital heavyweights like Barbarian > Group, R/GA, & Big Spaceship. http://www.creativitycat.com > _______________________________________________ > Matplotlib-users mailing list > Matplotlib-users@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/matplotlib-users

I had the same problem and fixed it by changing just two lines of code in the axes.py (line 1812 and 1814). Just change the formatter in 'self.xaxis.major.formatter.set_scientific(sb)' to whatever you want (the same for y).

You don't need to modify the internals of axes.py -- just set the
formatter on the axes instance itself.

  http://matplotlib.sourceforge.net/search.html?q=codex+set_major_formatter

Indeed, but it should really be fixed in the svn.

We could perhaps be a little smarter about this, but consider that one
can easily plot lines over images

In [30]: imshow(np.random.rand(512,512))
Out[30]: <matplotlib.image.AxesImage object at 0x151c4f4c>

In [31]: plot(np.arange(512), np.arange(512))

Since the plot can be a mix of images, polygons, lines, etc, it is not
obvious that the formatter should be int. We could trap the case
where you have only an image, no other data, and haven't set the
extent, but it would be complicated because you may add data to the
plot later and we would have to track that we had attempted to be
clever but we should now undo our cleverness. Our general philosophy
is to make is easy for you to customize when the default behavior
doesn't suit you, so try

  import matplotlib.ticker as ticker
  ax.xaxis.set_major_formatter(ticker.FormatStrFormatter('%d'))
  .. and ditto for yaxis ..

in addition to the ticks, you can customize how the coords appear in
the toolbar by setting

  ax.fmt_xdata = ticker.FormatStrFormatter('%d')
  ... and ditto for fmt_ydata

There are a variety of formatters available

  http://matplotlib.sourceforge.net/api/ticker_api.html

JDH

···

On Fri, May 29, 2009 at 10:50 AM, Xavier Gnata <xavier.gnata@...287...> wrote:

John Hunter wrote:

I had the same problem and fixed it by changing just two lines of code in the axes.py (line 1812 and 1814). Just change the formatter in 'self.xaxis.major.formatter.set_scientific(sb)' to whatever you want (the same for y).
      
You don't need to modify the internals of axes.py -- just set the
formatter on the axes instance itself.

  http://matplotlib.sourceforge.net/search.html?q=codex+set_major_formatter

Indeed, but it should really be fixed in the svn.
    
We could perhaps be a little smarter about this, but consider that one
can easily plot lines over images

In [30]: imshow(np.random.rand(512,512))
Out[30]: <matplotlib.image.AxesImage object at 0x151c4f4c>

In [31]: plot(np.arange(512), np.arange(512))

Since the plot can be a mix of images, polygons, lines, etc, it is not
obvious that the formatter should be int. We could trap the case
where you have only an image, no other data, and haven't set the
extent, but it would be complicated because you may add data to the
plot later and we would have to track that we had attempted to be
clever but we should now undo our cleverness. Our general philosophy
is to make is easy for you to customize when the default behavior
doesn't suit you, so try

  import matplotlib.ticker as ticker
  ax.xaxis.set_major_formatter(ticker.FormatStrFormatter('%d'))
  .. and ditto for yaxis ..

in addition to the ticks, you can customize how the coords appear in
the toolbar by setting

  ax.fmt_xdata = ticker.FormatStrFormatter('%d')
  ... and ditto for fmt_ydata

There are a variety of formatters available

  http://matplotlib.sourceforge.net/api/ticker_api.html

JDH
  

Hi John,

Ok, well; the way I use pylab may be a corner case :wink:

However, everyone would be happy if the default format would be consistent :

As it is, *by default*, when <1000 it displays an int and after 1000 it displays 1.42e3.
Why? What do you think this scientific format is a good for?

I understand some users would like to see floats by default.
Some other users would like to see integers by default.

I'm fine with integers or floats by default (I don't cadre) but I don't get the logic of the scientific format.
I only would like to see all the digits of the integer parts.
I would be fine if I would get 1.422e3 instead of 1.42e3 (we could for instance assume that images larger than (100 000, 100 000) are really a corner case ;)).

Why should be the *default* logic so strange?
Ok, it is easy to change but the default should at least make sense.
As it is, I don't think it does...but there could be a good rational I'm missing.

pylab is so easy and fun to use because the default settings are always the best one.
IMHO, there is one exception :frowning:

Xavier

···

On Fri, May 29, 2009 at 10:50 AM, Xavier Gnata <xavier.gnata@...287...> wrote:

Xavier Gnata wrote:

However, everyone would be happy if the default format would be consistent :

As it is, *by default*, when <1000 it displays an int and after 1000 it displays 1.42e3.
Why? What do you think this scientific format is a good for?

I understand some users would like to see floats by default.
Some other users would like to see integers by default.

It is not just a matter of integer versus float; the formatting algorithm must accomodate both.

I'm fine with integers or floats by default (I don't cadre) but I don't get the logic of the scientific format.
I only would like to see all the digits of the integer parts.
I would be fine if I would get 1.422e3 instead of 1.42e3 (we could for instance assume that images larger than (100 000, 100 000) are really a corner case ;)).

Why should be the *default* logic so strange?
Ok, it is easy to change but the default should at least make sense.
As it is, I don't think it does...but there could be a good rational I'm missing.

Right now, the default is very simple:

     def format_data_short(self,value):
         'return a short formatted string representation of a number'
         return '%1.3g'%value

It looks like changing it to something like "%-12g" would facilitate considerable improvement in reducing the jumping around of the numbers, as well as in providing much more precision. I think that 12 is the max number of characters in g conversion. Or maybe it is 13; I might not have tested negative numbers.

The problem is that then it crowds out the other part of the message, the pan/zoom status notification etc.

Breaking the message into two lines almost works (so far only checking with gtkagg), but the plot gets resized depending on whether there is a status or not.

I think that with some more fiddling around with that part of the toolbar--probably including breaking the message up into separate messages for status and readout, and maybe making the readout use two lines and always be present--we could make the readout and status display much nicer. I have never liked the way it jumps around.

Eric

···

pylab is so easy and fun to use because the default settings are always the best one.
IMHO, there is one exception :frowning:

Xavier

------------------------------------------------------------------------------
Register Now for Creativity and Technology (CaT), June 3rd, NYC. CaT is a gathering of tech-side developers & brand creativity professionals. Meet
the minds behind Google Creative Lab, Visual Complexity, Processing, & iPhoneDevCamp as they present alongside digital heavyweights like Barbarian Group, R/GA, & Big Spaceship. http://p.sf.net/sfu/creativitycat-com _______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-users

However, everyone would be happy if the default format would be consistent :

As it is, *by default*, when <1000 it displays an int and after 1000 it displays 1.42e3.
Why? What do you think this scientific format is a good for?

I understand some users would like to see floats by default.
Some other users would like to see integers by default.

It is not just a matter of integer versus float; the formatting algorithm must accomodate both.

I agree.

I'm fine with integers or floats by default (I don't cadre) but I don't get the logic of the scientific format.
I only would like to see all the digits of the integer parts.
I would be fine if I would get 1.422e3 instead of 1.42e3 (we could for instance assume that images larger than (100 000, 100 000) are really a corner case ;)).

Why should be the *default* logic so strange?
Ok, it is easy to change but the default should at least make sense.
As it is, I don't think it does...but there could be a good rational I'm missing.

Right now, the default is very simple:

    def format_data_short(self,value):
        'return a short formatted string representation of a number'
        return '%1.3g'%value

It looks like changing it to something like "%-12g" would facilitate considerable improvement in reducing the jumping around of the numbers, as well as in providing much more precision. I think that 12 is the max number of characters in g conversion. Or maybe it is 13; I might not have tested negative numbers.

The problem is that then it crowds out the other part of the message, the pan/zoom status notification etc.

Breaking the message into two lines almost works (so far only checking with gtkagg), but the plot gets resized depending on whether there is a status or not.

I think that with some more fiddling around with that part of the toolbar--probably including breaking the message up into separate messages for status and readout, and maybe making the readout use two lines and always be present--we could make the readout and status display much nicer. I have never liked the way it jumps around.

I also agree.
However, I would like to be sure I understand one point correctly:
As long as x<1000, the default format *is* an integer (at least when imshow(M) is used).
Fine for me. Why do we need to move to another *default* format for numbers larger than 1000?

Anyhow, I think that we should at least always display all the digits of the integer part of the coordinates.

BTW, ax.xaxis.set_major_formatter(ticker.FormatStrFormatter('%d')) is fine but it prevents you to do a simple imshow(M) to look at your data. You have to create ax. Easy...yes...but not as simple/nice as the one-liner imhow(M)

Xavier

···

Eric

pylab is so easy and fun to use because the default settings are always the best one.
IMHO, there is one exception :frowning:

Xavier

------------------------------------------------------------------------------

Register Now for Creativity and Technology (CaT), June 3rd, NYC. CaT is a gathering of tech-side developers & brand creativity professionals. Meet
the minds behind Google Creative Lab, Visual Complexity, Processing, & iPhoneDevCamp as they present alongside digital heavyweights like Barbarian Group, R/GA, & Big Spaceship. http://p.sf.net/sfu/creativitycat-com _______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-users

Xavier Gnata wrote:

Right now, the default is very simple:

    def format_data_short(self,value):
        'return a short formatted string representation of a number'
        return '%1.3g'%value

It looks like changing it to something like "%-12g" would facilitate considerable improvement in reducing the jumping around of the numbers, as well as in providing much more precision. I think that 12 is the max number of characters in g conversion. Or maybe it is 13; I might not have tested negative numbers.

The problem is that then it crowds out the other part of the message, the pan/zoom status notification etc.

Breaking the message into two lines almost works (so far only checking with gtkagg), but the plot gets resized depending on whether there is a status or not.

I think that with some more fiddling around with that part of the toolbar--probably including breaking the message up into separate messages for status and readout, and maybe making the readout use two lines and always be present--we could make the readout and status display much nicer. I have never liked the way it jumps around.

I also agree.
However, I would like to be sure I understand one point correctly:
As long as x<1000, the default format *is* an integer (at least when imshow(M) is used).

No. Try

imshow(rand(4,4))

There is nothing special about imshow that makes the cursor readout an integer, nor should there be.

Again, the present default is "%1.3g". I think we can and will do better, but it is not necessarily trivial.

Eric

Eric Firing wrote:

Xavier Gnata wrote:

Right now, the default is very simple:

    def format_data_short(self,value):
        'return a short formatted string representation of a number'
        return '%1.3g'%value

It looks like changing it to something like "%-12g" would facilitate considerable improvement in reducing the jumping around of the numbers, as well as in providing much more precision. I think that 12 is the max number of characters in g conversion. Or maybe it is 13; I might not have tested negative numbers.

The problem is that then it crowds out the other part of the message, the pan/zoom status notification etc.

Breaking the message into two lines almost works (so far only checking with gtkagg), but the plot gets resized depending on whether there is a status or not.

I think that with some more fiddling around with that part of the toolbar--probably including breaking the message up into separate messages for status and readout, and maybe making the readout use two lines and always be present--we could make the readout and status display much nicer. I have never liked the way it jumps around.

I also agree.
However, I would like to be sure I understand one point correctly:
As long as x<1000, the default format *is* an integer (at least when imshow(M) is used).

No. Try

imshow(rand(4,4))

There is nothing special about imshow that makes the cursor readout an integer, nor should there be.

Again, the present default is "%1.3g". I think we can and will do better, but it is not necessarily trivial.

Eric

ok. My bad! Sorry.
I have changed the default to %1.4g so that is matches my usecases *but* I agree that correct way to improve it in not that trivial...

Xavier

You can control the point at which mpl falls over to scientific
notation. From the matplotlibrc file (see
http://matplotlib.sourceforge.net/users/customizing.html)

axes.formatter.limits : -7, 7 # use scientific notation if log10
                               # of the axis range is smaller than the
                               # first or larger than the second

I'm actually surprised you are seeing problems with images of
1000x1000 -- it makes me suspect you have an older matplotlib version
or an older matplotlibrc laying around because at -7,7, which is the
current default, you should not see exponential formatting until you
get to much larger sizes.

JDH

···

On Sat, May 30, 2009 at 2:49 AM, Xavier Gnata <xavier.gnata@...287...> wrote:

ok. My bad! Sorry.
I have changed the default to %1.4g so that is matches my usecases *but* I
agree that correct way to improve it in not that trivial...

John Hunter wrote:

···

On Sat, May 30, 2009 at 2:49 AM, Xavier Gnata <xavier.gnata@...287...> wrote:

ok. My bad! Sorry.
I have changed the default to %1.4g so that is matches my usecases *but* I
agree that correct way to improve it in not that trivial...

You can control the point at which mpl falls over to scientific
notation. From the matplotlibrc file (see
http://matplotlib.sourceforge.net/users/customizing.html)

axes.formatter.limits : -7, 7 # use scientific notation if log10
                               # of the axis range is smaller than the
                               # first or larger than the second

I'm actually surprised you are seeing problems with images of
1000x1000 -- it makes me suspect you have an older matplotlib version
or an older matplotlibrc laying around because at -7,7, which is the
current default, you should not see exponential formatting until you
get to much larger sizes.

JDH

John,

No, that applies to the axis ticks but not to the readout, and I think it is the latter that Xavier is concerned with--at least that is what I have been talking about, and want to improve.

Eric

Just to clarify -- by "readout" do you mean the toolbar strings?

At first I was assuming that since the toolbar formatting picks up the
tick Formatter to format the strings, and ScalarFormatter uses
rcParams['axes.formatter.limits'] to determine when to fall over to
scientific notation, that this setting would be picked up by the
toolbar. The reason it does not is because ScalarFormatter overrides
Formatter.format_data_short, which is what the toolbar uses via
Axes.format_xdata/format_ydata, and ScalarFormatter.format_data_short
does not use the formatter.limits setting. Are we at least on the
same page now? If so, is it advisable/possible to make
format_data_short respect the formatter.limits setting so Xavier can
customize it to his heart's content.

JDH

···

On Sat, May 30, 2009 at 11:52 AM, Eric Firing <efiring@...202...> wrote:

No, that applies to the axis ticks but not to the readout, and I think it is
the latter that Xavier is concerned with--at least that is what I have been
talking about, and want to improve.

John Hunter wrote:

···

On Sat, May 30, 2009 at 11:52 AM, Eric Firing <efiring@...202...> wrote:

No, that applies to the axis ticks but not to the readout, and I think it is
the latter that Xavier is concerned with--at least that is what I have been
talking about, and want to improve.
    
Just to clarify -- by "readout" do you mean the toolbar strings?

At first I was assuming that since the toolbar formatting picks up the
tick Formatter to format the strings, and ScalarFormatter uses
rcParams['axes.formatter.limits'] to determine when to fall over to
scientific notation, that this setting would be picked up by the
toolbar. The reason it does not is because ScalarFormatter overrides
Formatter.format_data_short, which is what the toolbar uses via
Axes.format_xdata/format_ydata, and ScalarFormatter.format_data_short
does not use the formatter.limits setting. Are we at least on the
same page now? If so, is it advisable/possible to make
format_data_short respect the formatter.limits setting so Xavier can
customize it to his heart's content.

JDH
  

...and this way my brain and my heart would be fully satisfied :slight_smile:
Please perform this change :wink:

Xavier

John Hunter wrote:

No, that applies to the axis ticks but not to the readout, and I think it is
the latter that Xavier is concerned with--at least that is what I have been
talking about, and want to improve.

Just to clarify -- by "readout" do you mean the toolbar strings?

At first I was assuming that since the toolbar formatting picks up the
tick Formatter to format the strings, and ScalarFormatter uses
rcParams['axes.formatter.limits'] to determine when to fall over to
scientific notation, that this setting would be picked up by the
toolbar. The reason it does not is because ScalarFormatter overrides
Formatter.format_data_short, which is what the toolbar uses via
Axes.format_xdata/format_ydata, and ScalarFormatter.format_data_short
does not use the formatter.limits setting. Are we at least on the
same page now? If so, is it advisable/possible to make
format_data_short respect the formatter.limits setting so Xavier can
customize it to his heart's content.

Possible, but I think there is a much better solution along the lines I suggested earlier. I have it partly implemented. To really do it right will require a little bit of work on all the interactive backends; it might be very little and very easy. It prompted my question starting another thread as to whether we can drop support for GTK < 2.4 so as to simplify that backend.

Eric

···

On Sat, May 30, 2009 at 11:52 AM, Eric Firing <efiring@...202...> wrote:

JDH

------------------------------------------------------------------------------
Register Now for Creativity and Technology (CaT), June 3rd, NYC. CaT is a gathering of tech-side developers & brand creativity professionals. Meet
the minds behind Google Creative Lab, Visual Complexity, Processing, & iPhoneDevCamp as they present alongside digital heavyweights like Barbarian Group, R/GA, & Big Spaceship. http://p.sf.net/sfu/creativitycat-com _______________________________________________
Matplotlib-users mailing list
Matplotlib-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-users

Sorry I forgot to answer -- I answered you in my mind <wink>. While I
am never in favor of dropping support for l packages just because they
are old, if they are impeding adding good functionality because it is
too difficult to code/test against too many interfaces, then by all
means yes, we can drop <2.4. I thnk we could safely drop <2.6.

JDH

···

On Sat, May 30, 2009 at 6:46 PM, Eric Firing <efiring@...202...> wrote:

Possible, but I think there is a much better solution along the lines I
suggested earlier. I have it partly implemented. To really do it right
will require a little bit of work on all the interactive backends; it might
be very little and very easy. It prompted my question starting another
thread as to whether we can drop support for GTK < 2.4 so as to simplify
that backend.

John Hunter wrote:

···

On Sat, May 30, 2009 at 6:46 PM, Eric Firing <efiring@...202...> wrote:

Possible, but I think there is a much better solution along the lines I
suggested earlier. I have it partly implemented. To really do it right
will require a little bit of work on all the interactive backends; it might
be very little and very easy. It prompted my question starting another
thread as to whether we can drop support for GTK < 2.4 so as to simplify
that backend.
    
Sorry I forgot to answer -- I answered you in my mind <wink>. While I
am never in favor of dropping support for l packages just because they
are old, if they are impeding adding good functionality because it is
too difficult to code/test against too many interfaces, then by all
means yes, we can drop <2.4. I thnk we could safely drop <2.6.

JDH
  
Please do so.

Xavier

ok. My bad! Sorry.
I have changed the default to %1.4g so that is matches my usecases *but* I
agree that correct way to improve it in not that trivial...
    
You can control the point at which mpl falls over to scientific
notation. From the matplotlibrc file (see
http://matplotlib.sourceforge.net/users/customizing.html)

axes.formatter.limits : -7, 7 # use scientific notation if log10
                               # of the axis range is smaller than the
                               # first or larger than the second

I'm actually surprised you are seeing problems with images of
1000x1000 -- it makes me suspect you have an older matplotlib version
or an older matplotlibrc laying around because at -7,7, which is the
current default, you should not see exponential formatting until you
get to much larger sizes.

JDH
  

I have uncommented the "axes.formatter.limits : -7, 7" line in my matplotlibrc.
If have have understood the conclusion of this thread correctly, it should be taken info account quite soon, isn't it?

Xavier

Xavier Gnata wrote:

ok. My bad! Sorry.
I have changed the default to %1.4g so that is matches my usecases *but* I
agree that correct way to improve it in not that trivial...
    
You can control the point at which mpl falls over to scientific
notation. From the matplotlibrc file (see
http://matplotlib.sourceforge.net/users/customizing.html)

axes.formatter.limits : -7, 7 # use scientific notation if log10
                               # of the axis range is smaller than the
                               # first or larger than the second

I'm actually surprised you are seeing problems with images of
1000x1000 -- it makes me suspect you have an older matplotlib version
or an older matplotlibrc laying around because at -7,7, which is the
current default, you should not see exponential formatting until you
get to much larger sizes.

JDH
  

I have uncommented the "axes.formatter.limits : -7, 7" line in my matplotlibrc.
If have have understood the conclusion of this thread correctly, it should be taken info account quite soon, isn't it?

It already *is* taken into account--just not where you want it to be. And I don't think it *should* be taken into account there. It is used for the *tick labels*. I don't think that locking the formatting of these to the *cursor readout* is the right thing to do. The solution to your problem involves improving the latter with *no change* to the former.

I have just now committed a small change set that I think you will find sufficient improvement for the present, and that I hope no one else will find objectionable; but we will have to see how that turns out. It is possible that it will not play well on some backends/dpi/whatever, or under some other circumstances.

As noted in the commit message, doing this right requires some changes in all the interactive backends.

Eric

···

Xavier

Eric Firing wrote:

Xavier Gnata wrote:

ok. My bad! Sorry.
I have changed the default to %1.4g so that is matches my usecases *but* I
agree that correct way to improve it in not that trivial...
    
You can control the point at which mpl falls over to scientific
notation. From the matplotlibrc file (see
http://matplotlib.sourceforge.net/users/customizing.html)

axes.formatter.limits : -7, 7 # use scientific notation if log10
                               # of the axis range is smaller than the
                               # first or larger than the second

I'm actually surprised you are seeing problems with images of
1000x1000 -- it makes me suspect you have an older matplotlib version
or an older matplotlibrc laying around because at -7,7, which is the
current default, you should not see exponential formatting until you
get to much larger sizes.

JDH
  

I have uncommented the "axes.formatter.limits : -7, 7" line in my matplotlibrc.
If have have understood the conclusion of this thread correctly, it should be taken info account quite soon, isn't it?

It already *is* taken into account--just not where you want it to be. And I don't think it *should* be taken into account there. It is used for the *tick labels*. I don't think that locking the formatting of these to the *cursor readout* is the right thing to do. The solution to your problem involves improving the latter with *no change* to the former.

I have just now committed a small change set that I think you will find sufficient improvement for the present, and that I hope no one else will find objectionable; but we will have to see how that turns out. It is possible that it will not play well on some backends/dpi/whatever, or under some other circumstances.

As noted in the commit message, doing this right requires some changes in all the interactive backends.

Eric

Ok. Sorry for the conclusion.
Your small change is sufficient for my usecase :).
Thanks. I fully agree with you on the right way to really fix that problem;
I think pylab is great also because I always get feedback on this mailing list.

Xavier