From: C M <cmp...@gm...> - 2009-04-13 22:34:12
|
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 |
From: Ryan M. <rm...@gm...> - 2009-04-14 13:43:17
|
On Mon, Apr 13, 2009 at 5:34 PM, C M <cmp...@gm...> 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, 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 -- Ryan May Graduate Research Assistant School of Meteorology University of Oklahoma |
From: John H. <jd...@gm...> - 2009-04-14 14:53:45
|
On Tue, Apr 14, 2009 at 8:34 AM, Ryan May <rm...@gm...> 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. 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 |
From: C M <cmp...@gm...> - 2009-04-15 03:47:10
|
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 |