Skip to content

timezone aware datetime64 object converter fails when plot #22859

Closed
@enritoomey

Description

@enritoomey

Code Sample, a copy-pastable example if possible

import pandas
import dateutil.parser
import datetime


start = dateutil.parser.parse("2018-05-17 19:00:00").replace(tzinfo=datetime.timezone.utc)
end = dateutil.parser.parse("2018-05-17 20:00:00").replace(tzinfo=datetime.timezone.utc)
df = pandas.DataFrame(index=[start, end], data=[0,1])
df.plot()
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-2-848b80e64df8> in <module>()
----> 1 df.plot()

~/pyvenvs/matplotlib_issue/lib/python3.5/site-packages/pandas/plotting/_core.py in __call__(self, x, y, kind, ax, subplots, sharex, sharey, layout, figsize, use_index, title, grid, legend, style, logx, logy, loglog, xticks, yticks, xlim, ylim, rot, fontsize, colormap, table, yerr, xerr, secondary_y, sort_columns, **kwds)                                                                                                                                                        
   2939                           fontsize=fontsize, colormap=colormap, table=table,
   2940                           yerr=yerr, xerr=xerr, secondary_y=secondary_y,
-> 2941                           sort_columns=sort_columns, **kwds)
   2942     __call__.__doc__ = plot_frame.__doc__
   2943 

~/pyvenvs/matplotlib_issue/lib/python3.5/site-packages/pandas/plotting/_core.py in plot_frame(data, x, y, kind, ax, subplots, sharex, sharey, layout, figsize, use_index, title, grid, legend, style, logx, logy, loglog, xticks, yticks, xlim, ylim, rot, fontsize, colormap, table, yerr, xerr, secondary_y, sort_columns, **kwds)                                                                                                                                                      
   1975                  yerr=yerr, xerr=xerr,
   1976                  secondary_y=secondary_y, sort_columns=sort_columns,
-> 1977                  **kwds)
   1978 
   1979 

~/pyvenvs/matplotlib_issue/lib/python3.5/site-packages/pandas/plotting/_core.py in _plot(data, x, y, subplots, ax, kind, **kwds)
   1802         plot_obj = klass(data, subplots=subplots, ax=ax, kind=kind, **kwds)
   1803 
-> 1804     plot_obj.generate()
   1805     plot_obj.draw()
   1806     return plot_obj.result

~/pyvenvs/matplotlib_issue/lib/python3.5/site-packages/pandas/plotting/_core.py in generate(self)
    258         self._compute_plot_data()
    259         self._setup_subplots()
--> 260         self._make_plot()
    261         self._add_table()
    262         self._make_legend()

~/pyvenvs/matplotlib_issue/lib/python3.5/site-packages/pandas/plotting/_core.py in _make_plot(self)
    983                              stacking_id=stacking_id,
    984                              is_errorbar=is_errorbar,
--> 985                              **kwds)
    986             self._add_legend_handle(newlines[0], label, index=i)
    987 

~/pyvenvs/matplotlib_issue/lib/python3.5/site-packages/pandas/plotting/_core.py in _plot(cls, ax, x, y, style, column_num, stacking_id, **kwds)
    999             cls._initialize_stacker(ax, stacking_id, len(y))
   1000         y_values = cls._get_stacked_values(ax, stacking_id, y, kwds['label'])
-> 1001         lines = MPLPlot._plot(ax, x, y_values, style=style, **kwds)
   1002         cls._update_stacker(ax, stacking_id, y)
   1003         return lines

~/pyvenvs/matplotlib_issue/lib/python3.5/site-packages/pandas/plotting/_core.py in _plot(cls, ax, x, y, style, is_errorbar, **kwds)
    613             else:
    614                 args = (x, y)
--> 615             return ax.plot(*args, **kwds)
    616 
    617     def _get_index_name(self):

~/pyvenvs/matplotlib_issue/lib/python3.5/site-packages/matplotlib/__init__.py in inner(ax, data, *args, **kwargs)
   1783                         "the Matplotlib list!)" % (label_namer, func.__name__),
   1784                         RuntimeWarning, stacklevel=2)
-> 1785             return func(ax, *args, **kwargs)
   1786 
   1787         inner.__doc__ = _add_data_doc(inner.__doc__,

~/pyvenvs/matplotlib_issue/lib/python3.5/site-packages/matplotlib/axes/_axes.py in plot(self, scalex, scaley, *args, **kwargs)
   1602         kwargs = cbook.normalize_kwargs(kwargs, mlines.Line2D._alias_map)
   1603 
-> 1604         for line in self._get_lines(*args, **kwargs):
   1605             self.add_line(line)
   1606             lines.append(line)

~/pyvenvs/matplotlib_issue/lib/python3.5/site-packages/matplotlib/axes/_base.py in _grab_next_args(self, *args, **kwargs)
    391                 this += args[0],
    392                 args = args[1:]
--> 393             yield from self._plot_args(this, kwargs)
    394 
    395 

~/pyvenvs/matplotlib_issue/lib/python3.5/site-packages/matplotlib/axes/_base.py in _plot_args(self, tup, kwargs)
    368             x, y = index_of(tup[-1])
    369 
--> 370         x, y = self._xy_from_xy(x, y)
    371 
    372         if self.command == 'plot':

~/pyvenvs/matplotlib_issue/lib/python3.5/site-packages/matplotlib/axes/_base.py in _xy_from_xy(self, x, y)
    202     def _xy_from_xy(self, x, y):
    203         if self.axes.xaxis is not None and self.axes.yaxis is not None:
--> 204             bx = self.axes.xaxis.update_units(x)
    205             by = self.axes.yaxis.update_units(y)
    206 

~/pyvenvs/matplotlib_issue/lib/python3.5/site-packages/matplotlib/axis.py in update_units(self, data)
   1473         default = self.converter.default_units(data, self)
   1474         if default is not None and self.units is None:
-> 1475             self.set_units(default)
   1476 
   1477         if neednew:

~/pyvenvs/matplotlib_issue/lib/python3.5/site-packages/matplotlib/axis.py in set_units(self, u)
   1546                 pchanged = True
   1547         if pchanged:
-> 1548             self._update_axisinfo()
   1549             self.callbacks.process('units')
   1550             self.callbacks.process('units finalize')

~/pyvenvs/matplotlib_issue/lib/python3.5/site-packages/matplotlib/axis.py in _update_axisinfo(self)
   1488             return
   1489 
-> 1490         info = self.converter.axisinfo(self.units, self)
   1491 
   1492         if info is None:

~/pyvenvs/matplotlib_issue/lib/python3.5/site-packages/pandas/plotting/_converter.py in axisinfo(unit, axis)
    351 
    352         majloc = PandasAutoDateLocator(tz=tz)
--> 353         majfmt = PandasAutoDateFormatter(majloc, tz=tz)
    354         datemin = pydt.date(2000, 1, 1)
    355         datemax = pydt.date(2010, 1, 1)

~/pyvenvs/matplotlib_issue/lib/python3.5/site-packages/pandas/plotting/_converter.py in __init__(self, locator, tz, defaultfmt)
    365         # matplotlib.dates._UTC has no _utcoffset called by pandas
    366         if self._tz is dates.UTC:
--> 367             self._tz._utcoffset = self._tz.utcoffset(None)
    368 
    369         # For mpl > 2.0 the format strings are controlled via rcparams

AttributeError: 'datetime.timezone' object has no attribute '_utcoffset'

Problem description

Pandas converter, use to extract date str for axis labels, fails when index is timezone aware. This happends only if matplotlib>=3.0.0 version is installed. I reported the bug first to matplotlib (matplotlib/matplotlib#12310), but the close it as they believe that the bug is in pandas converter.

Output of pd.show_versions()

INSTALLED VERSIONS ------------------ commit: None python: 3.5.3.final.0 python-bits: 64 OS: Linux OS-release: 4.9.0-4-amd64 machine: x86_64 processor: byteorder: little LC_ALL: None LANG: en_US.UTF-8 LOCALE: en_US.UTF-8

pandas: 0.23.4
pytest: None
pip: 18.0
setuptools: 40.4.3
Cython: None
numpy: 1.15.2
scipy: None
pyarrow: None
xarray: None
IPython: 6.5.0
sphinx: None
patsy: None
dateutil: 2.7.3
pytz: 2018.5
blosc: None
bottleneck: None
tables: None
numexpr: None
feather: None
matplotlib: 3.0.0
openpyxl: None
xlrd: None
xlwt: None
xlsxwriter: None
lxml: None
bs4: None
html5lib: None
sqlalchemy: None
pymysql: None
psycopg2: None
jinja2: None
s3fs: None
fastparquet: None
pandas_gbq: None
pandas_datareader: None

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions