8000 Merge pull request #12678 from jklymak/fix-yearlocator-tz · jklymak/matplotlib@7768522 · GitHub
[go: up one dir, main page]

Skip to content

Commit 7768522

Browse files
tacaswelljklymak
authored andcommitted
Merge pull request matplotlib#12678 from jklymak/fix-yearlocator-tz
1 parent 65bedc5 commit 7768522

File tree

2 files changed

+175
-6
lines changed

2 files changed

+175
-6
lines changed

lib/matplotlib/dates.py

Lines changed: 23 additions & 5 deletions
< 8000 div class="border position-relative rounded-bottom-2">
Original file line numberDiff line numberDiff line change
@@ -1188,7 +1188,7 @@ def __init__(self, tz=None, minticks=5, maxticks=None,
11881188
locator.intervald[HOURLY] = [3] # only show every 3 hours
11891189
"""
11901190
DateLocator.__init__(self, tz)
1191-
self._locator = YearLocator()
1191+
self._locator = YearLocator(tz=tz)
11921192
self._freq = YEARLY
11931193
self._freqs = [YEARLY, MONTHLY, DAILY, HOURLY, MINUTELY,
11941194
SECONDLY, MICROSECONDLY]
@@ -1341,7 +1341,7 @@ def get_locator(self, dmin, dmax):
13411341
'AutoDateLocator.')
13421342

13431343
if (freq == YEARLY) and self.interval_multiples:
1344-
locator = YearLocator(interval)
1344+
locator = YearLocator(interval, tz=self.tz)
13451345
elif use_rrule_locator[i]:
13461346
_, bymonth, bymonthday, byhour, byminute, bysecond, _ = byranges
13471347
rrule = rrulewrapper(self._freq, interval=interval,
@@ -1391,8 +1391,11 @@ def __init__(self, base=1, month=1, day=1, tz=None):
13911391
'hour': 0,
13921392
'minute': 0,
13931393
'second': 0,
1394-
'tzinfo': tz
13951394
}
1395+
if not hasattr(tz, 'localize'):
1396+
# if tz is pytz, we need to do this w/ the localize fcn,
1397+
# otherwise datetime.replace works fine...
1398+
self.replaced['tzinfo'] = tz
13961399

13971400
def __call__(self):
13981401
# if no data have been set, this will tank with a ValueError
@@ -1407,13 +1410,26 @@ def tick_values(self, vmin, vmax):
14071410
ymin = self.base.le(vmin.year) * self.base.step
14081411
ymax = self.base.ge(vmax.year) * self.base.step
14091412

1410-
ticks = [vmin.replace(year=ymin, **self.replaced)]
1413+
vmin = vmin.replace(year=ymin, **self.replaced)
1414+
if hasattr(self.tz, 'localize'):
1415+
# look after pytz
1416+
if not vmin.tzinfo:
1417+
vmin = self.tz.localize(vmin, is_dst=True)
1418+
1419+
ticks = [vmin]
1420+
14111421
while True:
14121422
dt = ticks[-1]
14131423
if dt.year >= ymax:
14141424
return date2num(ticks)
14151425
year = dt.year + self.base.step
1416-
ticks.append(dt.replace(year=year, **self.replaced))
1426+
dt = dt.replace(year=year, **self.replaced)
1427+
if hasattr(self.tz, 'localize'):
1428+
# look after pytz
1429+
if not dt.tzinfo:
1430+
dt = self.tz.localize(dt, is_dst=True)
1431+
1432+
ticks.append(dt)
14171433

14181434
def autoscale(self):
14191435
"""
@@ -1424,7 +1440,9 @@ def autoscale(self):
14241440
ymin = self.base.le(dmin.year)
14251441
ymax = self.base.ge(dmax.year)
14261442
vmin = dmin.replace(year=ymin, **self.replaced)
1443+
vmin = vmin.astimezone(self.tz)
14271444
vmax = dmax.replace(year=ymax, **self.replaced)
1445+
vmax = vmax.astimezone(self.tz)
14281446

14291447
vmin = date2num(vmin)
14301448
vmax = date2num(vmax)

lib/matplotlib/tests/test_dates.py

Lines changed: 152 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
import matplotlib.pyplot as plt
1212
from matplotlib.cbook import MatplotlibDeprecationWarning
1313
import matplotlib.dates as mdates
14+
import matplotlib.ticker as mticker
15+
from matplotlib import rc_context
1416

1517

16 A3DB 18
def __has_pytz():
@@ -406,7 +408,6 @@ def _create_auto_date_locator(date1, date2):
406408
mdates.date2num(date2))
407409
return locator
408410

