subclassing AutoDateFormatter correctly

How can I correctly subclass AutoDateFormatter and use it in my code?

What I am doing is copying the code from matplotlib’s AutoDateFormatter and changing the strings for how the dates are represented and making that a class, MyAutoDateFormatter. AutoDateFormatter expects a locator, and I think (?) the default is AutoDateLocator. So in my code I am doing this:

    adl = AutoDateLocator()
    myformatter = MyAutoDateFormatter(adl)
    axis.xaxis.set_major_formatter(myformatter)

But when I run it, no matter the level of zoom, it says “2010” (when it should change depending on zoom level).

However, if I go into the matplotlib dates.py code itself and save the same changes to the date strings there, and I comment out the above code, then it works: the date strings change depending on level of zoom.

I could just leave it changed in mpl’s dates.py module, but I’d rather subclass AutoDateFormatter so that if I share the source code of my app with others, it will get this right.

What am I doing wrong?

Thanks, and any help appreciated as always.

Che

I’ve also just noticed that if I use the above code after the lines have been plotted, but then I click on one of the points (which causes a point-picking routine that ultimately plots a highlighting marker over that point), the x axis suddenly changes to use MyAutoDateFormatter’s format strings. (If I call it before I plot anything, it doesn’t help, though).

Is the act of plotting somehow “refreshing” things? What can I call in order to force this to happen without actually plotting any additional points after my lines are plotted?

Thanks,
Che

···

On Sun, Nov 28, 2010 at 8:52 PM, C M <cmpython@…287…> wrote:

How can I correctly subclass AutoDateFormatter and use it in my code?

What I am doing is copying the code from matplotlib’s AutoDateFormatter and changing the strings for how the dates are represented and making that a class, MyAutoDateFormatter. AutoDateFormatter expects a locator, and I think (?) the default is AutoDateLocator. So in my code I am doing this:

    adl = AutoDateLocator()
    myformatter = MyAutoDateFormatter(adl)
    axis.xaxis.set_major_formatter(myformatter)

But when I run it, no matter the level of zoom, it says “2010” (when it should change depending on zoom level).

However, if I go into the matplotlib dates.py code itself and save the same changes to the date strings there, and I comment out the above code, then it works: the date strings change depending on level of zoom.

It's difficult to tell without seeing the code that's producing the
problem. If you can boil your problem down to a simple, self-contained
script and post it here, then we can take a look and see what's going
on.

Ryan

···

On Tue, Nov 30, 2010 at 10:44 AM, C M <cmpython@...287...> wrote:

On Sun, Nov 28, 2010 at 8:52 PM, C M <cmpython@...287...> wrote:

How can I correctly subclass AutoDateFormatter and use it in my code?

What I am doing is copying the code from matplotlib's AutoDateFormatter
and changing the strings for how the dates are represented and making that a
class, MyAutoDateFormatter. AutoDateFormatter expects a locator, and I
think (?) the default is AutoDateLocator. So in my code I am doing this:

    adl = AutoDateLocator\(\)
    myformatter = MyAutoDateFormatter\(adl\)
    axis\.xaxis\.set\_major\_formatter\(myformatter\)

But when I run it, no matter the level of zoom, it says "2010" (when it
should change depending on zoom level).

However, if I go into the matplotlib dates.py code itself and save the
same changes to the date strings there, and I comment out the above code,
then it works: the date strings change depending on level of zoom.

I've also just noticed that if I use the above code after the lines have
been plotted, but then I click on one of the points (which causes a
point-picking routine that ultimately plots a highlighting marker over that
point), the x axis suddenly changes to use MyAutoDateFormatter's format
strings. (If I call it before I plot anything, it doesn't help, though).

Is the act of plotting somehow "refreshing" things? What can I call in
order to force this to happen without actually plotting any additional
points after my lines are plotted?

--
Ryan May
Graduate Research Assistant
School of Meteorology
University of Oklahoma

Thanks, Ryan. I’ve done that now. I use the OOP approach to matplotlib and embed it in wxPython, so my example uses that. I did not know how to apply an AutoDateFormatter to an axis if using pylab and figured the basics of what I am trying to do are apparent from this sample.

The sample is attached. The point of it is that, despite it apparently using my AutoDateFormatter, all the dates at all levels of zoom are %Y (e.g. “2010”). This is because in the AutoDateFormatter subclass, the line:

scale = float( self._locator._get_unit() )

is always returning 365.0.

I am not bothering for now to include the business about how point-picking remedies my problem, because the AutoDateFormatter shouldn’t need that–obviously, the way I am doing it is wrong, and I’d like to know what it is.

Thanks for any help,
Che

plot_test.py (3.07 KB)

···

On Tue, Nov 30, 2010 at 12:23 PM, Ryan May <rmay31@…287…> wrote:

On Tue, Nov 30, 2010 at 10:44 AM, C M <cmpython@…287…> wrote:

On Sun, Nov 28, 2010 at 8:52 PM, C M <cmpython@…287…> wrote:

How can I correctly subclass AutoDateFormatter and use it in my code?

What I am doing is copying the code from matplotlib’s AutoDateFormatter

and changing the strings for how the dates are represented and making that a

class, MyAutoDateFormatter. AutoDateFormatter expects a locator, and I

think (?) the default is AutoDateLocator. So in my code I am doing this:

    adl = AutoDateLocator()
    myformatter = MyAutoDateFormatter(adl)
    axis.xaxis.set_major_formatter(myformatter)

But when I run it, no matter the level of zoom, it says “2010” (when it

should change depending on zoom level).

However, if I go into the matplotlib dates.py code itself and save the

same changes to the date strings there, and I comment out the above code,

then it works: the date strings change depending on level of zoom.

I’ve also just noticed that if I use the above code after the lines have

been plotted, but then I click on one of the points (which causes a

point-picking routine that ultimately plots a highlighting marker over that

point), the x axis suddenly changes to use MyAutoDateFormatter’s format

strings. (If I call it before I plot anything, it doesn’t help, though).

Is the act of plotting somehow “refreshing” things? What can I call in

order to force this to happen without actually plotting any additional

points after my lines are plotted?

It’s difficult to tell without seeing the code that’s producing the

problem. If you can boil your problem down to a simple, self-contained

script and post it here, then we can take a look and see what’s going

on.

I'm guessing your problem was that only the year was being shown,
regardless? It would seem the problem stems from the fact that while
you give your formatter the AutoDateLocator, you never tell the axis
to use this. I got what I considered the correct behavior by adding
the following line at linen 84 in the script:

       self.subplot.xaxis.set_major_locator(adl)

Does adding that get you what you want?

Ryan

···

On Tue, Nov 30, 2010 at 7:00 PM, C M <cmpython@...287...> wrote:

Thanks, Ryan. I've done that now. I use the OOP approach to matplotlib and
embed it in wxPython, so my example uses that. I did not know how to apply
an AutoDateFormatter to an axis if using pylab and figured the basics of
what I am trying to do are apparent from this sample.

The sample is attached. The point of it is that, despite it apparently
using my AutoDateFormatter, all the dates at all levels of zoom are %Y (e.g.
"2010"). This is because in the AutoDateFormatter subclass, the line:

scale = float( self._locator._get_unit() )

is *always* returning 365.0.

I am not bothering for now to include the business about how point-picking
remedies my problem, because the AutoDateFormatter shouldn't need
that--obviously, the way I am doing it is wrong, and I'd like to know what
it is.

--
Ryan May
Graduate Research Assistant
School of Meteorology
University of Oklahoma

Yes, that was it! So simple, but I’ve been confused about how locators and formatters work together–now it makes much more sense. Thank you very much.

Che

···

On Wed, Dec 1, 2010 at 12:28 AM, Ryan May <rmay31@…1896…> wrote:

On Tue, Nov 30, 2010 at 7:00 PM, C M <cmpython@…287…> wrote:

Thanks, Ryan. I’ve done that now. I use the OOP approach to matplotlib and

embed it in wxPython, so my example uses that. I did not know how to apply

an AutoDateFormatter to an axis if using pylab and figured the basics of

what I am trying to do are apparent from this sample.

The sample is attached. The point of it is that, despite it apparently

using my AutoDateFormatter, all the dates at all levels of zoom are %Y (e.g.

“2010”). This is because in the AutoDateFormatter subclass, the line:

scale = float( self._locator._get_unit() )

is always returning 365.0.

I am not bothering for now to include the business about how point-picking

remedies my problem, because the AutoDateFormatter shouldn’t need

that–obviously, the way I am doing it is wrong, and I’d like to know what

it is.

I’m guessing your problem was that only the year was being shown,

regardless? It would seem the problem stems from the fact that while

you give your formatter the AutoDateLocator, you never tell the axis

to use this. I got what I considered the correct behavior by adding

the following line at linen 84 in the script:

   self.subplot.xaxis.set_major_locator(adl)

Does adding that get you what you want?

Ryan