From c81e5002582062a839e449dd89176defae0be7c1 Mon Sep 17 00:00:00 2001 From: Neil Parley Date: Wed, 20 Apr 2016 21:37:54 +0100 Subject: [PATCH 1/6] Attempted fixes for #8113 and #10678 --- pandas/core/generic.py | 3 +++ pandas/core/internals.py | 10 ++++++++++ pandas/tools/plotting.py | 9 +++++++-- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index ad56ea44a0dc6..bde076153a4d4 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -3017,6 +3017,9 @@ def _get_numeric_data(self): def _get_bool_data(self): return self._constructor(self._data.get_bool_data()).__finalize__(self) + def _get_dt_data(self): + return self._constructor(self._data.get_dt_data()).__finalize__(self) + # ---------------------------------------------------------------------- # Internal Interface Methods diff --git a/pandas/core/internals.py b/pandas/core/internals.py index 57361886eab8c..5077ab461208a 100644 --- a/pandas/core/internals.py +++ b/pandas/core/internals.py @@ -3354,6 +3354,16 @@ def get_numeric_data(self, copy=False): self._consolidate_inplace() return self.combine([b for b in self.blocks if b.is_numeric], copy) + def get_dt_data(self, copy=False): + """ + Parameters + ---------- + copy : boolean, default False + Whether to copy the blocks + """ + self._consolidate_inplace() + return self.combine([b for b in self.blocks if b.is_datetime], copy) + def combine(self, blocks, copy=True): """ return a new manager with the blocks """ if len(blocks) == 0: diff --git a/pandas/tools/plotting.py b/pandas/tools/plotting.py index f70a2b0b22140..fc244386e46d7 100644 --- a/pandas/tools/plotting.py +++ b/pandas/tools/plotting.py @@ -1146,6 +1146,8 @@ def _compute_plot_data(self): data = data.to_frame(name=label) numeric_data = data._convert(datetime=True)._get_numeric_data() + time_data = data._convert(datetime=True)._get_dt_data() + numeric_data = numeric_data.join(time_data) try: is_empty = numeric_data.empty @@ -1579,8 +1581,11 @@ class PlanePlot(MPLPlot): _layout_type = 'single' - def __init__(self, data, x, y, **kwargs): - MPLPlot.__init__(self, data, **kwargs) + def __init__(self, data, x, y, sharex=False, **kwargs): + if sharex is None: + # Fix x axis color bar problems + sharex = False + MPLPlot.__init__(self, data, sharex=sharex, **kwargs) if x is None or y is None: raise ValueError(self._kind + ' requires and x and y column') if is_integer(x) and not self.data.columns.holds_integer(): From b7036bbb8acbd83309eb16c3db574d2ec71ad7e3 Mon Sep 17 00:00:00 2001 From: Neil Parley Date: Thu, 21 Apr 2016 16:04:47 +0100 Subject: [PATCH 2/6] Create a new method which can override _compute_plot_data if the plot (i.e. scatter) is happy with datetimes --- pandas/tools/plotting.py | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/pandas/tools/plotting.py b/pandas/tools/plotting.py index fc244386e46d7..d9d289c6c4249 100644 --- a/pandas/tools/plotting.py +++ b/pandas/tools/plotting.py @@ -1146,8 +1146,6 @@ def _compute_plot_data(self): data = data.to_frame(name=label) numeric_data = data._convert(datetime=True)._get_numeric_data() - time_data = data._convert(datetime=True)._get_dt_data() - numeric_data = numeric_data.join(time_data) try: is_empty = numeric_data.empty @@ -1161,6 +1159,31 @@ def _compute_plot_data(self): self.data = numeric_data + def _compute_plot_data_with_dt(self): + data = self.data + + if isinstance(data, Series): + label = self.label + if label is None and data.name is None: + label = 'None' + data = data.to_frame(name=label) + + numeric_dt__data = data._convert(datetime=True)._get_numeric_data() + time_data = data._convert(datetime=True)._get_dt_data() + numeric_dt__data = numeric_dt__data.join(time_data) + + try: + is_empty = numeric_dt__data.empty + except AttributeError: + is_empty = not len(numeric_dt__data) + + # no empty frames or series allowed + if is_empty: + raise TypeError('Empty {0!r}: no numeric data to ' + 'plot'.format(numeric_dt__data.__class__.__name__)) + + self.data = numeric_dt__data + def _make_plot(self): raise AbstractMethodError(self) @@ -1618,6 +1641,9 @@ def __init__(self, data, x, y, s=None, c=None, **kwargs): c = self.data.columns[c] self.c = c + def _compute_plot_data(self): + self._compute_plot_data_with_dt() + def _make_plot(self): x, y, c, data = self.x, self.y, self.c, self.data ax = self.axes[0] From 8b8d542c7c8c4263c01617fd7009bd371174cbd4 Mon Sep 17 00:00:00 2001 From: Neil Parley Date: Mon, 15 Aug 2016 11:12:14 +0100 Subject: [PATCH 3/6] Move _compute_plot_data_with_dt to PlanePlot class --- pandas/tools/plotting.py | 49 ++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 25 deletions(-) diff --git a/pandas/tools/plotting.py b/pandas/tools/plotting.py index d9d289c6c4249..ea25db6c3f6fd 100644 --- a/pandas/tools/plotting.py +++ b/pandas/tools/plotting.py @@ -1159,31 +1159,6 @@ def _compute_plot_data(self): self.data = numeric_data - def _compute_plot_data_with_dt(self): - data = self.data - - if isinstance(data, Series): - label = self.label - if label is None and data.name is None: - label = 'None' - data = data.to_frame(name=label) - - numeric_dt__data = data._convert(datetime=True)._get_numeric_data() - time_data = data._convert(datetime=True)._get_dt_data() - numeric_dt__data = numeric_dt__data.join(time_data) - - try: - is_empty = numeric_dt__data.empty - except AttributeError: - is_empty = not len(numeric_dt__data) - - # no empty frames or series allowed - if is_empty: - raise TypeError('Empty {0!r}: no numeric data to ' - 'plot'.format(numeric_dt__data.__class__.__name__)) - - self.data = numeric_dt__data - def _make_plot(self): raise AbstractMethodError(self) @@ -1627,6 +1602,30 @@ def _post_plot_logic(self, ax, data): ax.set_ylabel(pprint_thing(y)) ax.set_xlabel(pprint_thing(x)) + def _compute_plot_data_with_dt(self): + data = self.data + + if isinstance(data, Series): + label = self.label + if label is None and data.name is None: + label = 'None' + data = data.to_frame(name=label) + + numeric_dt__data = data._convert(datetime=True)._get_numeric_data() + time_data = data._convert(datetime=True)._get_dt_data() + numeric_dt__data = numeric_dt__data.join(time_data) + + try: + is_empty = numeric_dt__data.empty + except AttributeError: + is_empty = not len(numeric_dt__data) + + # no empty frames or series allowed + if is_empty: + raise TypeError('Empty {0!r}: no numeric data to ' + 'plot'.format(numeric_dt__data.__class__.__name__)) + + self.data = numeric_dt__data class ScatterPlot(PlanePlot): _kind = 'scatter' From 8c0ffe2f4bfcb5c7ab3311eae5e9816c7808188f Mon Sep 17 00:00:00 2001 From: Neil Parley Date: Mon, 15 Aug 2016 12:26:49 +0100 Subject: [PATCH 4/6] Fix lint error. --- pandas/tools/plotting.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pandas/tools/plotting.py b/pandas/tools/plotting.py index ea25db6c3f6fd..dcb2a556921e7 100644 --- a/pandas/tools/plotting.py +++ b/pandas/tools/plotting.py @@ -1627,6 +1627,7 @@ def _compute_plot_data_with_dt(self): self.data = numeric_dt__data + class ScatterPlot(PlanePlot): _kind = 'scatter' From 13de504231fe3d934d210e49bd524f2db700b665 Mon Sep 17 00:00:00 2001 From: Neil Parley Date: Sun, 9 Apr 2017 16:30:01 +0100 Subject: [PATCH 5/6] Addressed comments --- pandas/core/generic.py | 4 ++-- pandas/core/internals.py | 2 +- pandas/tools/plotting.py | 35 ++++++++++++++++------------------- 3 files changed, 19 insertions(+), 22 deletions(-) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index bde076153a4d4..d27363e2cf558 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -3017,8 +3017,8 @@ def _get_numeric_data(self): def _get_bool_data(self): return self._constructor(self._data.get_bool_data()).__finalize__(self) - def _get_dt_data(self): - return self._constructor(self._data.get_dt_data()).__finalize__(self) + def _get_datetime_data(self): + return self._constructor(self._data.get_datetime_data()).__finalize__(self) # ---------------------------------------------------------------------- # Internal Interface Methods diff --git a/pandas/core/internals.py b/pandas/core/internals.py index 5077ab461208a..59014727ae188 100644 --- a/pandas/core/internals.py +++ b/pandas/core/internals.py @@ -3354,7 +3354,7 @@ def get_numeric_data(self, copy=False): self._consolidate_inplace() return self.combine([b for b in self.blocks if b.is_numeric], copy) - def get_dt_data(self, copy=False): + def get_datetime_data(self, copy=False): """ Parameters ---------- diff --git a/pandas/tools/plotting.py b/pandas/tools/plotting.py index dcb2a556921e7..adef4b725c459 100644 --- a/pandas/tools/plotting.py +++ b/pandas/tools/plotting.py @@ -1602,7 +1602,21 @@ def _post_plot_logic(self, ax, data): ax.set_ylabel(pprint_thing(y)) ax.set_xlabel(pprint_thing(x)) - def _compute_plot_data_with_dt(self): + +class ScatterPlot(PlanePlot): + _kind = 'scatter' + + def __init__(self, data, x, y, s=None, c=None, **kwargs): + if s is None: + # hide the matplotlib default for size, in case we want to change + # the handling of this argument later + s = 20 + super(ScatterPlot, self).__init__(data, x, y, s=s, **kwargs) + if is_integer(c) and not self.data.columns.holds_integer(): + c = self.data.columns[c] + self.c = c + + def _compute_plot_data(self): data = self.data if isinstance(data, Series): @@ -1612,7 +1626,7 @@ def _compute_plot_data_with_dt(self): data = data.to_frame(name=label) numeric_dt__data = data._convert(datetime=True)._get_numeric_data() - time_data = data._convert(datetime=True)._get_dt_data() + time_data = data._convert(datetime=True)._get_datetime_data() numeric_dt__data = numeric_dt__data.join(time_data) try: @@ -1627,23 +1641,6 @@ def _compute_plot_data_with_dt(self): self.data = numeric_dt__data - -class ScatterPlot(PlanePlot): - _kind = 'scatter' - - def __init__(self, data, x, y, s=None, c=None, **kwargs): - if s is None: - # hide the matplotlib default for size, in case we want to change - # the handling of this argument later - s = 20 - super(ScatterPlot, self).__init__(data, x, y, s=s, **kwargs) - if is_integer(c) and not self.data.columns.holds_integer(): - c = self.data.columns[c] - self.c = c - - def _compute_plot_data(self): - self._compute_plot_data_with_dt() - def _make_plot(self): x, y, c, data = self.x, self.y, self.c, self.data ax = self.axes[0] From cbf3c7345440aa6f4b2c8a79e9a67bf91a7ab591 Mon Sep 17 00:00:00 2001 From: Neil Parley Date: Sun, 9 Apr 2017 17:56:14 +0100 Subject: [PATCH 6/6] Reduce line length --- pandas/core/generic.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index d27363e2cf558..1a9a9a4d8b67f 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -3018,7 +3018,8 @@ def _get_bool_data(self): return self._constructor(self._data.get_bool_data()).__finalize__(self) def _get_datetime_data(self): - return self._constructor(self._data.get_datetime_data()).__finalize__(self) + return self._constructor( + self._data.get_datetime_data()).__finalize__(self) # ---------------------------------------------------------------------- # Internal Interface Methods