Skip to content

COMPAT/TST Matplotlib 2.0 compatability #13662

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Aug 22, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions ci/install_travis.sh
Original file line number Diff line number Diff line change
Expand Up @@ -138,5 +138,9 @@ else

fi

if [ "$JOB_NAME" == "34_slow" ]; then
conda install -c conda-forge/label/rc -c conda-forge matplotlib
fi

echo "done"
exit 0
2 changes: 1 addition & 1 deletion doc/source/whatsnew/v0.19.0.txt
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@ Other enhancements

- Added documentation to :ref:`I/O<io.dtypes>` regarding the perils of reading in columns with mixed dtypes and how to handle it (:issue:`13746`)
- Raise ``ImportError`` in the sql functions when ``sqlalchemy`` is not installed and a connection string is used (:issue:`11920`).

- Compatibility with matplotlib 2.0. Older versions of pandas should also work with matplotlib 2.0 (:issue:`13333`)

.. _whatsnew_0190.api:

Expand Down
18 changes: 14 additions & 4 deletions pandas/tests/plotting/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ def setUp(self):
self.mpl_ge_1_3_1 = plotting._mpl_ge_1_3_1()
self.mpl_ge_1_4_0 = plotting._mpl_ge_1_4_0()
self.mpl_ge_1_5_0 = plotting._mpl_ge_1_5_0()
self.mpl_ge_2_0_0 = plotting._mpl_ge_2_0_0()

if self.mpl_ge_1_4_0:
self.bp_n_objects = 7
Expand All @@ -64,6 +65,11 @@ def setUp(self):
else:
self.polycollection_factor = 1

