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

Skip to content

Commit 00d71ce

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

File tree

2 files changed

+120
-6
lines changed

2 files changed

+120
-6
lines changed

lib/matplotlib/dates.py

Lines 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

Lines 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)