409-
d1 = datetime.datetime(1997, 1, 1)
410411
results = ([datetime.timedelta(weeks=52 * 200),
411412
['1980-01-01 00:00:00+00:00', '2000-01-01 00:00:00+00:00',
412413
'2020-01-01 00:00:00+00:00', '2040-01-01 00:00:00+00:00',
@@ -467,12 +468,138 @@ def _create_auto_date_locator(date1, date2):
467468
],
468469
)
469470

471+
d1 = datetime.datetime(1997, 1, 1)
470472
for t_delta, expected in results:
471473
d2 = d1 + t_delta
472474
locator = _create_auto_date_locator(d1, d2)
473475
assert list(map(str, mdates.num2date(locator()))) == expected
474476

475477

478+
<<<<<<< HEAD
479+
=======
480+
def test_concise_formatter():
481+
def _create_auto_date_locator(date1, date2):
482+
fig, ax = plt.subplots()
483+
484+
locator = mdates.AutoDateLocator(interval_multiples=True)
485+
formatter = mdates.ConciseDateFormatter(locator)
486+
ax.yaxis.set_major_locator(locator)
487+
ax.yaxis.set_major_formatter(formatter)
488+
ax.set_ylim(date1, date2)
489+
fig.canvas.draw()
490+
sts = []
491+
for st in ax.get_yticklabels():
492+
sts += [st.get_text()]
493+
return sts
494+
495+
d1 = datetime.datetime(1997, 1, 1)
496+
results = ([datetime.timedelta(weeks=52 * 200),
497+
[str(t) for t in range(1980, 2201, 20)]
498+
],
499+
[datetime.timedelta(weeks=52),
500+
['1997', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug',
501+
'Sep', 'Oct', 'Nov', 'Dec']
502+
],
503+
[datetime.timedelta(days=141),
504+
['Jan', '22', 'Feb', '22', 'Mar', '22', 'Apr', '22',
505+
'May', '22']
506+
],
507+
[datetime.timedelta(days=40),
508+
['Jan', '05', '09', '13', '17', '21', '25', '29', 'Feb',
509+
'05', '09']
510+
],
511+
[datetime.timedelta(hours=40),
512+
['Jan-01', '04:00', '08:00', '12:00', '16:00', '20:00',
513+
'Jan-02', '04:00', '08:00', '12:00', '16:00']
514+
],
515+
[datetime.timedelta(minutes=20),
516+
['00:00', '00:05', '00:10', '00:15', '00:20']
517+
],
518+
[datetime.timedelta(seconds=40),
519+
['00:00', '05', '10', '15', '20', '25', '30', '35', '40']
520+
],
521+
[datetime.timedelta(seconds=2),
522+
['59.5', '00:00', '00.5', '01.0', '01.5', '02.0', '02.5']
523+
],
524+
)
525+
for t_delta, expected in results:
526+
d2 = d1 + t_delta
527+
strings = _create_auto_date_locator(d1, d2)
528+
assert strings == expected
529+
530+
531+
def test_auto_date_locator_intmult_tz():
532+
def _create_auto_date_locator(date1, date2, tz):
533+
locator = mdates.AutoDateLocator(interval_multiples=True, tz=tz)
534+
locator.create_dummy_axis()
535+
locator.set_view_interval(mdates.date2num(date1),
536+
mdates.date2num(date2))
537+
return locator
538+
539+
results = ([datetime.timedelta(weeks=52*200),
540+
['1980-01-01 00:00:00-08:00', '2000-01-01 00:00:00-08:00',
541+
'2020-01-01 00:00:00-08:00', '2040-01-01 00:00:00-08:00',
542+
'2060-01-01 00:00:00-08:00', '2080-01-01 00:00:00-08:00',
543+
'2100-01-01 00:00:00-08:00', '2120-01-01 00:00:00-08:00',
544+
'2140-01-01 00:00:00-08:00', '2160-01-01 00:00:00-08:00',
545+
'2180-01-01 00:00:00-08:00', '2200-01-01 00:00:00-08:00']
546+
],
547+
[datetime.timedelta(weeks=52),
548+
['1997-01-01 00:00:00-08:00', '1997-02-01 00:00:00-08:00',
549+
'1997-03-01 00:00:00-08:00', '1997-04-01 00:00:00-08:00',
550+
'1997-05-01 00:00:00-07:00', '1997-06-01 00:00:00-07:00',
551+
'1997-07-01 00:00:00-07:00', '1997-08-01 00:00:00-07:00',
552+
'1997-09-01 00:00:00-07:00', '1997-10-01 00:00:00-07:00',
553+
'1997-11-01 00:00:00-08:00', '1997-12-01 00:00:00-08:00']
554+
],
555+
[datetime.timedelta(days=141),
556+
['1997-01-01 00:00:00-08:00', '1997-01-22 00:00:00-08:00',
557+
'1997-02-01 00:00:00-08:00', '1997-02-22 00:00:00-08:00',
558+
'1997-03-01 00:00:00-08:00', '1997-03-22 00:00:00-08:00',
559+
'1997-04-01 00:00:00-08:00', '1997-04-22 00:00:00-07:00',
560+
'1997-05-01 00:00:00-07:00', '1997-05-22 00:00:00-07:00']
561+
],
562+
[datetime.timedelta(days=40),
563+
['1997-01-01 00:00:00-08:00', '1997-01-05 00:00:00-08:00',
564+
'1997-01-09 00:00:00-08:00', '1997-01-13 00:00:00-08:00',
565+
'1997-01-17 00:00:00-08:00', '1997-01-21 00:00:00-08:00',
566+
'1997-01-25 00:00:00-08:00', '1997-01-29 00:00:00-08:00',
567+
'1997-02-01 00:00:00-08:00', '1997-02-05 00:00:00-08:00',
568+
'1997-02-09 00:00:00-08:00']
569+
],
570+
[datetime.timedelta(hours=40),
571+
['1997-01-01 00:00:00-08:00', '1997-01-01 04:00:00-08:00',
572+
'1997-01-01 08:00:00-08:00', '1997-01-01 12:00:00-08:00',
573+
'1997-01-01 16:00:00-08:00', '1997-01-01 20:00:00-08:00',
574+
'1997-01-02 00:00:00-08:00', '1997-01-02 04:00:00-08:00',
575+
'1997-01-02 08:00:00-08:00', '1997-01-02 12:00:00-08:00',
576+
'1997-01-02 16:00:00-08:00']
577+
],
578+
[datetime.timedelta(minutes=20),
579+
['1997-01-01 00:00:00-08:00', '1997-01-01 00:05:00-08:00',
580+
'1997-01-01 00:10:00-08:00', '1997-01-01 00:15:00-08:00',
581+
'1997-01-01 00:20:00-08:00']
582+
],
583+
[datetime.timedelta(seconds=40),
584+
['1997-01-01 00:00:00-08:00', '1997-01-01 00:00:05-08:00',
585+
'1997-01-01 00:00:10-08:00', '1997-01-01 00:00:15-08:00',
586+
'1997-01-01 00:00:20-08:00', '1997-01-01 00:00:25-08:00',
587+
'1997-01-01 00:00:30-08:00', '1997-01-01 00:00:35-08:00',
588+
'1997-01-01 00:00:40-08:00']
589+
]
590+
)
591+
592+
tz = dateutil.tz.gettz('Canada/Pacific')
593+
d1 = datetime.datetime(1997, 1, 1, tzinfo=tz)
594+
for t_delta, expected in results:
595+
with rc_context({'_internal.classic_mode': False}):
596+
d2 = d1 + t_delta
597+
locator = _create_auto_date_locator(d1, d2, tz)
598+
st = list(map(str, mdates.num2date(locator(), tz=tz)))
599+
assert st == expected
600+
601+
602+
>>>>>>> 00d71cebb... Merge pull request #12678 from jklymak/fix-yearlocator-tz
476603
@image_comparison(baseline_images=['date_inverted_limit'],
477604
extensions=['png'])
478605
def test_date_inverted_limit():
@@ -617,6 +744,30 @@ def attach_tz(dt, zi):
617744
_test_rrulewrapper(attach_tz, pytz.timezone)
618745

619746

747+
@pytest.mark.pytz
748+
@pytest.mark.skipif(not __has_pytz(), reason="Requires pytz")
749+
def test_yearlocator_pytz():
750+
import pytz
751+
752+
tz = pytz.timezone('America/New_York')
753+
x = [tz.localize(datetime.datetime(2010, 1, 1))
754+
+ datetime.timedelta(i) for i in range(2000)]
755+
locator = mdates.AutoDateLocator(interval_multiples=True, tz=tz)
756+
locator.create_dummy_axis()
757+
locator.set_view_interval(mdates.date2num(x[0])-1.0,
758+
mdates.date2num(x[-1])+1.0)
759+
760+
np.testing.assert_allclose([733408.208333, 733773.208333, 734138.208333,
761+
734503.208333, 734869.208333,
762+
735234.208333, 735599.208333], locator())
763+
expected = ['2009-01-01 00:00:00-05:00',
764+
'2010-01-01 00:00:00-05:00', '2011-01-01 00:00:00-05:00',
765+
'2012-01-01 00:00:00-05:00', '2013-01-01 00:00:00-05:00',
766+
'2014-01-01 00:00:00-05:00', '2015-01-01 00:00:00-05:00']
767+
st = list(map(str, mdates.num2date(locator(), tz=tz)))
768+
assert st == expected
769+
770+
620771
def test_DayLocator():
621772
with pytest.raises(ValueError):
622773
mdates.DayLocator(interval=-1)

0 commit comments

Comments
 (0)
0