8000 Supported datetimes with microseconds, and those with long time series (>160 years). by pelson · Pull Request #1925 · matplotlib/matplotlib · GitHub
[go: up one dir, main page]

Skip to content

Supported datetimes with microseconds, and those with long time series (>160 years). #1925

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

Merged
merged 4 commits into from
May 20, 2013
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
PEP8 the dates module.
  • Loading branch information
pelson committed May 14, 2013
commit 5736059ea478f3ec2e7af14a5f6ed1f8dd65b8f9
71 changes: 35 additions & 36 deletions lib/matplotlib/dates.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
and calendar differences can cause confusing differences between what
Python and mpl give as the number of days since 0001-01-01 and what other
software and databases yield. For example, the `US Naval Observatory
<http://www.usno.navy.mil/USNO/astronomical-applications/data-services/jul-date>`_
<http://www.usno.navy.mil/USNO/astronomical-applications/
data-services/jul-date>`_
uses a calendar that switches from Julian to Gregorian in October, 1582.
Hence, using their calculator, the number of days between 0001-01-01 and
2006-04-01 is 732403, whereas using the Gregorian calendar via the datetime
Expand Down Expand Up @@ -115,8 +116,9 @@
import warnings


from dateutil.rrule import rrule, MO, TU, WE, TH, FR, SA, SU, YEARLY, \
MONTHLY, WEEKLY, DAILY, HOURLY, MINUTELY, SECONDLY
from dateutil.rrule import (rrule, MO, TU, WE, TH, FR, SA, SU, YEARLY,
MONTHLY, WEEKLY, DAILY, HOURLY, MINUTELY,
SECONDLY)
from dateutil.relativedelta import relativedelta
import dateutil.parser
import numpy as np
Expand All @@ -134,8 +136,9 @@
'RRuleLocator', 'AutoDateLocator', 'YearLocator',
'MonthLocator', 'WeekdayLocator',
'DayLocator', 'HourLocator', 'MinuteLocator',
'SecondLocator', 'rrule', 'MO', 'TU', 'WE', 'TH', 'FR',
'SA', 'SU', 'YEARLY', 'MONTHLY', 'WEEKLY', 'DAILY',
'SecondLocator', 'MicrosecondLocator',
'rrule', 'MO', 'TU', 'WE', 'TH', 'FR', 'SA', 'SU',
'YEARLY', 'MONTHLY', 'WEEKLY', 'DAILY',
'HOURLY', 'MINUTELY', 'SECONDLY', 'MICROSECONDLY', 'relativedelta',
'seconds', 'minutes', 'hours', 'weeks')

Expand Down Expand Up @@ -468,8 +471,7 @@ class AutoDateFormatter(ticker.Formatter):
30. : '%b %Y',
1.0 : '%b %d %Y',
1./24. : '%H:%M:%D',
1./24. : '%H:%M:%S',
1. / 10 * (24. * 60.): '%H:%M:%S.%f',
1. / (24. * 60.): '%H:%M:%S.%f',
}


Expand Down Expand Up @@ -503,13 +505,11 @@ def __init__(self, locator, tz=None, defaultfmt='%Y-%m-%d'):
self._tz = tz
self.defaultfmt = defaultfmt
self._formatter = DateFormatter(self.defaultfmt, tz)
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',
}
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'}

def __call__(self, x, pos=0):
scale = float(self._locator._get_unit())
Expand Down Expand Up @@ -579,7 +579,7 @@ def _get_interval(self):
def nonsingular(self, vmin, vmax):
"""
Given the proposed upper and lower extent, adjust the range
if it is too close to being singlular (i.e. a range of ~0).
if it is too close to being singular (i.e. a range of ~0).

"""
unit = self._get_unit()
Expand Down Expand Up @@ -713,11 +713,11 @@ def autoscale(self):
class AutoDateLocator(DateLocator):
"""
On autoscale, this class picks the best
:class:`RRuleLocator` to set the view limits and the tick
:class:`DateLocator` to set the view limits and the tick
locations.
"""
def __init__(self, tz=None, minticks=5, maxticks=None,
interval_multiples=False):
interval_multiples=False):
"""
*minticks* is the minimum number of ticks desired, which is used to
select the type of ticking (yearly, monthly, etc.).
Expand All @@ -728,7 +728,7 @@ def __init__(self, tz=None, minticks=5, maxticks=None,
individual rrule frequency constants (YEARLY, MONTHLY, etc.)
to their own maximum number of ticks. This can be used to keep
the number of ticks appropriate to the format chosen in
class:`AutoDateFormatter`. Any frequency not specified in this
:class:`AutoDateFormatter`. Any frequency not specified in this
dictionary is given a default value.

*tz* is a :class:`tzinfo` instance.
Expand Down Expand Up @@ -781,20 +781,19 @@ def __init__(self, tz=None, minticks=5, maxticks=None,
# number of ticks for every frequency and create a
# dictionary for this
self.maxticks = dict(izip(self._freqs,
[maxticks] * len(self._freqs)))
[maxticks] * len(self._freqs)))
self.interval_multiples = interval_multiples
self.intervald = {
YEARLY: [1, 2, 4, 5, 10, 20, 40, 50, 100, 200, 400, 500,
1000, 2000, 4000, 5000, 10000],
MONTHLY: [1, 2, 3, 4, 6],
DAILY: [1, 2, 3, 7, 14],
HOURLY: [1, 2, 3, 4, 6, 12],
MINUTELY: [1, 5, 10, 15, 30],
SECONDLY: [1, 5, 10, 15, 30],
MICROSECONDLY: [1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000,
5000, 10000, 20000, 50000, 100000, 200000, 500000,
1000000],
}
YEARLY: [1, 2, 4, 5, 10, 20, 40, 50, 100, 200, 400, 500,
1000, 2000, 4000, 5000, 10000],
MONTHLY: [1, 2, 3, 4, 6],
DAILY: [1, 2, 3, 7, 14],
HOURLY: [1, 2, 3, 4, 6, 12],
MINUTELY: [1, 5, 10, 15, 30],
SECONDLY: [1, 5, 10, 15, 30],
MICROSECONDLY: [1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000,
5000, 10000, 20000, 50000, 100000, 200000, 500000,
1000000]}
self._byranges = [None, range(1, 13), range(1, 32), range(0, 24),
range(0, 60), range(0, 60), None]

Expand Down Expand Up @@ -822,7 +821,7 @@ def refresh(self):

def _get_unit(self):
if self._freq in [MICROSECONDLY]:
return 1./MUSECONDS_PER_DAY
return 1. / MUSECONDS_PER_DAY
else:
return RRuleLocator.get_unit_generic(self._freq)

Expand All @@ -842,8 +841,7 @@ def get_locator(self, dmin, dmax):
numHours = (numDays * 24.0) + delta.hours
numMinutes = (numHours * 60.0) + delta.minutes
numSeconds = (numMinutes * 60.0) + delta.seconds
numMicroseconds = (numSeconds * 1e6) + \
delta.microseconds
numMicroseconds = (numSeconds * 1e6) + delta.microseconds

nums = [numYears, numMonths, numDays, numHours, numMinutes,
numSeconds, numMicroseconds]
Expand Down Expand Up @@ -1092,12 +1090,13 @@ def __init__(self, bysecond=None, interval=1, tz=None):

class MicrosecondLocator(DateLocator):
"""
Make ticks on occurances of each second.
Make ticks on occurances of each microsecond.

"""
def __init__(self, interval=1, tz=None):
"""
*interval* is the interval between each iteration. For
example, if ``interval=2``, mark every second miscrosecond.
example, if ``interval=2``, mark every second microsecond.

"""
self._interval = interval
Expand Down Expand Up @@ -1129,7 +1128,7 @@ def _get_unit(self):
Return how many days a unit of the locator is; used for
intelligent autoscaling.
"""
return 1./MUSECONDS_PER_DAY
return 1. / MUSECONDS_PER_DAY

def _get_interval(self):
"""
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified lib/matplotlib/tests/baseline_images/test_dates/date_axhline.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified lib/matplotlib/tests/baseline_images/test_dates/date_axhspan.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified lib/matplotlib/tests/baseline_images/test_dates/date_axvline.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified lib/matplotlib/tests/baseline_images/test_dates/date_axvspan.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified lib/matplotlib/tests/baseline_images/test_dates/date_empty.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
19 changes: 7 additions & 12 deletions lib/matplotlib/tests/test_dates.py
12B5
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@
from matplotlib.dates import DayLocator


@image_comparison(baseline_images=['date_empty'], extensions=['png'],
savefig_kwarg={'dpi': 60})
@image_comparison(baseline_images=['date_empty'], extensions=['png'])
def test_date_empty():
# make sure mpl does the right thing when told to plot dates even
# if no date data has been presented, cf
Expand All @@ -24,8 +23,7 @@ def test_date_empty():
ax.xaxis_date()


@image_comparison(baseline_images=['date_axhspan'], extensions=['png'],
savefig_kwarg={'dpi': 60})
@image_comparison(baseline_images=['date_axhspan'], extensions=['png'])
def test_date_axhspan():
# test ax hspan with date inputs
t0 = datetime.datetime(2009, 1, 20)
Expand All @@ -38,8 +36,7 @@ def test_date_axhspan():
fig.subplots_adjust(left=0.25)


@image_comparison(baseline_images=['date_axvspan'], extensions=['png'],
savefig_kwarg={'dpi': 60})
@image_comparison(baseline_images=['date_axvspan'], extensions=['png'])
def test_date_axvspan():
# test ax hspan with date inputs
t0 = datetime.datetime(2000, 1, 20)
Expand All @@ -53,7 +50,7 @@ def test_date_axvspan():


@image_comparison(baseline_images=['date_axhline'],
extensions=['png'], savefig_kwarg={'dpi': 60})
extensions=['png'])
def test_date_axhline():
# test ax hline with date inputs
t0 = datetime.datetime(2009, 1, 20)
Expand All @@ -67,7 +64,7 @@ def test_date_axhline():


@image_comparison(baseline_images=['date_axvline'], tol=16,
extensions=['png'], savefig_kwarg={'dpi': 60})
extensions=['png'])
def test_date_axvline():
# test ax hline with date inputs
t0 = datetime.datetime(2000, 1, 20)
Expand Down Expand Up @@ -104,8 +101,7 @@ def test_too_many_date_ticks():
fig.savefig('junk.png')


@image_comparison(baseline_images=['RRuleLocator_bounds'], extensions=['png'],
savefig_kwarg={'dpi': 60})
@image_comparison(baseline_images=['RRuleLocator_bounds'], extensions=['png'])
def test_RRuleLocator():
import matplotlib.testing.jpl_units as units
units.register()
Expand All @@ -131,7 +127,7 @@ def test_RRuleLocator():


@image_comparison(baseline_images=['DateFormatter_fractionalSeconds'],
extensions=['png'], savefig_kwarg={'dpi': 60})
extensions=['png'])
def test_DateFormatter():
import matplotlib.testing.jpl_units as units
units.register()
Expand Down Expand Up @@ -268,7 +264,6 @@ def _create_auto_date_locator(date1, date2):
expected)



if __name__ == '__main__':
import nose
nose.runmodule(argv=['-s', '--with-doctest'], exit=False)
0