From a61d8232c0293ba21c8c881c3959a3eaade19afc Mon Sep 17 00:00:00 2001 From: Tao He Date: Fri, 15 Mar 2019 19:06:05 +0800 Subject: [PATCH] BUG: Cast ExtensionArray to numpy ndarray before plot (#25590) * Cast `ExtensionArray` to `nd.array` before plot. --- doc/source/whatsnew/v0.25.0.rst | 1 + pandas/plotting/_core.py | 7 ++++++- pandas/tests/plotting/test_frame.py | 21 ++++++++++++++++++++- 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/doc/source/whatsnew/v0.25.0.rst b/doc/source/whatsnew/v0.25.0.rst index d186fdfe0f322..ddc5e543c6165 100644 --- a/doc/source/whatsnew/v0.25.0.rst +++ b/doc/source/whatsnew/v0.25.0.rst @@ -225,6 +225,7 @@ I/O Plotting ^^^^^^^^ +- Fixed bug where :class:`api.extensions.ExtensionArray` could not be used in matplotlib plotting (:issue:`25587`) - - - diff --git a/pandas/plotting/_core.py b/pandas/plotting/_core.py index b9ec4d58db739..68d5f30a399ac 100644 --- a/pandas/plotting/_core.py +++ b/pandas/plotting/_core.py @@ -365,6 +365,12 @@ def _compute_plot_data(self): if is_empty: raise TypeError('no numeric data to plot') + # GH25587: cast ExtensionArray of pandas (IntegerArray, etc.) to + # np.ndarray before plot. + numeric_data = numeric_data.copy() + for col in numeric_data: + numeric_data[col] = np.asarray(numeric_data[col]) + self.data = numeric_data def _make_plot(self): @@ -1794,7 +1800,6 @@ def _plot(data, x=None, y=None, subplots=False, ) label_name = label_kw or data.columns data.columns = label_name - plot_obj = klass(data, subplots=subplots, ax=ax, kind=kind, **kwds) plot_obj.generate() diff --git a/pandas/tests/plotting/test_frame.py b/pandas/tests/plotting/test_frame.py index 28806bb67c896..7346a3b09aecf 100644 --- a/pandas/tests/plotting/test_frame.py +++ b/pandas/tests/plotting/test_frame.py @@ -18,6 +18,7 @@ import pandas as pd from pandas import ( DataFrame, MultiIndex, PeriodIndex, Series, bdate_range, date_range) +from pandas.core.arrays import integer_array from pandas.tests.plotting.common import ( TestPlotBase, _check_plot_works, _ok_for_gaussian_kde, _skip_if_no_scipy_gaussian_kde) @@ -144,8 +145,26 @@ def test_plot(self): result = ax.axes assert result is axes[0] - # GH 15516 + def test_integer_array_plot(self): + # GH 25587 + arr = integer_array([1, 2, 3, 4], dtype="UInt32") + + s = Series(arr) + _check_plot_works(s.plot.line) + _check_plot_works(s.plot.bar) + _check_plot_works(s.plot.hist) + _check_plot_works(s.plot.pie) + + df = DataFrame({'x': arr, 'y': arr}) + _check_plot_works(df.plot.line) + _check_plot_works(df.plot.bar) + _check_plot_works(df.plot.hist) + _check_plot_works(df.plot.pie, y='y') + _check_plot_works(df.plot.scatter, x='x', y='y') + _check_plot_works(df.plot.hexbin, x='x', y='y') + def test_mpl2_color_cycle_str(self): + # GH 15516 colors = ['C' + str(x) for x in range(10)] df = DataFrame(randn(10, 3), columns=['a', 'b', 'c']) for c in colors: