Skip to content

Commit 4b04f80

Browse files
committed
Fix plotting a DataFrame without 0 in the index
This commit prevents the KeyError raised when DataFrame.plot() is called with xerr or yerr being a Series or DataFrame whose index doesn't include 0. The error comes from matplotlib code which tries to access xerr[0] or yerr[0], so to solve the problem, we convert xerr and yerr from Pandas objects to NumPy ndarrays before sending them through to matplotlib. This is a different instance of the same type of problem in Github issues #4493 and #6127 (and perhaps others).
1 parent 3733fa9 commit 4b04f80

File tree

2 files changed

+31
-2
lines changed

2 files changed

+31
-2
lines changed

pandas/tests/test_graphics.py

+27
Original file line numberDiff line numberDiff line change
@@ -3369,6 +3369,33 @@ def _check_errorbar_color(containers, expected, has_err='has_xerr'):
33693369
self._check_has_errorbars(ax, xerr=0, yerr=1)
33703370
_check_errorbar_color(ax.containers, 'green', has_err='has_yerr')
33713371

3372+
def test_errorbar_no_zero_in_index(self):
3373+
a = [1,2,3]
3374+
s = Series(a, index=a)
3375+
ax = _check_plot_works(s.plot, yerr=s)
3376+
self._check_has_errorbars(ax, xerr=0, yerr=1)
3377+
ax = _check_plot_works(s.plot, xerr=s)
3378+
self._check_has_errorbars(ax, xerr=1, yerr=0)
3379+
ax = _check_plot_works(s.plot, xerr=s, yerr=s)
3380+
self._check_has_errorbars(ax, xerr=1, yerr=1)
3381+
3382+
df = DataFrame(a, index=a)
3383+
ax = _check_plot_works(df.plot, yerr=df)
3384+
self._check_has_errorbars(ax, xerr=0, yerr=1)
3385+
ax = _check_plot_works(df.plot, xerr=df)
3386+
self._check_has_errorbars(ax, xerr=1, yerr=0)
3387+
ax = _check_plot_works(df.plot, xerr=df, yerr=df)
3388+
self._check_has_errorbars(ax, xerr=1, yerr=1)
3389+
3390+
a = np.array([[4,5,6], [7,8,9]])
3391+
df = DataFrame(a, index=[1,2], columns=['col1', 'col2', 'col3'])
3392+
ax = _check_plot_works(df.plot, yerr=df)
3393+
self._check_has_errorbars(ax, xerr=0, yerr=3)
3394+
ax = _check_plot_works(df.plot, xerr=df)
3395+
self._check_has_errorbars(ax, xerr=3, yerr=0)
3396+
ax = _check_plot_works(df.plot, xerr=df, yerr=df)
3397+
self._check_has_errorbars(ax, xerr=3, yerr=3)
3398+
33723399
@slow
33733400
def test_sharex_and_ax(self):
33743401
# https://github.com/pydata/pandas/issues/9737

pandas/tools/plotting.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -1465,7 +1465,7 @@ def match_labels(data, e):
14651465
return err
14661466

14671467
def _get_errorbars(self, label=None, index=None, xerr=True, yerr=True):
1468-
from pandas import DataFrame
1468+
from pandas import DataFrame, Series
14691469
errors = {}
14701470

14711471
for kw, flag in zip(['xerr', 'yerr'], [xerr, yerr]):
@@ -1480,7 +1480,9 @@ def _get_errorbars(self, label=None, index=None, xerr=True, yerr=True):
14801480
elif index is not None and err is not None:
14811481
err = err[index]
14821482

1483-
if err is not None:
1483+
if isinstance(err, (DataFrame, Series)):
1484+
errors[kw] = err.as_matrix()
1485+
elif err is not None:
14841486
errors[kw] = err
14851487
return errors
14861488

0 commit comments

Comments
 (0)