tweaking automatic date formatting?

Hi, I've asked this before but still am stuck. I want to use
mpl's automatic tick locating and date formatting for a zoomable
date plot, OTHER THAN the hour formatting. The default hour formatting
(when zoomed in on 1 day) is like "05:00:00 UTC", but I'd like to be
of the form something more readable for users, like: "5:00pm 12/03".

If I just use my own custom date formatter, then ALL the zoom levels
will have this format, but I'd only like it for when the plot is zoomed
down to the level of one day. (So it is a rule of "if zoomed to one day,
use my custom dateformatter, otherwise, use the automatic one").

Why I'd like this: for looking across weeks or months worth of data,
hours are irrelevant, but for looking at days, hours are relevant, but
users will not think in terms of UTC and they will want to see on the
x axis which day they are looking at.

Does anyone know how this can be done in mpl? Thank you,
Che

I don’t think matplotlib supports anything like this out of the box. However, you should be able to do this by subclassing the Formatter class in matplotlib/ticker.py. I believe Chaco has support for ticking like this for dates, so you could look to it for inspiration on how to go about implementing the concept.

Ryan

···

On Mon, Apr 13, 2009 at 5:34 PM, C M <cmpython@…287…> wrote:

Hi, I’ve asked this before but still am stuck. I want to use

mpl’s automatic tick locating and date formatting for a zoomable

date plot, OTHER THAN the hour formatting. The default hour formatting

(when zoomed in on 1 day) is like “05:00:00 UTC”, but I’d like to be

of the form something more readable for users, like: “5:00pm 12/03”.

If I just use my own custom date formatter, then ALL the zoom levels

will have this format, but I’d only like it for when the plot is zoomed

down to the level of one day. (So it is a rule of "if zoomed to one day,

use my custom dateformatter, otherwise, use the automatic one").

Why I’d like this: for looking across weeks or months worth of data,

hours are irrelevant, but for looking at days, hours are relevant, but

users will not think in terms of UTC and they will want to see on the

x axis which day they are looking at.

Does anyone know how this can be done in mpl? Thank you,


Ryan May
Graduate Research Assistant
School of Meteorology
University of Oklahoma

Here is the code for the autodateformatter (scale is in days).
Perhaps you can just tweak it to work like you want and then set you
custom formatter with

  ax.xaxis.set_major_formatter(myformatter)

   class AutoDateFormatter(ticker.Formatter):
       """
       This class attempts to figure out the best format to use. This is
       most useful when used with the :class:`AutoDateLocator`.
       """

       # This can be improved by providing some user-level direction on
       # how to choose the best format (precedence, etc...)

       # Perhaps a 'struct' that has a field for each time-type where a
       # zero would indicate "don't show" and a number would indicate
       # "show" with some sort of priority. Same priorities could mean
       # show all with the same priority.

       # Or more simply, perhaps just a format string for each
       # possibility...

       def __init__(self, locator, tz=None):
           self._locator = locator
              self._formatter = DateFormatter("%b %d %Y %H:%M:%S %Z", tz)
              self._tz = tz

          def __call__(self, x, pos=0):
              scale = float( self._locator._get_unit() )

              if ( scale == 365.0 ):
                  self._formatter = DateFormatter("%Y", self._tz)
              elif ( scale == 30.0 ):
                  self._formatter = DateFormatter("%b %Y", self._tz)
              elif ( (scale == 1.0) or (scale == 7.0) ):
                  self._formatter = DateFormatter("%b %d %Y", self._tz)
              elif ( scale == (1.0/24.0) ):
                  self._formatter = DateFormatter("%H:%M:%S %Z", self._tz)
              elif ( scale == (1.0/(24*60)) ):
                  self._formatter = DateFormatter("%H:%M:%S %Z", self._tz)
              elif ( scale == (1.0/(24*3600)) ):
                  self._formatter = DateFormatter("%H:%M:%S %Z", self._tz)
              else:
                  self._formatter = DateFormatter("%b %d %Y %H:%M:%S
%Z", self._tz)

           return self._formatter(x, pos)

JDH

···

On Tue, Apr 14, 2009 at 8:34 AM, Ryan May <rmay31@...287...> wrote:

I don't think matplotlib supports anything like this out of the box.
However, you should be able to do this by subclassing the Formatter class in
matplotlib/ticker.py. I believe Chaco has support for ticking like this for
dates, so you could look to it for inspiration on how to go about
implementing the concept.

Thanks, Ryan, John, and Pierre... I will try to change it at the
point John suggests, maybe inspired by scikits.timeseries
(or just using it).

btw, I think adding the ability to set the AutoDateFormat
formatting choices per scale would be a good small addition
to mpl. (Maybe that is what the commented lines in the
class are about, but I don't quite understand them). Methods
like .set_dayscale_format, .set_weekscale_format, etc.

Thanks,
Che