Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 00d71ce

Browse filesBrowse files
authored
Merge pull request #12678 from jklymak/fix-yearlocator-tz
FIX: set tz for YearLocator
2 parents a55909a + d8fcd82 commit 00d71ce
Copy full SHA for 00d71ce

File tree

Expand file treeCollapse file tree

2 files changed

+120
-6
lines changed
Filter options
Expand file treeCollapse file tree

2 files changed

+120
-6
lines changed

‎lib/matplotlib/dates.py

Copy file name to clipboardExpand all lines: lib/matplotlib/dates.py
+23-5Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1415,7 +1415,7 @@ def __init__(self, tz=None, minticks=5, maxticks=None,
14151415
locator.intervald[HOURLY] = [3] # only show every 3 hours
14161416
"""
14171417
DateLocator.__init__(self, tz)
1418-
self._locator = YearLocator()
1418+
self._locator = YearLocator(tz=tz)
14191419
self._freq = YEARLY
14201420
self._freqs = [YEARLY, MONTHLY, DAILY, HOURLY, MINUTELY,
14211421
SECONDLY, MICROSECONDLY]
@@ -1572,7 +1572,7 @@ def get_locator(self, dmin, dmax):
15721572
'AutoDateLocator.')
15731573

15741574
if (freq == YEARLY) and self.interval_multiples:
1575-
locator = YearLocator(interval)
1575+
locator = YearLocator(interval, tz=self.tz)
15761576
elif use_rrule_locator[i]:
15771577
_, bymonth, bymonthday, byhour, byminute, bysecond, _ = byranges
15781578
rrule = rrulewrapper(self._freq, interval=interval,
@@ -1621,8 +1621,11 @@ def __init__(self, base=1, month=1, day=1, tz=None):
16211621
'hour': 0,
16221622
'minute': 0,
16231623
'second': 0,
1624-
'tzinfo': tz
16251624
}
1625+
if not hasattr(tz, 'localize'):
1626+
# if tz is pytz, we need to do this w/ the localize fcn,
1627+
# otherwise datetime.replace works fine...
1628+
self.replaced['tzinfo'] = tz
16261629

16271630
def __call__(self):
16281631
# if no data have been set, this will tank with a ValueError
@@ -1637,13 +1640,26 @@ def tick_values(self, vmin, vmax):
16371640
ymin = self.base.le(vmin.year) * self.base.step
16381641
ymax = self.base.ge(vmax.year) * self.base.step
16391642

1640-
ticks = [vmin.replace(year=ymin, **self.replaced)]
1643+
vmin = vmin.replace(year=ymin, **self.replaced)
1644+
if hasattr(self.tz, 'localize'):
1645+
# look after pytz
1646+
if not vmin.tzinfo:
1647+
vmin = self.tz.localize(vmin, is_dst=True)
1648+
1649+
ticks = [vmin]
1650+
16411651
while True:
16421652
dt = ticks[-1]
16431653
if dt.year >= ymax:
16441654
return date2num(ticks)
16451655
year = dt.year + self.base.step
1646-
ticks.append(dt.replace(year=year, **self.replaced))
1656+
dt = dt.replace(year=year, **self.replaced)
1657+
if hasattr(self.tz, 'localize'):
1658+
# look after pytz
1659+
if not dt.tzinfo:
1660+
dt = self.tz.localize(dt, is_dst=True)
1661+
1662+
ticks.append(dt)
16471663

16481664
def autoscale(self):
16491665
"""
@@ -1654,7 +1670,9 @@ def autoscale(self):
16541670
ymin = self.base.le(dmin.year)
16551671
ymax = self.base.ge(dmax.year)
16561672
vmin = dmin.replace(year=ymin, **self.replaced)
1673+
vmin = vmin.astimezone(self.tz)
16571674
vmax = dmax.replace(year=ymax, **self.replaced)
1675+
vmax = vmax.astimezone(self.tz)
16581676

16591677
vmin = date2num(vmin)
16601678
vmax = date2num(vmax)

‎lib/matplotlib/tests/test_dates.py

Copy file name to clipboardExpand all lines: lib/matplotlib/tests/test_dates.py
+97-1Lines changed: 97 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from matplotlib.cbook import MatplotlibDeprecationWarning
1313
import matplotlib.dates as mdates
1414
import matplotlib.ticker as mticker
15+
from matplotlib import rc_context
1516

1617

1718
def __has_pytz():
@@ -439,7 +440,6 @@ def _create_auto_date_locator(date1, date2):
439440
mdates.date2num(date2))
440441
return locator
441442

