From 1c3f6f8ede5cfe6456b6095d956274eb883a6dc3 Mon Sep 17 00:00:00 2001 From: Maoz Gelbart <13831112+MaozGelbart@users.noreply.github.com> Date: Thu, 27 Feb 2020 18:26:14 +0200 Subject: [PATCH] MNT: Remove unused code paths (#1965) * TST: pandas==1.0 compat * Remove old matplotlib paths * Remove old scipy paths * Remove _set_spine_position The behavior that this function addressed has been resolved in matplotlib 1.4: https://github.com/matplotlib/matplotlib/pull/3104 * Clean more old compat code paths Removed a few try/except clauses aimed to cover old matplotlib/pandas versions that are no longer supported. * Remove __future__ imports * Improve code style (cherry picked from commit 5498cdb2f145b15a85adac0c8ff233656f52a943) --- doc/sphinxext/gallery_generator.py | 1 - seaborn/algorithms.py | 1 - seaborn/axisgrid.py | 22 +---- seaborn/categorical.py | 21 +--- seaborn/distributions.py | 7 +- seaborn/matrix.py | 1 - seaborn/miscplot.py | 1 - seaborn/palettes.py | 1 - seaborn/rcmod.py | 43 +++----- seaborn/regression.py | 7 +- seaborn/relational.py | 7 +- seaborn/tests/test_axisgrid.py | 4 - seaborn/tests/test_categorical.py | 153 +++++++++++------------------ seaborn/tests/test_palettes.py | 14 +-- seaborn/tests/test_rcmod.py | 14 --- seaborn/tests/test_regression.py | 7 -- seaborn/tests/test_relational.py | 3 +- seaborn/tests/test_utils.py | 123 +++++++++++------------ seaborn/utils.py | 34 +------ seaborn/widgets.py | 1 - 20 files changed, 147 insertions(+), 318 deletions(-) diff --git a/doc/sphinxext/gallery_generator.py b/doc/sphinxext/gallery_generator.py index bfbe3de2a7..710e1ffddb 100644 --- a/doc/sphinxext/gallery_generator.py +++ b/doc/sphinxext/gallery_generator.py @@ -4,7 +4,6 @@ Lightly modified from the mpld3 project. """ -from __future__ import division import os import os.path as op import re diff --git a/seaborn/algorithms.py b/seaborn/algorithms.py index 6b31ac846f..a47d2099eb 100644 --- a/seaborn/algorithms.py +++ b/seaborn/algorithms.py @@ -1,5 +1,4 @@ """Algorithms to support fitting routines in seaborn plotting functions.""" -from __future__ import division import numbers import numpy as np import warnings diff --git a/seaborn/axisgrid.py b/seaborn/axisgrid.py index 3a367b9373..4c18599030 100644 --- a/seaborn/axisgrid.py +++ b/seaborn/axisgrid.py @@ -1,6 +1,4 @@ -from __future__ import division from itertools import product -from distutils.version import LooseVersion import warnings from textwrap import dedent @@ -232,9 +230,6 @@ def __init__(self, data, row=None, col=None, hue=None, col_wrap=None, margin_titles=False, xlim=None, ylim=None, subplot_kws=None, gridspec_kws=None, size=None): - MPL_GRIDSPEC_VERSION = LooseVersion('1.4') - OLD_MPL = LooseVersion(mpl.__version__) < MPL_GRIDSPEC_VERSION - # Handle deprecations if size is not None: height = size @@ -315,12 +310,6 @@ def __init__(self, data, row=None, col=None, hue=None, col_wrap=None, subplot_kw=subplot_kws, gridspec_kw=gridspec_kws) - if OLD_MPL: - kwargs.pop('gridspec_kw', None) - if gridspec_kws: - msg = "gridspec module only available in mpl >= {}" - warnings.warn(msg.format(MPL_GRIDSPEC_VERSION)) - fig, axes = plt.subplots(nrow, ncol, **kwargs) self.axes = axes @@ -446,14 +435,14 @@ def __init__(self, data, row=None, col=None, hue=None, col_wrap=None, {margin_titles} {{x, y}}lim: tuples, optional Limits for each of the axes on each facet (only relevant when - share{{x, y}} is True. + share{{x, y}} is True). subplot_kws : dict, optional Dictionary of keyword arguments passed to matplotlib subplot(s) methods. gridspec_kws : dict, optional Dictionary of keyword arguments passed to matplotlib's ``gridspec`` - module (via ``plt.subplots``). Requires matplotlib >= 1.4 and is - ignored if ``col_wrap`` is not ``None``. + module (via ``plt.subplots``). Ignored if ``col_wrap`` is not + ``None``. See Also -------- @@ -1303,10 +1292,7 @@ def __init__(self, data, hue=None, hue_order=None, palette=None, if corner: hide_indices = np.triu_indices_from(axes, 1) for i, j in zip(*hide_indices): - try: - axes[i, j].remove() - except NotImplementedError: # Problem on old matplotlibs? - axes[i, j].set_axis_off() + axes[i, j].remove() axes[i, j] = None self.fig = fig diff --git a/seaborn/categorical.py b/seaborn/categorical.py index a27a0842a3..66e553d01b 100644 --- a/seaborn/categorical.py +++ b/seaborn/categorical.py @@ -1,4 +1,3 @@ -from __future__ import division from textwrap import dedent import colorsys import numpy as np @@ -325,15 +324,7 @@ def infer_orient(self, x, y, orient=None): orient = str(orient) def is_categorical(s): - try: - # Correct way, but does not exist in older Pandas - try: - return pd.api.types.is_categorical_dtype(s) - except AttributeError: - return pd.core.common.is_categorical_dtype(s) - except AttributeError: - # Also works, but feels hackier - return str(s.dtype) == "categorical" + return pd.api.types.is_categorical_dtype(s) def is_not_numeric(s): try: @@ -709,15 +700,7 @@ def estimate_densities(self, bw, cut, scale, scale_hue, gridsize): def fit_kde(self, x, bw): """Estimate a KDE for a vector of data with flexible bandwidth.""" - # Allow for the use of old scipy where `bw` is fixed - try: - kde = stats.gaussian_kde(x, bw) - except TypeError: - kde = stats.gaussian_kde(x) - if bw != "scott": # scipy default - msg = ("Ignoring bandwidth choice, " - "please upgrade scipy to use a different bandwidth.") - warnings.warn(msg, UserWarning) + kde = stats.gaussian_kde(x, bw) # Extract the numeric bandwidth from the KDE object bw_used = kde.factor diff --git a/seaborn/distributions.py b/seaborn/distributions.py index 0a06643272..b97f6d584d 100644 --- a/seaborn/distributions.py +++ b/seaborn/distributions.py @@ -1,5 +1,4 @@ """Plotting functions for visualizing distributions.""" -from __future__ import division import numpy as np from scipy import stats import pandas as pd @@ -8,7 +7,6 @@ import matplotlib.transforms as tx from matplotlib.collections import LineCollection import warnings -from distutils.version import LooseVersion try: import statsmodels.nonparametric.api as smnp @@ -216,10 +214,7 @@ def distplot(a, bins=None, hist=True, kde=True, rug=False, fit=None, if bins is None: bins = min(_freedman_diaconis_bins(a), 50) hist_kws.setdefault("alpha", 0.4) - if LooseVersion(mpl.__version__) < LooseVersion("2.2"): - hist_kws.setdefault("normed", norm_hist) - else: - hist_kws.setdefault("density", norm_hist) + hist_kws.setdefault("density", norm_hist) orientation = "horizontal" if vertical else "vertical" hist_color = hist_kws.pop("color", color) diff --git a/seaborn/matrix.py b/seaborn/matrix.py index b76e42eb4b..c6f7ab22c4 100644 --- a/seaborn/matrix.py +++ b/seaborn/matrix.py @@ -1,5 +1,4 @@ """Functions to visualize matrices of data.""" -from __future__ import division import itertools import warnings diff --git a/seaborn/miscplot.py b/seaborn/miscplot.py index 512091f2ca..935b140acb 100644 --- a/seaborn/miscplot.py +++ b/seaborn/miscplot.py @@ -1,4 +1,3 @@ -from __future__ import division import numpy as np import matplotlib as mpl import matplotlib.pyplot as plt diff --git a/seaborn/palettes.py b/seaborn/palettes.py index 40afd4a99f..5aa18cbdc7 100644 --- a/seaborn/palettes.py +++ b/seaborn/palettes.py @@ -1,4 +1,3 @@ -from __future__ import division import colorsys from itertools import cycle diff --git a/seaborn/rcmod.py b/seaborn/rcmod.py index 45cea6ca32..7225fddf03 100644 --- a/seaborn/rcmod.py +++ b/seaborn/rcmod.py @@ -1,15 +1,11 @@ """Control plot style and scaling using the matplotlib rcParams interface.""" -from distutils.version import LooseVersion +import warnings import functools import matplotlib as mpl -import warnings +from cycler import cycler from . import palettes, _orig_rc_params -mpl_ge_150 = LooseVersion(mpl.__version__) >= '1.5.0' -mpl_ge_2 = LooseVersion(mpl.__version__) >= '2.0' - - __all__ = ["set", "reset_defaults", "reset_orig", "axes_style", "set_style", "plotting_context", "set_context", "set_palette"] @@ -37,30 +33,23 @@ "lines.solid_capstyle", "patch.edgecolor", + "patch.force_edgecolor", "image.cmap", "font.family", "font.sans-serif", - ] - -if mpl_ge_2: + "xtick.bottom", + "xtick.top", + "ytick.left", + "ytick.right", - _style_keys.extend([ + "axes.spines.left", + "axes.spines.bottom", + "axes.spines.right", + "axes.spines.top", - "patch.force_edgecolor", - - "xtick.bottom", - "xtick.top", - "ytick.left", - "ytick.right", - - "axes.spines.left", - "axes.spines.bottom", - "axes.spines.right", - "axes.spines.top", - - ]) + ] _context_keys = [ @@ -540,12 +529,8 @@ def set_palette(palette, n_colors=None, desat=None, color_codes=False): """ colors = palettes.color_palette(palette, n_colors, desat) - if mpl_ge_150: - from cycler import cycler - cyl = cycler('color', colors) - mpl.rcParams['axes.prop_cycle'] = cyl - else: - mpl.rcParams["axes.color_cycle"] = list(colors) + cyl = cycler('color', colors) + mpl.rcParams['axes.prop_cycle'] = cyl mpl.rcParams["patch.facecolor"] = colors[0] if color_codes: try: diff --git a/seaborn/regression.py b/seaborn/regression.py index 0e8281ec4c..ae52c942a0 100644 --- a/seaborn/regression.py +++ b/seaborn/regression.py @@ -1,5 +1,4 @@ """Plotting functions for linear models (broadly construed).""" -from __future__ import division import copy from textwrap import dedent import warnings @@ -420,11 +419,7 @@ def lineplot(self, ax, kws): # Draw the regression line and confidence interval line, = ax.plot(grid, yhat, **kws) - try: - line.sticky_edges.x[:] = edges # Prevent mpl from adding margin - except AttributeError: - msg = "Cannot set sticky_edges; requires newer matplotlib." - warnings.warn(msg, UserWarning) + line.sticky_edges.x[:] = edges # Prevent mpl from adding margin if err_bands is not None: ax.fill_between(grid, *err_bands, facecolor=fill_color, alpha=.15) diff --git a/seaborn/relational.py b/seaborn/relational.py index b0cd8fefd7..d19736b138 100644 --- a/seaborn/relational.py +++ b/seaborn/relational.py @@ -1,7 +1,5 @@ -from __future__ import division from itertools import product from textwrap import dedent -from distutils.version import LooseVersion import warnings import numpy as np @@ -23,10 +21,7 @@ class _RelationalPlotter(object): - if LooseVersion(mpl.__version__) >= "2.0": - default_markers = ["o", "X", "s", "P", "D", "^", "v", "p"] - else: - default_markers = ["o", "s", "D", "^", "v", "p"] + default_markers = ["o", "X", "s", "P", "D", "^", "v", "p"] default_dashes = ["", (4, 1.5), (1, 1), (3, 1, 1.5, 1), (5, 1, 1, 1), (5, 1, 2, 1, 2, 1)] diff --git a/seaborn/tests/test_axisgrid.py b/seaborn/tests/test_axisgrid.py index 3acbfb96da..4f2a62248b 100644 --- a/seaborn/tests/test_axisgrid.py +++ b/seaborn/tests/test_axisgrid.py @@ -14,8 +14,6 @@ except ImportError: import pandas.util.testing as tm -from distutils.version import LooseVersion - from .. import axisgrid as ag from .. import rcmod from ..palettes import color_palette @@ -831,8 +829,6 @@ def test_specific_nonsquare_axes_with_array(self): nt.assert_equal(g.y_vars, list(y_vars)) nt.assert_true(not g.square_grid) - @pytest.mark.xfail(LooseVersion(mpl.__version__) < "1.5", - reason="Expected failure on older matplotlib") def test_corner(self): plot_vars = ["x", "y", "z"] diff --git a/seaborn/tests/test_categorical.py b/seaborn/tests/test_categorical.py index 8d8e584a16..01194043f1 100644 --- a/seaborn/tests/test_categorical.py +++ b/seaborn/tests/test_categorical.py @@ -1,13 +1,10 @@ import numpy as np import pandas as pd -import scipy from scipy import stats, spatial import matplotlib as mpl import matplotlib.pyplot as plt from matplotlib.colors import rgb2hex -from distutils.version import LooseVersion - import pytest import nose.tools as nt import numpy.testing as npt @@ -16,10 +13,6 @@ from .. import palettes -pandas_has_categoricals = LooseVersion(pd.__version__) >= "0.15" -mpl_barplot_change = LooseVersion("2.0.1") - - class CategoricalFixture(object): """Test boxplot (also base class for things like violinplots).""" rs = np.random.RandomState(30) @@ -231,24 +224,23 @@ def test_longform_groupby(self): npt.assert_array_equal(hues, self.h[self.g == group]) # Test categorical grouping data - if pandas_has_categoricals: - df = self.df.copy() - df.g = df.g.astype("category") + df = self.df.copy() + df.g = df.g.astype("category") - # Test that horizontal orientation is automatically detected - p.establish_variables("y", "g", "h", data=df) - nt.assert_equal(len(p.plot_data), 3) - nt.assert_equal(len(p.plot_hues), 3) - nt.assert_equal(p.orient, "h") - nt.assert_equal(p.value_label, "y") - nt.assert_equal(p.group_label, "g") - nt.assert_equal(p.hue_title, "h") + # Test that horizontal orientation is automatically detected + p.establish_variables("y", "g", "h", data=df) + nt.assert_equal(len(p.plot_data), 3) + nt.assert_equal(len(p.plot_hues), 3) + nt.assert_equal(p.orient, "h") + nt.assert_equal(p.value_label, "y") + nt.assert_equal(p.group_label, "g") + nt.assert_equal(p.hue_title, "h") - for group, vals in zip(["a", "b", "c"], p.plot_data): - npt.assert_array_equal(vals, self.y[self.g == group]) + for group, vals in zip(["a", "b", "c"], p.plot_data): + npt.assert_array_equal(vals, self.y[self.g == group]) - for group, hues in zip(["a", "b", "c"], p.plot_hues): - npt.assert_array_equal(hues, self.h[self.g == group]) + for group, hues in zip(["a", "b", "c"], p.plot_hues): + npt.assert_array_equal(hues, self.h[self.g == group]) # Test grouped data that matches on index p1 = cat._CategoricalPlotter() @@ -299,20 +291,19 @@ def test_order(self): npt.assert_array_equal(vals, self.y[self.g == group]) # Test inferred order from a grouped input with categorical groups - if pandas_has_categoricals: - df = self.df.copy() - df.g = df.g.astype("category") - df.g = df.g.cat.reorder_categories(["c", "b", "a"]) - p.establish_variables("g", "y", data=df) - nt.assert_equal(p.group_names, ["c", "b", "a"]) + df = self.df.copy() + df.g = df.g.astype("category") + df.g = df.g.cat.reorder_categories(["c", "b", "a"]) + p.establish_variables("g", "y", data=df) + nt.assert_equal(p.group_names, ["c", "b", "a"]) - for group, vals in zip(["c", "b", "a"], p.plot_data): - npt.assert_array_equal(vals, self.y[self.g == group]) + for group, vals in zip(["c", "b", "a"], p.plot_data): + npt.assert_array_equal(vals, self.y[self.g == group]) - df.g = (df.g.cat.add_categories("d") - .cat.reorder_categories(["c", "b", "d", "a"])) - p.establish_variables("g", "y", data=df) - nt.assert_equal(p.group_names, ["c", "b", "d", "a"]) + df.g = (df.g.cat.add_categories("d") + .cat.reorder_categories(["c", "b", "d", "a"])) + p.establish_variables("g", "y", data=df) + nt.assert_equal(p.group_names, ["c", "b", "d", "a"]) def test_hue_order(self): @@ -328,17 +319,16 @@ def test_hue_order(self): nt.assert_equal(p.hue_names, ["n", "m"]) # Test inferred hue order from a categorical hue input - if pandas_has_categoricals: - df = self.df.copy() - df.h = df.h.astype("category") - df.h = df.h.cat.reorder_categories(["n", "m"]) - p.establish_variables("g", "y", "h", data=df) - nt.assert_equal(p.hue_names, ["n", "m"]) - - df.h = (df.h.cat.add_categories("o") - .cat.reorder_categories(["o", "m", "n"])) - p.establish_variables("g", "y", "h", data=df) - nt.assert_equal(p.hue_names, ["o", "m", "n"]) + df = self.df.copy() + df.h = df.h.astype("category") + df.h = df.h.cat.reorder_categories(["n", "m"]) + p.establish_variables("g", "y", "h", data=df) + nt.assert_equal(p.hue_names, ["n", "m"]) + + df.h = (df.h.cat.add_categories("o") + .cat.reorder_categories(["o", "m", "n"])) + p.establish_variables("g", "y", "h", data=df) + nt.assert_equal(p.hue_names, ["o", "m", "n"]) def test_plot_units(self): @@ -367,13 +357,12 @@ def test_infer_orient(self): with nt.assert_raises(ValueError): p.infer_orient(cats, cats) - if pandas_has_categoricals: - cats = pd.Series([0, 1, 2] * 10, dtype="category") - nt.assert_equal(p.infer_orient(cats, nums), "v") - nt.assert_equal(p.infer_orient(nums, cats), "h") + cats = pd.Series([0, 1, 2] * 10, dtype="category") + nt.assert_equal(p.infer_orient(cats, nums), "v") + nt.assert_equal(p.infer_orient(nums, cats), "h") - with nt.assert_raises(ValueError): - p.infer_orient(cats, cats) + with nt.assert_raises(ValueError): + p.infer_orient(cats, cats) def test_default_palettes(self): @@ -1164,25 +1153,17 @@ def test_kde_fit(self): data = self.y data_std = data.std(ddof=1) - # Bandwidth behavior depends on scipy version - if LooseVersion(scipy.__version__) < "0.11": - # Test ignoring custom bandwidth on old scipy - kde, bw = p.fit_kde(self.y, .2) - nt.assert_is_instance(kde, stats.gaussian_kde) - nt.assert_equal(kde.factor, kde.scotts_factor()) - - else: - # Test reference rule bandwidth - kde, bw = p.fit_kde(data, "scott") - nt.assert_is_instance(kde, stats.gaussian_kde) - nt.assert_equal(kde.factor, kde.scotts_factor()) - nt.assert_equal(bw, kde.scotts_factor() * data_std) - - # Test numeric scale factor - kde, bw = p.fit_kde(self.y, .2) - nt.assert_is_instance(kde, stats.gaussian_kde) - nt.assert_equal(kde.factor, .2) - nt.assert_equal(bw, .2 * data_std) + # Test reference rule bandwidth + kde, bw = p.fit_kde(data, "scott") + nt.assert_is_instance(kde, stats.gaussian_kde) + nt.assert_equal(kde.factor, kde.scotts_factor()) + nt.assert_equal(bw, kde.scotts_factor() * data_std) + + # Test numeric scale factor + kde, bw = p.fit_kde(self.y, .2) + nt.assert_is_instance(kde, stats.gaussian_kde) + nt.assert_equal(kde.factor, .2) + nt.assert_equal(bw, .2 * data_std) def test_draw_to_density(self): @@ -1982,12 +1963,8 @@ def test_draw_vertical_bars(self): for bar, pos, stat in zip(ax.patches, positions, p.statistic): nt.assert_equal(bar.get_x(), pos) nt.assert_equal(bar.get_width(), p.width) - if mpl.__version__ >= mpl_barplot_change: - nt.assert_equal(bar.get_y(), 0) - nt.assert_equal(bar.get_height(), stat) - else: - nt.assert_equal(bar.get_y(), min(0, stat)) - nt.assert_equal(bar.get_height(), abs(stat)) + nt.assert_equal(bar.get_y(), 0) + nt.assert_equal(bar.get_height(), stat) def test_draw_horizontal_bars(self): @@ -2008,12 +1985,8 @@ def test_draw_horizontal_bars(self): for bar, pos, stat in zip(ax.patches, positions, p.statistic): nt.assert_equal(bar.get_y(), pos) nt.assert_equal(bar.get_height(), p.width) - if mpl.__version__ >= mpl_barplot_change: - nt.assert_equal(bar.get_x(), 0) - nt.assert_equal(bar.get_width(), stat) - else: - nt.assert_equal(bar.get_x(), min(0, stat)) - nt.assert_equal(bar.get_width(), abs(stat)) + nt.assert_equal(bar.get_x(), 0) + nt.assert_equal(bar.get_width(), stat) def test_draw_nested_vertical_bars(self): @@ -2039,12 +2012,8 @@ def test_draw_nested_vertical_bars(self): nt.assert_almost_equal(bar.get_width(), p.nested_width) for bar, stat in zip(ax.patches, p.statistic.T.flat): - if LooseVersion(mpl.__version__) >= mpl_barplot_change: - nt.assert_almost_equal(bar.get_y(), 0) - nt.assert_almost_equal(bar.get_height(), stat) - else: - nt.assert_almost_equal(bar.get_y(), min(0, stat)) - nt.assert_almost_equal(bar.get_height(), abs(stat)) + nt.assert_almost_equal(bar.get_y(), 0) + nt.assert_almost_equal(bar.get_height(), stat) def test_draw_nested_horizontal_bars(self): @@ -2070,12 +2039,8 @@ def test_draw_nested_horizontal_bars(self): nt.assert_almost_equal(bar.get_height(), p.nested_width) for bar, stat in zip(ax.patches, p.statistic.T.flat): - if LooseVersion(mpl.__version__) >= mpl_barplot_change: - nt.assert_almost_equal(bar.get_x(), 0) - nt.assert_almost_equal(bar.get_width(), stat) - else: - nt.assert_almost_equal(bar.get_x(), min(0, stat)) - nt.assert_almost_equal(bar.get_width(), abs(stat)) + nt.assert_almost_equal(bar.get_x(), 0) + nt.assert_almost_equal(bar.get_width(), stat) def test_draw_missing_bars(self): diff --git a/seaborn/tests/test_palettes.py b/seaborn/tests/test_palettes.py index 229a72cb32..0761897dea 100644 --- a/seaborn/tests/test_palettes.py +++ b/seaborn/tests/test_palettes.py @@ -11,9 +11,6 @@ from ..external import husl from ..colors import xkcd_rgb, crayons -from distutils.version import LooseVersion -mpl_ge_150 = LooseVersion(mpl.__version__) >= '1.5.0' - class TestColorPalettes(object): @@ -360,9 +357,8 @@ def test_preserved_palette_length(self): def test_get_color_cycle(self): - if mpl_ge_150: - colors = [(1., 0., 0.), (0, 1., 0.)] - prop_cycle = plt.cycler(color=colors) - with plt.rc_context({"axes.prop_cycle": prop_cycle}): - result = utils.get_color_cycle() - assert result == colors + colors = [(1., 0., 0.), (0, 1., 0.)] + prop_cycle = plt.cycler(color=colors) + with plt.rc_context({"axes.prop_cycle": prop_cycle}): + result = utils.get_color_cycle() + assert result == colors diff --git a/seaborn/tests/test_rcmod.py b/seaborn/tests/test_rcmod.py index 290d171f80..eb6110272e 100644 --- a/seaborn/tests/test_rcmod.py +++ b/seaborn/tests/test_rcmod.py @@ -1,6 +1,5 @@ import numpy as np import matplotlib as mpl -from distutils.version import LooseVersion import nose import matplotlib.pyplot as plt import nose.tools as nt @@ -112,22 +111,12 @@ def test_set_with_palette(self): def test_reset_defaults(self): - # Changes to the rc parameters make this test hard to manage - # on older versions of matplotlib, so we'll skip it - if LooseVersion(mpl.__version__) < LooseVersion("1.3"): - raise nose.SkipTest - rcmod.reset_defaults() self.assert_rc_params(mpl.rcParamsDefault) rcmod.set() def test_reset_orig(self): - # Changes to the rc parameters make this test hard to manage - # on older versions of matplotlib, so we'll skip it - if LooseVersion(mpl.__version__) < LooseVersion("1.3"): - raise nose.SkipTest - rcmod.reset_orig() self.assert_rc_params(mpl.rcParamsOrig) rcmod.set() @@ -249,9 +238,6 @@ def test_set_serif_font(self): def test_different_sans_serif(self): - if LooseVersion(mpl.__version__) < LooseVersion("1.4"): - raise nose.SkipTest - rcmod.set() rcmod.set_style(rc={"font.sans-serif": ["Verdana"]}) diff --git a/seaborn/tests/test_regression.py b/seaborn/tests/test_regression.py index bf44b58f7a..315380d840 100644 --- a/seaborn/tests/test_regression.py +++ b/seaborn/tests/test_regression.py @@ -10,8 +10,6 @@ import pandas.testing as pdt except ImportError: import pandas.util.testing as pdt -from nose import SkipTest -from distutils.version import LooseVersion try: import statsmodels.regression.linear_model as smlm @@ -561,9 +559,6 @@ def test_lmplot_markers(self): def test_lmplot_marker_linewidths(self): - if mpl.__version__ == "1.4.2": - raise SkipTest - g = lm.lmplot("x", "y", data=self.df, hue="h", fit_reg=False, markers=["o", "+"]) c = g.axes[0, 0].collections @@ -623,8 +618,6 @@ def test_three_point_colors(self): npt.assert_almost_equal(color[0, :3], (1, 0, 0)) - @pytest.mark.skipif(LooseVersion(mpl.__version__) < "2.0", - reason="not supported on old matplotlib") def test_regplot_xlim(self): f, ax = plt.subplots() diff --git a/seaborn/tests/test_relational.py b/seaborn/tests/test_relational.py index 262bc4ee99..435950eb6d 100644 --- a/seaborn/tests/test_relational.py +++ b/seaborn/tests/test_relational.py @@ -1,4 +1,3 @@ -from __future__ import division from itertools import product import warnings import numpy as np @@ -122,7 +121,7 @@ def missing_df(self): @pytest.fixture def null_column(self): - return pd.Series(index=np.arange(20)) + return pd.Series(index=np.arange(20), dtype='float64') def test_wide_df_variables(self, wide_df): diff --git a/seaborn/tests/test_utils.py b/seaborn/tests/test_utils.py index 559cc06457..e86aa4c843 100644 --- a/seaborn/tests/test_utils.py +++ b/seaborn/tests/test_utils.py @@ -1,6 +1,5 @@ """Tests for plotting utilities.""" import tempfile -import shutil import numpy as np import pandas as pd @@ -27,9 +26,6 @@ from ..utils import get_dataset_names, load_dataset, _network -pandas_has_categoricals = LooseVersion(pd.__version__) >= "0.15" - - a_norm = np.random.randn(100) @@ -329,17 +325,16 @@ def test_categorical_order(): out = utils.categorical_order(pd.Series(y)) nt.assert_equal(out, [1, 2, 3, 4, 5]) - if pandas_has_categoricals: - x = pd.Categorical(x, order) - out = utils.categorical_order(x) - nt.assert_equal(out, list(x.categories)) + x = pd.Categorical(x, order) + out = utils.categorical_order(x) + nt.assert_equal(out, list(x.categories)) - x = pd.Series(x) - out = utils.categorical_order(x) - nt.assert_equal(out, list(x.cat.categories)) + x = pd.Series(x) + out = utils.categorical_order(x) + nt.assert_equal(out, list(x.cat.categories)) - out = utils.categorical_order(x, ["b", "a"]) - nt.assert_equal(out, ["b", "a"]) + out = utils.categorical_order(x, ["b", "a"]) + nt.assert_equal(out, ["b", "a"]) x = ["a", np.nan, "c", "c", "b", "a", "d"] out = utils.categorical_order(x) @@ -379,59 +374,55 @@ def test_locator_to_legend_entries(): assert str_levels == ['1e-07', '1e-05', '1e-03', '1e-01', '10'] -if LooseVersion(pd.__version__) >= "0.15": - - def check_load_dataset(name): - ds = load_dataset(name, cache=False) - assert(isinstance(ds, pd.DataFrame)) - - def check_load_cached_dataset(name): - # Test the cacheing using a temporary file. - # With Python 3.2+, we could use the tempfile.TemporaryDirectory() - # context manager instead of this try...finally statement - tmpdir = tempfile.mkdtemp() - try: - # download and cache - ds = load_dataset(name, cache=True, data_home=tmpdir) - - # use cached version - ds2 = load_dataset(name, cache=True, data_home=tmpdir) - pdt.assert_frame_equal(ds, ds2) - - finally: - shutil.rmtree(tmpdir) - - @_network(url="https://github.com/mwaskom/seaborn-data") - def test_get_dataset_names(): - if not BeautifulSoup: - raise nose.SkipTest("No BeautifulSoup available for parsing html") - names = get_dataset_names() - assert(len(names) > 0) - assert(u"titanic" in names) - - @_network(url="https://github.com/mwaskom/seaborn-data") - def test_load_datasets(): - if not BeautifulSoup: - raise nose.SkipTest("No BeautifulSoup available for parsing html") - - # Heavy test to verify that we can load all available datasets - for name in get_dataset_names(): - # unfortunately @network somehow obscures this generator so it - # does not get in effect, so we need to call explicitly - # yield check_load_dataset, name - check_load_dataset(name) - - @_network(url="https://github.com/mwaskom/seaborn-data") - def test_load_cached_datasets(): - if not BeautifulSoup: - raise nose.SkipTest("No BeautifulSoup available for parsing html") - - # Heavy test to verify that we can load all available datasets - for name in get_dataset_names(): - # unfortunately @network somehow obscures this generator so it - # does not get in effect, so we need to call explicitly - # yield check_load_dataset, name - check_load_cached_dataset(name) +def check_load_dataset(name): + ds = load_dataset(name, cache=False) + assert(isinstance(ds, pd.DataFrame)) + + +def check_load_cached_dataset(name): + # Test the cacheing using a temporary file. + with tempfile.TemporaryDirectory() as tmpdir: + # download and cache + ds = load_dataset(name, cache=True, data_home=tmpdir) + + # use cached version + ds2 = load_dataset(name, cache=True, data_home=tmpdir) + pdt.assert_frame_equal(ds, ds2) + + +@_network(url="https://github.com/mwaskom/seaborn-data") +def test_get_dataset_names(): + if not BeautifulSoup: + raise nose.SkipTest("No BeautifulSoup available for parsing html") + names = get_dataset_names() + assert(len(names) > 0) + assert("titanic" in names) + + +@_network(url="https://github.com/mwaskom/seaborn-data") +def test_load_datasets(): + if not BeautifulSoup: + raise nose.SkipTest("No BeautifulSoup available for parsing html") + + # Heavy test to verify that we can load all available datasets + for name in get_dataset_names(): + # unfortunately @network somehow obscures this generator so it + # does not get in effect, so we need to call explicitly + # yield check_load_dataset, name + check_load_dataset(name) + + +@_network(url="https://github.com/mwaskom/seaborn-data") +def test_load_cached_datasets(): + if not BeautifulSoup: + raise nose.SkipTest("No BeautifulSoup available for parsing html") + + # Heavy test to verify that we can load all available datasets + for name in get_dataset_names(): + # unfortunately @network somehow obscures this generator so it + # does not get in effect, so we need to call explicitly + # yield check_load_dataset, name + check_load_cached_dataset(name) def test_relative_luminance(): diff --git a/seaborn/utils.py b/seaborn/utils.py index 7e54788d63..0aae2c25c0 100644 --- a/seaborn/utils.py +++ b/seaborn/utils.py @@ -1,5 +1,4 @@ """Small plotting-related utility functions.""" -from __future__ import print_function, division import colorsys import os @@ -228,7 +227,7 @@ def despine(fig=None, ax=None, top=True, right=True, left=False, val = offset.get(side, 0) except AttributeError: val = offset - _set_spine_position(ax_i.spines[side], ('outward', val)) + ax_i.spines[side].set_position(('outward', val)) # Potentially move the ticks if left and not right: @@ -288,24 +287,6 @@ def despine(fig=None, ax=None, top=True, right=True, left=False, ax_i.set_yticks(newticks) -def _set_spine_position(spine, position): - """ - Set the spine's position without resetting an associated axis. - - As of matplotlib v. 1.0.0, if a spine has an associated axis, then - spine.set_position() calls axis.cla(), which resets locators, formatters, - etc. We temporarily replace that call with axis.reset_ticks(), which is - sufficient for our purposes. - """ - axis = spine.axis - if axis is not None: - cla = axis.cla - axis.cla = axis.reset_ticks - spine.set_position(position) - if axis is not None: - axis.cla = cla - - def _kde_support(data, bw, gridsize, cut, clip): """Establish support for a kernel density estimate.""" support_min = max(data.min() - bw * cut, clip[0]) @@ -575,18 +556,7 @@ def get_view_interval(self): def get_color_cycle(): """Return the list of colors in the current matplotlib color cycle.""" - try: - cyl = mpl.rcParams['axes.prop_cycle'] - try: - # matplotlib 1.5 verifies that axes.prop_cycle *is* a cycler - # but no garuantee that there's a `color` key. - # so users could have a custom rcParmas w/ no color... - return [x['color'] for x in cyl] - except KeyError: - pass - except KeyError: - pass - return mpl.rcParams['axes.color_cycle'] + return [x['color'] for x in mpl.rcParams['axes.prop_cycle']] def relative_luminance(color): diff --git a/seaborn/widgets.py b/seaborn/widgets.py index 6976f61bf4..2f6735c447 100644 --- a/seaborn/widgets.py +++ b/seaborn/widgets.py @@ -1,4 +1,3 @@ -from __future__ import division import numpy as np import matplotlib.pyplot as plt from matplotlib.colors import LinearSegmentedColormap