From 08b7821d6ba2ee5f92e0b5b0735f9c5e6d201a22 Mon Sep 17 00:00:00 2001 From: Matthijs Kooijman Date: Tue, 28 Jul 2015 18:40:05 +0200 Subject: [PATCH] Reduce AutoDateFormatter precision when possible Previously, the AutoDateFormatter would choose a format with second or microsecond precision, even when the ticks were significantly coarser than that. The resulting extra precision looks weird and can clutter the display (especially with the long microsecond display). This commit changes the default scale to format dictionary, which now works as follows: - Use microsecond precision when the ticks are less than a second apart - Use second precision when the ticks are seconds apart - Use minute precision when the ticks are minutes or hours apart - Use day-precision, month or year precision when the ticks are days or more apart (unchanged). Note that there is no point in displaying only the hour when the ticks are hours apart, since then it won't be immediately clear that a time is being displayed. Adding the (technically superfluous) :00 for the minutes should make it immediately obvious that a time is being displayed, which is why the minute precision should also be used when the ticks are hours apart. While updating the documentation for this change, it was also changed to use symbolic constants instead of hardcoded numbers. This should make it more clear what the intention is. Closes: #4808 --- lib/matplotlib/dates.py | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/lib/matplotlib/dates.py b/lib/matplotlib/dates.py index d001fe450e8d..e6af7a5fe74e 100755 --- a/lib/matplotlib/dates.py +++ b/lib/matplotlib/dates.py @@ -629,13 +629,13 @@ class AutoDateFormatter(ticker.Formatter): format string. The default looks like this:: self.scaled = { - 365.0 : '%Y', - 30. : '%b %Y', - 1.0 : '%b %d %Y', - 1./24. : '%H:%M:%S', - 1. / (24. * 60.): '%H:%M:%S.%f', - } - + DAYS_PER_YEAR : '%Y', + DAYS_PER_MONTH : '%b %Y', + 1.0 : '%b %d %Y', + 1. / HOURS_PER_DAY : '%H:%M', + 1. / SEC_PER_DAY : '%H:%M:%S', + 1. / MUSECONDS_PER_DAY : '%H:%M:%S.%f' + } The algorithm picks the key in the dictionary that is >= the current scale and uses that format string. You can customize this @@ -688,8 +688,9 @@ def __init__(self, locator, tz=None, defaultfmt='%Y-%m-%d'): self.scaled = {DAYS_PER_YEAR: '%Y', DAYS_PER_MONTH: '%b %Y', 1.0: '%b %d %Y', - 1. / HOURS_PER_DAY: '%H:%M:%S', - 1. / (MINUTES_PER_DAY): '%H:%M:%S.%f'} + 1. / HOURS_PER_DAY: '%H:%M', + 1. / SEC_PER_DAY: '%H:%M:%S', + 1. / MUSECONDS_PER_DAY: '%H:%M:%S.%f'} def __call__(self, x, pos=None): locator_unit_scale = float(self._locator._get_unit())