if self.mpl_ge_2_0_0:
self.default_figsize = (6.4, 4.8)
else:
self.default_figsize = (8.0, 6.0)
self.default_tick_position = 'left' if self.mpl_ge_2_0_0 else 'default'
# common test data
from pandas import read_csv
path = os.path.join(os.path.dirname(curpath()), 'data', 'iris.csv')
Expand Down Expand Up @@ -189,7 +195,9 @@ def _check_colors(self, collections, linecolors=None, facecolors=None,
"""

from matplotlib.lines import Line2D
from matplotlib.collections import Collection, PolyCollection
from matplotlib.collections import (
Collection, PolyCollection, LineCollection
)
conv = self.colorconverter
if linecolors is not None:

Expand All @@ -203,7 +211,7 @@ def _check_colors(self, collections, linecolors=None, facecolors=None,
result = patch.get_color()
# Line2D may contains string color expression
result = conv.to_rgba(result)
elif isinstance(patch, PolyCollection):
elif isinstance(patch, (PolyCollection, LineCollection)):
result = tuple(patch.get_edgecolor()[0])
else:
result = patch.get_edgecolor()
Expand Down Expand Up @@ -318,7 +326,7 @@ def _check_ax_scales(self, axes, xaxis='linear', yaxis='linear'):
self.assertEqual(ax.yaxis.get_scale(), yaxis)

def _check_axes_shape(self, axes, axes_num=None, layout=None,
figsize=(8.0, 6.0)):
figsize=None):
"""
Check expected number of axes is drawn in expected layout

Expand All @@ -333,6 +341,8 @@ def _check_axes_shape(self, axes, axes_num=None, layout=None,
figsize : tuple
expected figsize. default is matplotlib default
"""
if figsize is None:
figsize = self.default_figsize
visible_axes = self._flatten_visible(axes)

if axes_num is not None:
Expand All @@ -346,7 +356,7 @@ def _check_axes_shape(self, axes, axes_num=None, layout=None,
self.assertEqual(result, layout)

self.assert_numpy_array_equal(
np.round(visible_axes[0].figure.get_size_inches()),
visible_axes[0].figure.get_size_inches(),
np.array(figsize, dtype=np.float64))

def _get_axes_layout(self, axes):
Expand Down
16 changes: 11 additions & 5 deletions pandas/tests/plotting/test_datetimelike.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class TestTSPlot(TestPlotBase):

def setUp(self):
TestPlotBase.setUp(self)

freq = ['S', 'T', 'H', 'D', 'W', 'M', 'Q', 'A']
idx = [period_range('12/31/1999', freq=x, periods=100) for x in freq]
self.period_ser = [Series(np.random.randn(len(x)), x) for x in idx]
Expand Down Expand Up @@ -122,7 +123,8 @@ def test_tsplot(self):
_check_plot_works(s.plot, ax=ax)

ax = ts.plot(style='k')
self.assertEqual((0., 0., 0.), ax.get_lines()[0].get_color())
color = (0., 0., 0., 1) if self.mpl_ge_2_0_0 else (0., 0., 0.)
self.assertEqual(color, ax.get_lines()[0].get_color())

def test_both_style_and_color(self):
import matplotlib.pyplot as plt # noqa
Expand Down Expand Up @@ -575,7 +577,8 @@ def test_secondary_y(self):
plt.close(fig)

ax2 = ser2.plot()
self.assertEqual(ax2.get_yaxis().get_ticks_position(), 'default')
self.assertEqual(ax2.get_yaxis().get_ticks_position(),
self.default_tick_position)
plt.close(ax2.get_figure())

ax = ser2.plot()
Expand Down Expand Up @@ -605,7 +608,8 @@ def test_secondary_y_ts(self):
plt.close(fig)

ax2 = ser2.plot()
self.assertEqual(ax2.get_yaxis().get_ticks_position(), 'default')
self.assertEqual(ax2.get_yaxis().get_ticks_position(),
self.default_tick_position)
plt.close(ax2.get_figure())

ax = ser2.plot()
Expand Down Expand Up @@ -639,15 +643,17 @@ def test_secondary_frame(self):
df = DataFrame(np.random.randn(5, 3), columns=['a', 'b', 'c'])
axes = df.plot(secondary_y=['a', 'c'], subplots=True)
self.assertEqual(axes[0].get_yaxis().get_ticks_position(), 'right')
self.assertEqual(axes[1].get_yaxis().get_ticks_position(), 'default')
self.assertEqual(axes[1].get_yaxis().get_ticks_position(),
self.default_tick_position)
self.assertEqual(axes[2].get_yaxis().get_ticks_position(), 'right')

@slow
def test_secondary_bar_frame(self):
df = DataFrame(np.random.randn(5, 3), columns=['a', 'b', 'c'])
axes = df.plot(kind='bar', secondary_y=['a', 'c'], subplots=True)
self.assertEqual(axes[0].get_yaxis().get_ticks_position(), 'right')
self.assertEqual(axes[1].get_yaxis().get_ticks_position(), 'default')
self.assertEqual(axes[1].get_yaxis().get_ticks_position(),
self.default_tick_position)
self.assertEqual(axes[2].get_yaxis().get_ticks_position(), 'right')

def test_mixed_freq_regular_first(self):
Expand Down
76 changes: 57 additions & 19 deletions pandas/tests/plotting/test_frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import pandas as pd
from pandas import (Series, DataFrame, MultiIndex, PeriodIndex, date_range,
bdate_range)
from pandas.types.api import is_list_like
from pandas.compat import (range, lrange, StringIO, lmap, lzip, u, zip, PY3)
from pandas.formats.printing import pprint_thing
import pandas.util.testing as tm
Expand Down Expand Up @@ -952,9 +953,12 @@ def test_scatter_colors(self):
with tm.assertRaises(TypeError):
df.plot.scatter(x='a', y='b', c='c', color='green')

default_colors = self._maybe_unpack_cycler(self.plt.rcParams)

ax = df.plot.scatter(x='a', y='b', c='c')
tm.assert_numpy_array_equal(ax.collections[0].get_facecolor()[0],
np.array([0, 0, 1, 1], dtype=np.float64))
tm.assert_numpy_array_equal(
ax.collections[0].get_facecolor()[0],
np.array(self.colorconverter.to_rgba(default_colors[0])))

ax = df.plot.scatter(x='a', y='b', color='white')
tm.assert_numpy_array_equal(ax.collections[0].get_facecolor()[0],
Expand Down Expand Up @@ -1623,6 +1627,8 @@ def test_line_colors_and_styles_subplots(self):

axes = df.plot(subplots=True)
for ax, c in zip(axes, list(default_colors)):
if self.mpl_ge_2_0_0:
c = [c]
self._check_colors(ax.get_lines(), linecolors=c)
tm.close()

Expand Down Expand Up @@ -1703,9 +1709,14 @@ def test_area_colors(self):
self._check_colors(poly, facecolors=custom_colors)

handles, labels = ax.get_legend_handles_labels()
# legend is stored as Line2D, thus check linecolors
linehandles = [x for x in handles if not isinstance(x, PolyCollection)]
self._check_colors(linehandles, linecolors=custom_colors)
if self.mpl_ge_1_5_0:
self._check_colors(handles, facecolors=custom_colors)
else:
# legend is stored as Line2D, thus check linecolors
linehandles = [x for x in handles
if not isinstance(x, PolyCollection)]
self._check_colors(linehandles, linecolors=custom_colors)

for h in handles:
self.assertTrue(h.get_alpha() is None)
tm.close()
Expand All @@ -1717,8 +1728,12 @@ def test_area_colors(self):
self._check_colors(poly, facecolors=jet_colors)

handles, labels = ax.get_legend_handles_labels()
linehandles = [x for x in handles if not isinstance(x, PolyCollection)]
self._check_colors(linehandles, linecolors=jet_colors)
if self.mpl_ge_1_5_0:
self._check_colors(handles, facecolors=jet_colors)
else:
linehandles = [x for x in handles
if not isinstance(x, PolyCollection)]
self._check_colors(linehandles, linecolors=jet_colors)
for h in handles:
self.assertTrue(h.get_alpha() is None)
tm.close()
Expand All @@ -1731,8 +1746,12 @@ def test_area_colors(self):
self._check_colors(poly, facecolors=jet_with_alpha)

handles, labels = ax.get_legend_handles_labels()
# Line2D can't have alpha in its linecolor
self._check_colors(handles[:len(jet_colors)], linecolors=jet_colors)
if self.mpl_ge_1_5_0:
linecolors = jet_with_alpha
else:
# Line2D can't have alpha in its linecolor
linecolors = jet_colors
self._check_colors(handles[:len(jet_colors)], linecolors=linecolors)
for h in handles:
self.assertEqual(h.get_alpha(), 0.5)

Expand Down Expand Up @@ -1855,7 +1874,10 @@ def test_kde_colors_and_styles_subplots(self):
@slow
def test_boxplot_colors(self):
def _check_colors(bp, box_c, whiskers_c, medians_c, caps_c='k',
fliers_c='b'):
fliers_c=None):
# TODO: outside this func?
if fliers_c is None:
fliers_c = 'k' if self.mpl_ge_2_0_0 else 'b'
self._check_colors(bp['boxes'],
linecolors=[box_c] * len(bp['boxes']))
self._check_colors(bp['whiskers'],
Expand Down Expand Up @@ -2232,16 +2254,24 @@ def test_errorbar_asymmetrical(self):
np.random.seed(0)
err = np.random.rand(3, 2, 5)

data = np.random.randn(5, 3)
df = DataFrame(data)
# each column is [0, 1, 2, 3, 4], [3, 4, 5, 6, 7]...
df = DataFrame(np.arange(15).reshape(3, 5)).T
data = df.values

ax = df.plot(yerr=err, xerr=err / 2)

self.assertEqual(ax.lines[7].get_ydata()[0], data[0, 1] - err[1, 0, 0])
self.assertEqual(ax.lines[8].get_ydata()[0], data[0, 1] + err[1, 1, 0])
if self.mpl_ge_2_0_0:
yerr_0_0 = ax.collections[1].get_paths()[0].vertices[:, 1]
expected_0_0 = err[0, :, 0] * np.array([-1, 1])
tm.assert_almost_equal(yerr_0_0, expected_0_0)
else:
self.assertEqual(ax.lines[7].get_ydata()[0],
data[0, 1] - err[1, 0, 0])
self.assertEqual(ax.lines[8].get_ydata()[0],
data[0, 1] + err[1, 1, 0])

self.assertEqual(ax.lines[5].get_xdata()[0], -err[1, 0, 0] / 2)
self.assertEqual(ax.lines[6].get_xdata()[0], err[1, 1, 0] / 2)
self.assertEqual(ax.lines[5].get_xdata()[0], -err[1, 0, 0] / 2)
self.assertEqual(ax.lines[6].get_xdata()[0], err[1, 1, 0] / 2)

with tm.assertRaises(ValueError):
df.plot(yerr=err.T)
Expand Down Expand Up @@ -2277,9 +2307,17 @@ def test_errorbar_scatter(self):
self._check_has_errorbars(ax, xerr=1, yerr=1)

def _check_errorbar_color(containers, expected, has_err='has_xerr'):
errs = [c.lines[1][0]
for c in ax.containers if getattr(c, has_err, False)]
self._check_colors(errs, linecolors=[expected] * len(errs))
lines = []
errs = [c.lines
for c in ax.containers if getattr(c, has_err, False)][0]
for el in errs:
if is_list_like(el):
lines.extend(el)
else:
lines.append(el)
err_lines = [x for x in lines if x in ax.collections]
self._check_colors(
err_lines, linecolors=np.array([expected] * len(err_lines)))

# GH 8081
df = DataFrame(
Expand Down
10 changes: 8 additions & 2 deletions pandas/tests/plotting/test_misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,10 @@ def test_scatter_matrix_axis(self):
axes0_labels = axes[0][0].yaxis.get_majorticklabels()

# GH 5662
expected = ['-2', '-1', '0', '1', '2']
if self.mpl_ge_2_0_0:
expected = ['-2', '0', '2']
else:
expected = ['-2', '-1', '0', '1', '2']
self._check_text_labels(axes0_labels, expected)
self._check_ticks_props(
axes, xlabelsize=8, xrot=90, ylabelsize=8, yrot=0)
Expand All @@ -115,7 +118,10 @@ def test_scatter_matrix_axis(self):
axes = _check_plot_works(scatter_matrix, filterwarnings='always',
frame=df, range_padding=.1)
axes0_labels = axes[0][0].yaxis.get_majorticklabels()
expected = ['-1.2', '-1.0', '-0.8', '-0.6', '-0.4', '-0.2', '0.0']
if self.mpl_ge_2_0_0:
expected = ['-1.0', '-0.5', '0.0']
else:
expected = ['-1.2', '-1.0', '-0.8', '-0.6', '-0.4', '-0.2', '0.0']
self._check_text_labels(axes0_labels, expected)
self._check_ticks_props(
axes, xlabelsize=8, xrot=90, ylabelsize=8, yrot=0)
Expand Down
5 changes: 3 additions & 2 deletions pandas/tests/plotting/test_series.py
Original file line number Diff line number Diff line change
Expand Up @@ -218,12 +218,13 @@ def test_bar_log(self):
expected = np.hstack((1.0e-04, expected, 1.0e+01))

ax = Series([0.1, 0.01, 0.001]).plot(log=True, kind='bar')
self.assertEqual(ax.get_ylim(), (0.001, 0.10000000000000001))
ymax = 0.12589254117941673 if self.mpl_ge_2_0_0 else .10000000000000001
self.assertEqual(ax.get_ylim(), (0.001, ymax))
tm.assert_numpy_array_equal(ax.yaxis.get_ticklocs(), expected)
tm.close()

ax = Series([0.1, 0.01, 0.001]).plot(log=True, kind='barh')
self.assertEqual(ax.get_xlim(), (0.001, 0.10000000000000001))
self.assertEqual(ax.get_xlim(), (0.001, ymax))
tm.assert_numpy_array_equal(ax.xaxis.get_ticklocs(), expected)

@slow
Expand Down
8 changes: 8 additions & 0 deletions pandas/tools/plotting.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,14 @@ def _mpl_ge_1_5_0():
except ImportError:
return False


def _mpl_ge_2_0_0():
try:
import matplotlib
return matplotlib.__version__ >= LooseVersion('2.0')
except ImportError:
return False

if _mpl_ge_1_5_0():
# Compat with mp 1.5, which uses cycler.
import cycler
Expand Down