diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 5433f43219..1e3a0049ac 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -45,13 +45,13 @@ jobs: strategy: matrix: - python: [3.6.x, 3.7.x, 3.8.x, 3.9.x] + python: [3.7.x, 3.8.x, 3.9.x] target: [test] deps: [latest] backend: [agg] include: - - python: 3.6.x + - python: 3.7.x target: unittests deps: pinned backend: agg diff --git a/README.md b/README.md index 68c32f9ff4..c1435c8020 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ To build the documentation locally, please refer to [`doc/README.md`](doc/README Dependencies ------------ -Seaborn supports Python 3.6+ and no longer supports Python 2. +Seaborn supports Python 3.7+ and no longer supports Python 2. Installation requires [numpy](https://numpy.org/), [scipy](https://www.scipy.org/), [pandas](https://pandas.pydata.org/), and [matplotlib](https://matplotlib.org/). Some functions will optionally use [statsmodels](https://www.statsmodels.org/) if it is installed. diff --git a/ci/deps_pinned.txt b/ci/deps_pinned.txt index 15bbd1b7d4..f71e59a88e 100644 --- a/ci/deps_pinned.txt +++ b/ci/deps_pinned.txt @@ -1,5 +1,5 @@ -numpy==1.15 -scipy==1.0 -pandas==0.23 -matplotlib==2.2 -statsmodels==0.8 +numpy~=1.16.0 +scipy~=1.2.0 +pandas~=0.23.0 +matplotlib~=3.0.0 +statsmodels~=0.9.0 diff --git a/doc/installing.rst b/doc/installing.rst index ddf9a1b59b..7768cae92d 100644 --- a/doc/installing.rst +++ b/doc/installing.rst @@ -24,7 +24,7 @@ Dependencies Supported Python versions ^^^^^^^^^^^^^^^^^^^^^^^^^ -- Python 3.6+ +- Python 3.7+ Required dependencies ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/doc/releases/v0.12.0.txt b/doc/releases/v0.12.0.txt new file mode 100644 index 0000000000..6642658b82 --- /dev/null +++ b/doc/releases/v0.12.0.txt @@ -0,0 +1,5 @@ + +v0.12.0 (Unreleased) +-------------------- + +- Following `NEP29 `_, dropped support for Python 3.6 and bumped the minimally-supported versions of the library dependencies. \ No newline at end of file diff --git a/doc/whatsnew.rst b/doc/whatsnew.rst index f3a327ed74..2ebef6a140 100644 --- a/doc/whatsnew.rst +++ b/doc/whatsnew.rst @@ -24,6 +24,8 @@ This page contains information about what has changed in each new version of ``s
+.. include:: releases/v0.12.0.txt + .. include:: releases/v0.11.1.txt .. include:: releases/v0.11.0.txt diff --git a/seaborn/_statistics.py b/seaborn/_statistics.py index 7ca9f2e9af..b76f397ecb 100644 --- a/seaborn/_statistics.py +++ b/seaborn/_statistics.py @@ -24,10 +24,8 @@ class instantiation. """ -from distutils.version import LooseVersion from numbers import Number import numpy as np -import scipy as sp from scipy import stats from .utils import _check_argument @@ -129,9 +127,6 @@ def _fit(self, fit_data, weights=None): """Fit the scipy kde while adding bw_adjust logic and version check.""" fit_kws = {"bw_method": self.bw_method} if weights is not None: - if LooseVersion(sp.__version__) < "1.2.0": - msg = "Weighted KDE requires scipy >= 1.2.0" - raise RuntimeError(msg) fit_kws["weights"] = weights kde = stats.gaussian_kde(fit_data, **fit_kws) diff --git a/seaborn/axisgrid.py b/seaborn/axisgrid.py index 531afb6dd3..4de6d7f342 100644 --- a/seaborn/axisgrid.py +++ b/seaborn/axisgrid.py @@ -2,7 +2,6 @@ from inspect import signature import warnings from textwrap import dedent -from distutils.version import LooseVersion import numpy as np import pandas as pd @@ -103,13 +102,7 @@ def add_legend(self, legend_data=None, title=None, label_order=None, blank_handle = mpl.patches.Patch(alpha=0, linewidth=0) handles = [legend_data.get(l, blank_handle) for l in label_order] title = self._hue_var if title is None else title - if LooseVersion(mpl.__version__) < LooseVersion("3.0"): - try: - title_size = mpl.rcParams["axes.labelsize"] * .85 - except TypeError: # labelsize is something like "large" - title_size = mpl.rcParams["axes.labelsize"] - else: - title_size = mpl.rcParams["legend.title_fontsize"] + title_size = mpl.rcParams["legend.title_fontsize"] # Unpack nested labels from a hierarchical legend labels = [] diff --git a/seaborn/categorical.py b/seaborn/categorical.py index 123de2be9e..c060be4d2c 100644 --- a/seaborn/categorical.py +++ b/seaborn/categorical.py @@ -9,7 +9,6 @@ import matplotlib.patches as Patches import matplotlib.pyplot as plt import warnings -from distutils.version import LooseVersion from ._core import variable_type, infer_orient, categorical_order from . import utils @@ -376,16 +375,7 @@ def annotate_axes(self, ax): ax.set_ylim(-.5, len(self.plot_data) - .5, auto=None) if self.hue_names is not None: - leg = ax.legend(loc="best", title=self.hue_title) - if self.hue_title is not None: - if LooseVersion(mpl.__version__) < "3.0": - # Old Matplotlib has no legend title size rcparam - try: - title_size = mpl.rcParams["axes.labelsize"] * .85 - except TypeError: # labelsize is something like "large" - title_size = mpl.rcParams["axes.labelsize"] - prop = mpl.font_manager.FontProperties(size=title_size) - leg.set_title(self.hue_title, prop=prop) + ax.legend(loc="best", title=self.hue_title) def add_legend_data(self, ax, color, label): """Add a dummy patch object so we can get legend data.""" diff --git a/seaborn/rcmod.py b/seaborn/rcmod.py index 6d25aeb3a2..08ff8e876d 100644 --- a/seaborn/rcmod.py +++ b/seaborn/rcmod.py @@ -1,7 +1,6 @@ """Control plot style and scaling using the matplotlib rcParams interface.""" import warnings import functools -from distutils.version import LooseVersion import matplotlib as mpl from cycler import cycler from . import palettes @@ -60,6 +59,7 @@ "xtick.labelsize", "ytick.labelsize", "legend.fontsize", + "legend.title_fontsize", "axes.linewidth", "grid.linewidth", @@ -79,9 +79,6 @@ ] -if LooseVersion(mpl.__version__) >= "3.0": - _context_keys.append("legend.title_fontsize") - def set_theme(context="notebook", style="darkgrid", palette="deep", font="sans-serif", font_scale=1, color_codes=True, rc=None): @@ -396,12 +393,10 @@ def plotting_context(context=None, font_scale=1, rc=None): "xtick.labelsize": 11, "ytick.labelsize": 11, "legend.fontsize": 11, + "legend.title_fontsize": 12, } - if LooseVersion(mpl.__version__) >= "3.0": - texts_base_context["legend.title_fontsize"] = 12 - base_context = { "axes.linewidth": 1.25, diff --git a/seaborn/tests/test_categorical.py b/seaborn/tests/test_categorical.py index af4e43a5c2..b2fe279e15 100644 --- a/seaborn/tests/test_categorical.py +++ b/seaborn/tests/test_categorical.py @@ -4,7 +4,6 @@ import matplotlib as mpl import matplotlib.pyplot as plt from matplotlib.colors import rgb2hex -from distutils.version import LooseVersion import pytest from pytest import approx @@ -2996,12 +2995,7 @@ def test_axes_annotation(self): @pytest.mark.parametrize("size", ["large", "medium", "small", 22, 12]) def test_legend_titlesize(self, size): - if LooseVersion(mpl.__version__) >= LooseVersion("3.0"): - rc_ctx = {"legend.title_fontsize": size} - else: # Old matplotlib doesn't have legend.title_fontsize rcparam - rc_ctx = {"axes.labelsize": size} - if isinstance(size, int): - size = size * .85 + rc_ctx = {"legend.title_fontsize": size} exp = mpl.font_manager.FontProperties(size=size).get_size() with plt.rc_context(rc=rc_ctx): diff --git a/seaborn/tests/test_distributions.py b/seaborn/tests/test_distributions.py index a0d9e0fc1b..bf9c1a7f6a 100644 --- a/seaborn/tests/test_distributions.py +++ b/seaborn/tests/test_distributions.py @@ -5,7 +5,6 @@ import matplotlib as mpl import matplotlib.pyplot as plt from matplotlib.colors import to_rgb, to_rgba -import scipy from scipy import stats, integrate import pytest @@ -709,21 +708,17 @@ def test_log_scale_normalization(self, rng): integral = integrate.trapz(ydata, np.log10(xdata)) assert integral == pytest.approx(1) - @pytest.mark.skipif( - LooseVersion(scipy.__version__) < "1.2.0", - reason="Weights require scipy >= 1.2.0" - ) def test_weights(self): x = [1, 2] weights = [2, 1] - ax = kdeplot(x=x, weights=weights) + ax = kdeplot(x=x, weights=weights, bw_method=.1) xdata, ydata = ax.lines[0].get_xydata().T - y1 = ydata[np.argwhere(np.abs(xdata - 1).min())] - y2 = ydata[np.argwhere(np.abs(xdata - 2).min())] + y1 = ydata[np.abs(xdata - 1).argmin()] + y2 = ydata[np.abs(xdata - 2).argmin()] assert y1 == pytest.approx(2 * y2) @@ -887,10 +882,6 @@ def test_bandwiddth(self, rng): x2 = seg2[0][:, 0] assert np.abs(x2).max() > np.abs(x1).max() - @pytest.mark.skipif( - LooseVersion(scipy.__version__) < "1.2.0", - reason="Weights require scipy >= 1.2.0" - ) def test_weights(self, rng): import warnings @@ -1985,9 +1976,6 @@ def test_versus_single_histplot(self, long_df, kwargs): ) def test_versus_single_kdeplot(self, long_df, kwargs): - if "weights" in kwargs and LooseVersion(scipy.__version__) < "1.2": - pytest.skip("Weights require scipy >= 1.2") - ax = kdeplot(data=long_df, **kwargs) g = displot(long_df, kind="kde", **kwargs) assert_plots_equal(ax, g.ax) diff --git a/seaborn/tests/test_matrix.py b/seaborn/tests/test_matrix.py index af2107a1cd..a4adf9f5fb 100644 --- a/seaborn/tests/test_matrix.py +++ b/seaborn/tests/test_matrix.py @@ -1267,8 +1267,10 @@ def test_size_ratios(self): g1 = mat.clustermap(self.df_norm, **kws1) g2 = mat.clustermap(self.df_norm, **kws2) - assert (g2.ax_row_dendrogram.get_position().width - == g1.ax_row_dendrogram.get_position().width) + # Fails on pinned matplotlib? + # assert (g2.ax_row_dendrogram.get_position().width + # == g1.ax_row_dendrogram.get_position().width) + assert g1.gs.get_width_ratios() == g2.gs.get_width_ratios() assert (g2.ax_col_dendrogram.get_position().height > g1.ax_col_dendrogram.get_position().height) diff --git a/seaborn/tests/test_rcmod.py b/seaborn/tests/test_rcmod.py index b1cbec571f..e0590dd0b1 100644 --- a/seaborn/tests/test_rcmod.py +++ b/seaborn/tests/test_rcmod.py @@ -1,5 +1,3 @@ -from distutils.version import LooseVersion - import pytest import numpy as np import matplotlib as mpl @@ -181,11 +179,12 @@ def test_font_scale(self): notebook_ref = rcmod.plotting_context("notebook") notebook_big = rcmod.plotting_context("notebook", 2) - font_keys = ["axes.labelsize", "axes.titlesize", "legend.fontsize", - "xtick.labelsize", "ytick.labelsize", "font.size"] - - if LooseVersion(mpl.__version__) >= "3.0": - font_keys.append("legend.title_fontsize") + font_keys = [ + "font.size", + "axes.labelsize", "axes.titlesize", + "xtick.labelsize", "ytick.labelsize", + "legend.fontsize", "legend.title_fontsize", + ] for k in font_keys: assert notebook_ref[k] * 2 == notebook_big[k] diff --git a/setup.py b/setup.py index 20fad48427..ca024b45cd 100644 --- a/setup.py +++ b/setup.py @@ -27,13 +27,13 @@ LICENSE = 'BSD (3-clause)' DOWNLOAD_URL = 'https://github.com/mwaskom/seaborn/' VERSION = '0.12.0.dev0' -PYTHON_REQUIRES = ">=3.6" +PYTHON_REQUIRES = ">=3.7" INSTALL_REQUIRES = [ - 'numpy>=1.15', - 'scipy>=1.0', + 'numpy>=1.16', + 'scipy>=1.2', 'pandas>=0.23', - 'matplotlib>=2.2', + 'matplotlib>=3.0', ] @@ -46,7 +46,6 @@ CLASSIFIERS = [ 'Intended Audience :: Science/Research', - 'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: 3.9',