442-
d1 = datetime.datetime(1997, 1, 1)
443443
results = ([datetime.timedelta(weeks=52 * 200),
444444
['1980-01-01 00:00:00+00:00', '2000-01-01 00:00:00+00:00',
445445
'2020-01-01 00:00:00+00:00', '2040-01-01 00:00:00+00:00',
@@ -500,6 +500,7 @@ def _create_auto_date_locator(date1, date2):
500500
],
501501
)
502502

503+
d1 = datetime.datetime(1997, 1, 1)
503504
for t_delta, expected in results:
504505
d2 = d1 + t_delta
505506
locator = _create_auto_date_locator(d1, d2)
@@ -557,6 +558,77 @@ def _create_auto_date_locator(date1, date2):
557558
assert strings == expected
558559

559560

561+
def test_auto_date_locator_intmult_tz():
562+
def _create_auto_date_locator(date1, date2, tz):
563+
locator = mdates.AutoDateLocator(interval_multiples=True, tz=tz)
564+
locator.create_dummy_axis()
565+
locator.set_view_interval(mdates.date2num(date1),
566+
mdates.date2num(date2))
567+
return locator
568+
569+
results = ([datetime.timedelta(weeks=52*200),
570+
['1980-01-01 00:00:00-08:00', '2000-01-01 00:00:00-08:00',
571+
'2020-01-01 00:00:00-08:00', '2040-01-01 00:00:00-08:00',
572+
'2060-01-01 00:00:00-08:00', '2080-01-01 00:00:00-08:00',
573+
'2100-01-01 00:00:00-08:00', '2120-01-01 00:00:00-08:00',
574+
'2140-01-01 00:00:00-08:00', '2160-01-01 00:00:00-08:00',
575+
'2180-01-01 00:00:00-08:00', '2200-01-01 00:00:00-08:00']
576+
],
577+
[datetime.timedelta(weeks=52),
578+
['1997-01-01 00:00:00-08:00', '1997-02-01 00:00:00-08:00',
579+
'1997-03-01 00:00:00-08:00', '1997-04-01 00:00:00-08:00',
580+
'1997-05-01 00:00:00-07:00', '1997-06-01 00:00:00-07:00',
581+
'1997-07-01 00:00:00-07:00', '1997-08-01 00:00:00-07:00',
582+
'1997-09-01 00:00:00-07:00', '1997-10-01 00:00:00-07:00',
583+
'1997-11-01 00:00:00-08:00', '1997-12-01 00:00:00-08:00']
584+
],
585+
[datetime.timedelta(days=141),
586+
['1997-01-01 00:00:00-08:00', '1997-01-22 00:00:00-08:00',
587+
'1997-02-01 00:00:00-08:00', '1997-02-22 00:00:00-08:00',
588+
'1997-03-01 00:00:00-08:00', '1997-03-22 00:00:00-08:00',
589+
'1997-04-01 00:00:00-08:00', '1997-04-22 00:00:00-07:00',
590+
'1997-05-01 00:00:00-07:00', '1997-05-22 00:00:00-07:00']
591+
],
592+
[datetime.timedelta(days=40),
593+
['1997-01-01 00:00:00-08:00', '1997-01-05 00:00:00-08:00',
594+
'1997-01-09 00:00:00-08:00', '1997-01-13 00:00:00-08:00',
595+
'1997-01-17 00:00:00-08:00', '1997-01-21 00:00:00-08:00',
596+
'1997-01-25 00:00:00-08:00', '1997-01-29 00:00:00-08:00',
597+
'1997-02-01 00:00:00-08:00', '1997-02-05 00:00:00-08:00',
598+
'1997-02-09 00:00:00-08:00']
599+
],
600+
[datetime.timedelta(hours=40),
601+
['1997-01-01 00:00:00-08:00', '1997-01-01 04:00:00-08:00',
602+
'1997-01-01 08:00:00-08:00', '1997-01-01 12:00:00-08:00',
603+
'1997-01-01 16:00:00-08:00', '1997-01-01 20:00:00-08:00',
604+
'1997-01-02 00:00:00-08:00', '1997-01-02 04:00:00-08:00',
605+
'1997-01-02 08:00:00-08:00', '1997-01-02 12:00:00-08:00',
606+
'1997-01-02 16:00:00-08:00']
607+
],
608+
[datetime.timedelta(minutes=20),
609+
['1997-01-01 00:00:00-08:00', '1997-01-01 00:05:00-08:00',
610+
'1997-01-01 00:10:00-08:00', '1997-01-01 00:15:00-08:00',
611+
'1997-01-01 00:20:00-08:00']
612+
],
613+
[datetime.timedelta(seconds=40),
614+
['1997-01-01 00:00:00-08:00', '1997-01-01 00:00:05-08:00',
615+
'1997-01-01 00:00:10-08:00', '1997-01-01 00:00:15-08:00',
616+
'1997-01-01 00:00:20-08:00', '1997-01-01 00:00:25-08:00',
617+
'1997-01-01 00:00:30-08:00', '1997-01-01 00:00:35-08:00',
618+
'1997-01-01 00:00:40-08:00']
619+
]
620+
)
621+
622+
tz = dateutil.tz.gettz('Canada/Pacific')
623+
d1 = datetime.datetime(1997, 1, 1, tzinfo=tz)
624+
for t_delta, expected in results:
625+
with rc_context({'_internal.classic_mode': False}):
626+
d2 = d1 + t_delta
627+
locator = _create_auto_date_locator(d1, d2, tz)
628+
st = list(map(str, mdates.num2date(locator(), tz=tz)))
629+
assert st == expected
630+
631+
560632
@image_comparison(baseline_images=['date_inverted_limit'],
561633
extensions=['png'])
562634
def test_date_inverted_limit():
@@ -701,6 +773,30 @@ def attach_tz(dt, zi):
701773
_test_rrulewrapper(attach_tz, pytz.timezone)
702774

703775

776+
@pytest.mark.pytz
777+
@pytest.mark.skipif(not __has_pytz(), reason="Requires pytz")
778+
def test_yearlocator_pytz():
779+
import pytz
780+
781+
tz = pytz.timezone('America/New_York')
782+
x = [tz.localize(datetime.datetime(2010, 1, 1))
783+
+ datetime.timedelta(i) for i in range(2000)]
784+
locator = mdates.AutoDateLocator(interval_multiples=True, tz=tz)
785+
locator.create_dummy_axis()
786+
locator.set_view_interval(mdates.date2num(x[0])-1.0,
787+
mdates.date2num(x[-1])+1.0)
788+
789+
np.testing.assert_allclose([733408.208333, 733773.208333, 734138.208333,
790+
734503.208333, 734869.208333,
791+
735234.208333, 735599.208333], locator())
792+
expected = ['2009-01-01 00:00:00-05:00',
793+
'2010-01-01 00:00:00-05:00', '2011-01-01 00:00:00-05:00',
794+
'2012-01-01 00:00:00-05:00', '2013-01-01 00:00:00-05:00',
795+
'2014-01-01 00:00:00-05:00', '2015-01-01 00:00:00-05:00']
796+
st = list(map(str, mdates.num2date(locator(), tz=tz)))
797+
assert st == expected
798+
799+
704800
def test_DayLocator():
705801
with pytest.raises(ValueError):
706802
mdates.DayLocator(interval=-1)

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.