Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Bug : (minor) time axis labels show "%f" instead of microseconds for years up to 1900 #3179

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
azjps opened this issue Jul 2, 2014 · 2 comments · Fixed by #3242
Closed

Comments

@azjps
Copy link
Contributor

azjps commented Jul 2, 2014

When plotting with a timestamp-based axis with datetimes of years <= 1900, upon zooming into sub-second scales, the default axis label date formatter shows "%f" instead of microseconds.

In [52]: import time, datetime, matplotlib.dates as mdates

In [53]: dt = mdates.date2num(datetime.datetime(1900, 1, 1, 10, 0))

In [54]: mdates.DateFormatter("%H:%M:%S.%f")(dt)
Out[54]: u'10:00:00.%f'

In [55]: time.strftime("%H:%M:%S.%f", (2000,) + mdates.num2date(dt).timetuple()[1:])
Out[55]: '10:00:00.%f'

This is since timetuple doesn't carry microsecond data. Minor in nature (was using a sentinel date of 1900 without realizing matplotlib would handle it specially) but I figured I would point it out.

@azjps azjps changed the title Bug : (minor) time.strftime doesn't carry microseconds Bug : (minor) time axis labels show "%f" instead of microseconds for years <= 1900 Jul 2, 2014
@azjps azjps changed the title Bug : (minor) time axis labels show "%f" instead of microseconds for years <= 1900 Bug : (minor) time axis labels show "%f" instead of microseconds for years upto 1900 Jul 2, 2014
@azjps azjps changed the title Bug : (minor) time axis labels show "%f" instead of microseconds for years upto 1900 Bug : (minor) time axis labels show "%f" instead of microseconds for years up to 1900 Jul 2, 2014
@pelson
Copy link
Member

pelson commented Jul 2, 2014

Good spot @azjps, and thanks for making it easy to reproduce. Are you interested in having a go at implementing a fix for this?

@azjps
Copy link
Contributor Author

azjps commented Jul 2, 2014

Sure :) It seems to me that these three lines in dates.DateFormatter.strftime:

timetuple = dt.timetuple()
s1 = time.strftime(fmt, (year,) + timetuple[1:])
s2 = time.strftime(fmt, (year + 28,) + timetuple[1:])

could be replaced by

s1 = dt.replace(year=year).strftime(fmt)
s2 = dt.replace(year=year+28).strftime(fmt)

although someone should check that setting to this year in a datetime object will not somehow re-introduce the year before 1900 issue that dates.DateFormatter.stftime was trying to resolve. It seems the updated year value indeed is between 1973 and 2000. I'll submit a pull request in a bit.

azjps added a commit to azjps/matplotlib that referenced this issue Jul 3, 2014
@tacaswell tacaswell modified the milestones: v1.4.0, v1.4.x Jul 12, 2014
@tacaswell tacaswell modified the milestones: 1.5.0, v1.4.x Feb 7, 2015
azjps added a commit to azjps/matplotlib that referenced this issue Feb 24, 2015
Add a simple test for DateFormatter.

closes matplotlib#3179

Change-Id: Idff9d06cbc6dc00a3cb8dcf113983d82dbdd3fde
azjps added a commit to azjps/matplotlib that referenced this issue Feb 25, 2015
It also fails to replace %y or %x correctly, since
its strftime implementation replaces only 4-digit years.

I added a boolean flag DateFormatter.replace_directives_before_1900:
- If False, strftime uses the old implementation, which will
not replace %f and which will replace incorrect values for %y and %x.
- If True, strftime will first try a few regular expressions
to replace %y/%x/%f with the appropriate datetime values. I'm
not positive this covers all cases but I don't know of any cases
where this fails right now.

Add a simple test for DateFormatter with and without this flag.

closes matplotlib#3179

Change-Id: Idff9d06cbc6dc00a3cb8dcf113983d82dbdd3fde
azjps added a commit to azjps/matplotlib that referenced this issue May 25, 2015
It also fails to replace %y or %x correctly, since
its strftime implementation replaces only 4-digit years.

Instead, we now use a regular expression to replace %f
with the microsecond value. (We could also be tricky and
call strftime again with the original datetime object ..)
We also make substitutions for both 2-digit and 4-digit
years, which for example are displayed by %y, %Y, and %x.

Minor point: in time.h, strftime will not use padding for
%y and %Y but will use zero-padding for %x. Since this is
unlikely to ever be a cause of concern and isn't documented
anywhere afaik, I've used zero-padding for all three.
(Certainly it's preferable to just printing the wrong year!)

Add tests and (maybe excessively long?) comments.

closes matplotlib#3179

Change-Id: Idff9d06cbc6dc00a3cb8dcf113983d82dbdd3fde
azjps added a commit to azjps/matplotlib that referenced this issue May 27, 2015
It also fails to replace %y or %x correctly, since
its strftime implementation replaces only 4-digit years.

Instead, we now use a regular expression to replace %f
with the microsecond value. (We could also be tricky and
call strftime again with the original datetime object ..)
We also make substitutions for both 2-digit and 4-digit
years, which for example are displayed by %y, %Y, and %x.

Minor point: in time.h, strftime will not use padding for
%y and %Y but will use zero-padding for %x. Since this is
unlikely to ever be a cause of concern and isn't documented
anywhere afaik, I've used zero-padding for all three.
(Certainly it's preferable to just printing the wrong year!)

Add tests and (maybe excessively long?) comments.

closes matplotlib#3179

Change-Id: Idff9d06cbc6dc00a3cb8dcf113983d82dbdd3fde
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants