83
83
Out[1]: 732401
84
84
85
85
All the Matplotlib date converters, tickers and formatters are timezone aware.
86
- If no explicit timezone is provided, :rc:`timezone` is assumed. If you want to
87
- use a custom time zone, pass a `datetime.tzinfo` instance with the tz keyword
88
- argument to `num2date`, `.Axis.axis_date`, and any custom date tickers or
89
- locators you create.
86
+ If no explicit timezone is provided, :rc:`timezone` is assumed, provided as a
87
+ string. If you want to use a custom timezone, pass a `datetime.tzinfo`
88
+ instance or a string with the timezone name with the tz keyword argument to
89
+ `num2date`, `.Axis.axis_date`, and any custom date tickers or locators you
90
+ create. Timezone strings are parsed by `~dateutil.tz.gettz`.
90
91
91
92
A wide range of specific and general purpose date tick locators and
92
93
formatters are provided in this module. See
202
203
UTC = datetime .timezone .utc
203
204
204
205
205
- def _get_rc_timezone ():
206
- """Retrieve the preferred timezone from the rcParams dictionary."""
207
- s = mpl .rcParams ['timezone' ]
208
- if s == 'UTC' :
209
- return UTC
210
- return dateutil .tz .gettz (s )
206
+ def _get_tzinfo (tz = None ):
207
+ """
208
+ Generate tzinfo from a string or return tzinfo. If ``None`` (default),
209
+ retrieve the preferred timezone from the rcParams dictionary.
210
+ """
211
+ if tz is None :
212
+ tz = mpl .rcParams ['timezone' ]
213
+ if tz == 'UTC' :
214
+ return UTC
215
+ if isinstance (tz , str ):
216
+ tzinfo = dateutil .tz .gettz (tz )
217
+ if tzinfo is None :
218
+ raise ValueError (f"{ tz } is not a valid timezone as parsed by"
219
+ " dateutil.tz.gettz." )
220
+ return tzinfo
221
+ if isinstance (tz , datetime .tzinfo ):
222
+ return tz
223
+ raise TypeError ("tz must be string or tzinfo subclass." )
211
224
212
225
213
226
"""
@@ -341,8 +354,7 @@ def _from_ordinalf(x, tz=None):
341
354
:rc:`timezone`.
342
355
"""
343
356
344
- if tz is None :
345
- tz = _get_rc_timezone ()
357
+ tz = _get_tzinfo (tz )
346
358
347
359
dt = (np .datetime64 (get_epoch ()) +
348
360
np .timedelta64 (int (np .round (x * MUSECONDS_PER_DAY )), 'us' ))
@@ -508,8 +520,8 @@ def num2date(x, tz=None):
508
520
Number of days (fraction part represents hours, minutes, seconds)
509
521
since the epoch. See `.get_epoch` for the
510
522
epoch, which can be changed by :rc:`date.epoch` or `.set_epoch`.
511
- tz : str, default: :rc:`timezone`
512
- Timezone of *x*.
523
+ tz : str or `~datetime.tzinfo` , default: :rc:`timezone`
524
+ Timezone of *x*. If a string, *tz* is passed to `dateutil.tz`.
513
525
514
526
Returns
515
527
-------
@@ -525,8 +537,7 @@ def num2date(x, tz=None):
525
537
Gregorian calendar is assumed; this is not universal practice.
526
538
For details, see the module docstring.
527
539
"""
528
- if tz is None :
529
- tz = _get_rc_timezone ()
540
+ tz = _get_tzinfo (tz )
530
541
return _from_ordinalf_np_vectorized (x , tz ).tolist ()
531
542
532
543
@@ -621,16 +632,14 @@ def __init__(self, fmt, tz=None, *, usetex=None):
621
632
----------
622
633
fmt : str
623
634
`~datetime.datetime.strftime` format string
624
- tz : ` datetime.tzinfo`, default: :rc:`timezone`
635
+ tz : str or `~ datetime.tzinfo`, default: :rc:`timezone`
625
636
Ticks timezone.
626
637
usetex : bool, default: :rc:`text.usetex`
627
638
To enable/disable the use of TeX's math mode for rendering the
628
639
results of the formatter.
629
640
"""
630
- if tz is None :
631
- tz = _get_rc_timezone ()
641
+ self .tz = _get_tzinfo (tz )
632
642
self .fmt = fmt
633
- self .tz = tz
634
643
self ._usetex = (usetex if usetex is not None else
635
644
mpl .rcParams ['text.usetex' ])
636
645
@@ -639,7 +648,7 @@ def __call__(self, x, pos=0):
639
648
return _wrap_in_tex (result ) if self ._usetex else result
640
649
641
650
def set_tzinfo (self , tz ):
642
- self .tz = tz
651
+ self .tz = _get_tzinfo ( tz )
643
652
644
653
645
654
class ConciseDateFormatter (ticker .Formatter ):
@@ -656,8 +665,8 @@ class ConciseDateFormatter(ticker.Formatter):
656
665
locator : `.ticker.Locator`
657
666
Locator that this axis is using.
658
667
659
- tz : str, optional
660
- Passed to `.dates.date2num `.
668
+ tz : str or `~datetime.tzinfo`, default: :rc:`timezone`
669
+ Passed to `.dates.num2date `.
661
670
662
671
formats : list of 6 strings, optional
663
672
Format strings for 6 levels of tick labelling: mostly years,
@@ -757,7 +766,7 @@ def __init__(self, locator, tz=None, formats=None, offset_formats=None,
757
766
758
767
if offset_formats :
759
768
if len (offset_formats ) != 6 :
760
- raise ValueError ('offsetfmts argument must be a list of '
769
+ raise ValueError ('offset_formats argument must be a list of '
761
770
'6 format strings (or None)' )
762
771
self .offset_formats = offset_formats
763
772
else :
@@ -927,8 +936,8 @@ def __init__(self, locator, tz=None, defaultfmt='%Y-%m-%d', *,
927
936
locator : `.ticker.Locator`
928
937
Locator that this axis is using.
929
938
930
- tz : str, optional
931
- Passed to `.dates.date2num `.
939
+ tz : str or `~datetime.tzinfo` , optional
940
+ Passed to `.dates.num2date `.
932
941
933
942
defaultfmt : str
934
943
The default format to use if none of the values in ``self.scaled``
@@ -1000,7 +1009,7 @@ def set(self, **kwargs):
1000
1009
def _update_rrule (self , ** kwargs ):
1001
1010
tzinfo = self ._base_tzinfo
1002
1011
1003
- # rrule does not play nicely with time zones - especially pytz time
1012
+ # rrule does not play nicely with timezones - especially pytz time
1004
1013
# zones, it's best to use naive zones and attach timezones once the
1005
1014
# datetimes are returned
1006
1015
if 'dtstart' in kwargs :
@@ -1103,17 +1112,15 @@ def __init__(self, tz=None):
1103
1112
"""
1104
1113
Parameters
1105
1114
----------
1106
- tz : ` datetime.tzinfo`
1115
+ tz : str or `~ datetime.tzinfo`, default: :rc:`timezone `
1107
1116
"""
1108
- if tz is None :
1109
- tz = _get_rc_timezone ()
1110
- self .tz = tz
1117
+ self .tz = _get_tzinfo (tz )
1111
1118
1112
1119
def set_tzinfo (self , tz ):
1113
1120
"""
1114
- Set time zone info.
1121
+ Set timezone info. str or `~datetime.tzinfo` .
1115
1122
"""
1116
- self .tz = tz
1123
+ self .tz = _get_tzinfo ( tz )
1117
1124
1118
1125
def datalim_to_dt (self ):
1119
1126
"""Convert axis data interval to datetime objects."""
@@ -1283,7 +1290,7 @@ def __init__(self, tz=None, minticks=5, maxticks=None,
1283
1290
"""
1284
1291
Parameters
1285
1292
----------
1286
- tz : ` datetime.tzinfo`
1293
+ tz : str or `~ datetime.tzinfo`, default: :rc:`timezone `
1287
1294
Ticks timezone.
1288
1295
minticks : int
1289
1296
The minimum number of ticks desired; controls whether ticks occur
@@ -1303,7 +1310,7 @@ def __init__(self, tz=None, minticks=5, maxticks=None,
1303
1310
the ticks to be at hours 0, 6, 12, 18 when hourly ticking is done
1304
1311
at 6 hour intervals.
1305
1312
"""
1306
- super ().__init__ (tz )
1313
+ super ().__init__ (tz = tz )
1307
1314
self ._freq = YEARLY
1308
1315
self ._freqs = [YEARLY , MONTHLY , DAILY , HOURLY , MINUTELY ,
1309
1316
SECONDLY , MICROSECONDLY ]
@@ -1457,7 +1464,7 @@ def get_locator(self, dmin, dmax):
1457
1464
byhour = byhour , byminute = byminute ,
1458
1465
bysecond = bysecond )
1459
1466
1460
- locator = RRuleLocator (rrule , self .tz )
1467
+ locator = RRuleLocator (rrule , tz = self .tz )
1461
1468
else :
1462
1469
locator = MicrosecondLocator (interval , tz = self .tz )
1463
1470
if date2num (dmin ) > 70 * 365 and interval < 1000 :
@@ -1490,7 +1497,7 @@ def __init__(self, base=1, month=1, day=1, tz=None):
1490
1497
"""
1491
1498
rule = rrulewrapper (YEARLY , interval = base , bymonth = month ,
1492
1499
bymonthday = day , ** self .hms0d )
1493
- super ().__init__ (rule , tz )
1500
+ super ().__init__ (rule , tz = tz )
1494
1501
self .base = ticker ._Edge_integer (base , 0 )
1495
1502
1496
1503
def _create_rrule (self , vmin , vmax ):
@@ -1534,7 +1541,7 @@ def __init__(self, bymonth=None, bymonthday=1, interval=1, tz=None):
1534
1541
1535
1542
rule = rrulewrapper (MONTHLY , bymonth = bymonth , bymonthday = bymonthday ,
1536
1543
interval = interval , ** self .hms0d )
1537
- super ().__init__ (rule , tz )
1544
+ super ().__init__ (rule , tz = tz )
1538
1545
1539
1546
1540
1547
class WeekdayLocator (RRuleLocator ):
@@ -1562,7 +1569,7 @@ def __init__(self, byweekday=1, interval=1, tz=None):
1562
1569
1563
1570
rule = rrulewrapper (DAILY , byweekday = byweekday ,
1564
1571
interval = interval , ** self .hms0d )
1565
- super ().__init__ (rule , tz )
1572
+ super ().__init__ (rule , tz = tz )
1566
1573
1567
1574
1568
1575
class DayLocator (RRuleLocator ):
@@ -1588,7 +1595,7 @@ def __init__(self, bymonthday=None, interval=1, tz=None):
1588
1595
1589
1596
rule = rrulewrapper (DAILY , bymonthday = bymonthday ,
1590
1597
interval = interval , ** self .hms0d )
1591
- super ().__init__ (rule , tz )
1598
+ super ().__init__ (rule , tz = tz )
1592
1599
1593
1600
1594
1601
class HourLocator (RRuleLocator ):
@@ -1608,7 +1615,7 @@ def __init__(self, byhour=None, interval=1, tz=None):
1608
1615
1609
1616
rule = rrulewrapper (HOURLY , byhour = byhour , interval = interval ,
1610
1617
byminute = 0 , bysecond = 0 )
1611
- super ().__init__ (rule , tz )
1618
+ super ().__init__ (rule , tz = tz )
1612
1619
1613
1620
1614
1621
class MinuteLocator (RRuleLocator ):
@@ -1628,7 +1635,7 @@ def __init__(self, byminute=None, interval=1, tz=None):
1628
1635
1629
1636
rule = rrulewrapper (MINUTELY , byminute = byminute , interval = interval ,
1630
1637
bysecond = 0 )
1631
- super ().__init__ (rule , tz )
1638
+ super ().__init__ (rule , tz = tz )
1632
1639
1633
1640
1634
1641
class SecondLocator (RRuleLocator ):
@@ -1648,7 +1655,7 @@ def __init__(self, bysecond=None, interval=1, tz=None):
1648
1655
bysecond = range (60 )
1649
1656
1650
1657
rule = rrulewrapper (SECONDLY , bysecond = bysecond , interval = interval )
1651
- super ().__init__ (rule , tz )
1658
+ super ().__init__ (rule , tz = tz )
1652
1659
1653
1660
1654
1661
class MicrosecondLocator (DateLocator ):
0 commit comments