diff --git a/ci/azure-macos-35.yaml b/ci/azure-macos-35.yaml index a36f748ded812..6ccdc79d11b27 100644 --- a/ci/azure-macos-35.yaml +++ b/ci/azure-macos-35.yaml @@ -8,10 +8,10 @@ dependencies: - html5lib - jinja2 - lxml - - matplotlib + - matplotlib=2.2.0 - nomkl - numexpr - - numpy=1.10.4 + - numpy=1.12.0 - openpyxl=2.5.5 - pytables - python=3.5* diff --git a/ci/azure-windows-27.yaml b/ci/azure-windows-27.yaml index bcd9ddee1715e..d48a9ba986a93 100644 --- a/ci/azure-windows-27.yaml +++ b/ci/azure-windows-27.yaml @@ -10,7 +10,7 @@ dependencies: - html5lib - jinja2=2.8 - lxml - - matplotlib + - matplotlib=2.0.1 - numexpr - numpy=1.12* - openpyxl=2.5.5 diff --git a/ci/azure/macos.yml b/ci/azure/macos.yml index 9bfaef04ea2fa..fb10d89731f26 100644 --- a/ci/azure/macos.yml +++ b/ci/azure/macos.yml @@ -9,7 +9,7 @@ jobs: strategy: maxParallel: 11 matrix: - py35_np_110: + py35_np_120: ENV_FILE: ci/azure-macos-35.yaml CONDA_PY: "35" CONDA_ENV: pandas diff --git a/ci/azure/windows-py27.yml b/ci/azure/windows-py27.yml index 10251bc03b8dc..8718cc849b7a8 100644 --- a/ci/azure/windows-py27.yml +++ b/ci/azure/windows-py27.yml @@ -9,7 +9,7 @@ jobs: strategy: maxParallel: 11 matrix: - py36_np14: + py36_np121: ENV_FILE: ci/azure-windows-27.yaml CONDA_PY: "27" CONDA_ENV: pandas diff --git a/ci/circle-27-compat.yaml b/ci/circle-27-compat.yaml index 84ec7e20fc8f1..5b726304cf414 100644 --- a/ci/circle-27-compat.yaml +++ b/ci/circle-27-compat.yaml @@ -3,18 +3,18 @@ channels: - defaults - conda-forge dependencies: - - bottleneck=1.0.0 + - bottleneck=1.2.0 - cython=0.28.2 - jinja2=2.8 - - numexpr=2.4.4 # we test that we correctly don't use an unsupported numexpr - - numpy=1.9.3 + - numexpr=2.6.1 + - numpy=1.12.0 - openpyxl=2.5.5 - psycopg2 - - pytables=3.2.2 + - pytables=3.4.2 - python-dateutil=2.5.0 - python=2.7* - pytz=2013b - - scipy=0.14.0 + - scipy=0.18.1 - sqlalchemy=0.7.8 - xlrd=0.9.2 - xlsxwriter=0.5.2 diff --git a/ci/requirements-optional-conda.txt b/ci/requirements-optional-conda.txt index 376fdb1e14e3a..e9afd7a551b6e 100644 --- a/ci/requirements-optional-conda.txt +++ b/ci/requirements-optional-conda.txt @@ -1,6 +1,6 @@ beautifulsoup4>=4.2.1 blosc -bottleneck +bottleneck>=1.2.0 fastparquet feather-format gcsfs @@ -9,17 +9,17 @@ ipython>=5.6.0 ipykernel jinja2 lxml -matplotlib +matplotlib>=2.0.0 nbsphinx -numexpr +numexpr>=2.6.1 openpyxl=2.5.5 pyarrow pymysql -pytables +pytables>=3.4.2 pytest-cov pytest-xdist s3fs -scipy +scipy>=0.18.1 seaborn sqlalchemy statsmodels diff --git a/ci/requirements-optional-pip.txt b/ci/requirements-optional-pip.txt index 09ce8e59a3b46..ebe0c4ca88ee6 100644 --- a/ci/requirements-optional-pip.txt +++ b/ci/requirements-optional-pip.txt @@ -2,7 +2,7 @@ # Do not modify directly beautifulsoup4>=4.2.1 blosc -bottleneck +bottleneck>=1.2.0 fastparquet feather-format gcsfs @@ -11,9 +11,9 @@ ipython>=5.6.0 ipykernel jinja2 lxml -matplotlib +matplotlib>=2.0.0 nbsphinx -numexpr +numexpr>=2.6.1 openpyxl==2.5.5 pyarrow pymysql @@ -21,7 +21,7 @@ tables pytest-cov pytest-xdist s3fs -scipy +scipy>=0.18.1 seaborn sqlalchemy statsmodels diff --git a/ci/travis-27-locale.yaml b/ci/travis-27-locale.yaml index aca65f27d4187..dc5580ae6d287 100644 --- a/ci/travis-27-locale.yaml +++ b/ci/travis-27-locale.yaml @@ -3,11 +3,11 @@ channels: - defaults - conda-forge dependencies: - - bottleneck=1.0.0 + - bottleneck=1.2.0 - cython=0.28.2 - lxml - - matplotlib=1.4.3 - - numpy=1.9.3 + - matplotlib=2.0.0 + - numpy=1.12.0 - openpyxl=2.4.0 - python-dateutil - python-blosc diff --git a/ci/travis-27.yaml b/ci/travis-27.yaml index cc0c5a3192188..f079ac309b97c 100644 --- a/ci/travis-27.yaml +++ b/ci/travis-27.yaml @@ -14,7 +14,7 @@ dependencies: - jemalloc=4.5.0.post - jinja2=2.8 - lxml - - matplotlib + - matplotlib=2.2.2 - mock - nomkl - numexpr diff --git a/doc/source/install.rst b/doc/source/install.rst index 7a846c817aee2..843384b680cf8 100644 --- a/doc/source/install.rst +++ b/doc/source/install.rst @@ -225,7 +225,7 @@ Dependencies ------------ * `setuptools `__: 24.2.0 or higher -* `NumPy `__: 1.9.0 or higher +* `NumPy `__: 1.12.0 or higher * `python-dateutil `__: 2.5.0 or higher * `pytz `__ @@ -236,11 +236,11 @@ Recommended Dependencies * `numexpr `__: for accelerating certain numerical operations. ``numexpr`` uses multiple cores as well as smart chunking and caching to achieve large speedups. - If installed, must be Version 2.4.6 or higher. + If installed, must be Version 2.6.1 or higher. * `bottleneck `__: for accelerating certain types of ``nan`` evaluations. ``bottleneck`` uses specialized cython routines to achieve large speedups. If installed, - must be Version 1.0.0 or higher. + must be Version 1.2.0 or higher. .. note:: @@ -255,9 +255,9 @@ Optional Dependencies * `Cython `__: Only necessary to build development version. Version 0.28.2 or higher. -* `SciPy `__: miscellaneous statistical functions, Version 0.14.0 or higher +* `SciPy `__: miscellaneous statistical functions, Version 0.18.1 or higher * `xarray `__: pandas like handling for > 2 dims, needed for converting Panels to xarray objects. Version 0.7.0 or higher is recommended. -* `PyTables `__: necessary for HDF5-based storage. Version 3.0.0 or higher required, Version 3.2.1 or higher highly recommended. +* `PyTables `__: necessary for HDF5-based storage, Version 3.4.2 or higher * `Feather Format `__: necessary for feather-based storage, version 0.3.1 or higher. * `Apache Parquet `__, either `pyarrow `__ (>= 0.4.1) or `fastparquet `__ (>= 0.0.6) for parquet-based storage. The `snappy `__ and `brotli `__ are available for compression support. * `SQLAlchemy `__: for SQL database support. Version 0.8.1 or higher recommended. Besides SQLAlchemy, you also need a database specific driver. You can find an overview of supported drivers for each SQL dialect in the `SQLAlchemy docs `__. Some common drivers are: @@ -266,7 +266,7 @@ Optional Dependencies * `pymysql `__: for MySQL. * `SQLite `__: for SQLite, this is included in Python's standard library by default. -* `matplotlib `__: for plotting, Version 1.4.3 or higher. +* `matplotlib `__: for plotting, Version 2.0.0 or higher. * For Excel I/O: * `xlrd/xlwt `__: Excel reading (xlrd) and writing (xlwt) diff --git a/doc/source/whatsnew/v0.24.0.txt b/doc/source/whatsnew/v0.24.0.txt index 8a7ff4be78a8a..3053625721560 100644 --- a/doc/source/whatsnew/v0.24.0.txt +++ b/doc/source/whatsnew/v0.24.0.txt @@ -206,8 +206,32 @@ Other Enhancements Backwards incompatible API changes ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + - A newly constructed empty :class:`DataFrame` with integer as the ``dtype`` will now only be cast to ``float64`` if ``index`` is specified (:issue:`22858`) +.. _whatsnew_0240.api_breaking.deps: + +Dependencies have increased minimum versions +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +We have updated our minimum supported versions of dependencies (:issue:`21242`). +If installed, we now require: + ++-----------------+-----------------+----------+ +| Package | Minimum Version | Required | ++=================+=================+==========+ +| numpy | 1.12.0 | X | ++-----------------+-----------------+----------+ +| bottleneck | 1.2.0 | | ++-----------------+-----------------+----------+ +| matplotlib | 2.0.0 | | ++-----------------+-----------------+----------+ +| numexpr | 2.6.1 | | ++-----------------+-----------------+----------+ +| pytables | 3.4.2 | | ++-----------------+-----------------+----------+ +| scipy | 0.18.1 | | ++-----------------+-----------------+----------+ .. _whatsnew_0240.api_breaking.interval_values: diff --git a/pandas/compat/numpy/__init__.py b/pandas/compat/numpy/__init__.py index d4e3def84664b..5e67cf2ee2837 100644 --- a/pandas/compat/numpy/__init__.py +++ b/pandas/compat/numpy/__init__.py @@ -9,19 +9,16 @@ # numpy versioning _np_version = np.__version__ _nlv = LooseVersion(_np_version) -_np_version_under1p10 = _nlv < LooseVersion('1.10') -_np_version_under1p11 = _nlv < LooseVersion('1.11') -_np_version_under1p12 = _nlv < LooseVersion('1.12') _np_version_under1p13 = _nlv < LooseVersion('1.13') _np_version_under1p14 = _nlv < LooseVersion('1.14') _np_version_under1p15 = _nlv < LooseVersion('1.15') -if _nlv < '1.9': +if _nlv < '1.12': raise ImportError('this version of pandas is incompatible with ' - 'numpy < 1.9.0\n' + 'numpy < 1.12.0\n' 'your numpy version is {0}.\n' - 'Please upgrade numpy to >= 1.9.0 to use ' + 'Please upgrade numpy to >= 1.12.0 to use ' 'this pandas version'.format(_np_version)) @@ -43,9 +40,7 @@ def np_datetime64_compat(s, *args, **kwargs): tz-changes in 1.11 that make '2015-01-01 09:00:00Z' show a deprecation warning, when need to pass '2015-01-01 09:00:00' """ - - if not _np_version_under1p11: - s = tz_replacer(s) + s = tz_replacer(s) return np.datetime64(s, *args, **kwargs) @@ -56,23 +51,17 @@ def np_array_datetime64_compat(arr, *args, **kwargs): tz-changes in 1.11 that make '2015-01-01 09:00:00Z' show a deprecation warning, when need to pass '2015-01-01 09:00:00' """ - - if not _np_version_under1p11: - - # is_list_like - if (hasattr(arr, '__iter__') and - not isinstance(arr, string_and_binary_types)): - arr = [tz_replacer(s) for s in arr] - else: - arr = tz_replacer(arr) + # is_list_like + if (hasattr(arr, '__iter__') + and not isinstance(arr, string_and_binary_types)): + arr = [tz_replacer(s) for s in arr] + else: + arr = tz_replacer(arr) return np.array(arr, *args, **kwargs) __all__ = ['np', - '_np_version_under1p10', - '_np_version_under1p11', - '_np_version_under1p12', '_np_version_under1p13', '_np_version_under1p14', '_np_version_under1p15' diff --git a/pandas/core/algorithms.py b/pandas/core/algorithms.py index 4607aba070cfc..cb9ffc4bd0fd5 100644 --- a/pandas/core/algorithms.py +++ b/pandas/core/algorithms.py @@ -30,7 +30,6 @@ ensure_platform_int, ensure_object, ensure_float64, ensure_uint64, ensure_int64) -from pandas.compat.numpy import _np_version_under1p10 from pandas.core.dtypes.missing import isna, na_value_for_dtype from pandas.core import common as com @@ -910,26 +909,12 @@ def checked_add_with_arr(arr, b, arr_mask=None, b_mask=None): ------ OverflowError if any x + y exceeds the maximum or minimum int64 value. """ - def _broadcast(arr_or_scalar, shape): - """ - Helper function to broadcast arrays / scalars to the desired shape. - """ - if _np_version_under1p10: - if is_scalar(arr_or_scalar): - out = np.empty(shape) - out.fill(arr_or_scalar) - else: - out = arr_or_scalar - else: - out = np.broadcast_to(arr_or_scalar, shape) - return out - # For performance reasons, we broadcast 'b' to the new array 'b2' # so that it has the same size as 'arr'. - b2 = _broadcast(b, arr.shape) + b2 = np.broadcast_to(b, arr.shape) if b_mask is not None: # We do the same broadcasting for b_mask as well. - b2_mask = _broadcast(b_mask, arr.shape) + b2_mask = np.broadcast_to(b_mask, arr.shape) else: b2_mask = None diff --git a/pandas/core/computation/check.py b/pandas/core/computation/check.py index 2a9ed0fb9764d..06f72bb36de5c 100644 --- a/pandas/core/computation/check.py +++ b/pandas/core/computation/check.py @@ -2,7 +2,7 @@ from distutils.version import LooseVersion _NUMEXPR_INSTALLED = False -_MIN_NUMEXPR_VERSION = "2.4.6" +_MIN_NUMEXPR_VERSION = "2.6.1" try: import numexpr as ne diff --git a/pandas/core/ops.py b/pandas/core/ops.py index 640b2812d3e85..aff6f17fba2e2 100644 --- a/pandas/core/ops.py +++ b/pandas/core/ops.py @@ -1805,12 +1805,7 @@ def to_series(right): elif right.shape[0] == left.shape[0] and right.shape[1] == 1: # Broadcast across columns - try: - right = np.broadcast_to(right, left.shape) - except AttributeError: - # numpy < 1.10.0 - right = np.tile(right, (1, left.shape[1])) - + right = np.broadcast_to(right, left.shape) right = left._constructor(right, index=left.index, columns=left.columns) diff --git a/pandas/plotting/_compat.py b/pandas/plotting/_compat.py index 5032b259e9831..385e88d58cc26 100644 --- a/pandas/plotting/_compat.py +++ b/pandas/plotting/_compat.py @@ -18,15 +18,8 @@ def inner(): return inner -_mpl_ge_1_2_1 = _mpl_version('1.2.1', operator.ge) -_mpl_le_1_2_1 = _mpl_version('1.2.1', operator.le) -_mpl_ge_1_3_1 = _mpl_version('1.3.1', operator.ge) -_mpl_ge_1_4_0 = _mpl_version('1.4.0', operator.ge) -_mpl_ge_1_4_1 = _mpl_version('1.4.1', operator.ge) -_mpl_ge_1_5_0 = _mpl_version('1.5.0', operator.ge) -_mpl_ge_2_0_0 = _mpl_version('2.0.0', operator.ge) -_mpl_le_2_0_0 = _mpl_version('2.0.0', operator.le) _mpl_ge_2_0_1 = _mpl_version('2.0.1', operator.ge) _mpl_ge_2_1_0 = _mpl_version('2.1.0', operator.ge) _mpl_ge_2_2_0 = _mpl_version('2.2.0', operator.ge) +_mpl_ge_2_2_2 = _mpl_version('2.2.2', operator.ge) _mpl_ge_3_0_0 = _mpl_version('3.0.0', operator.ge) diff --git a/pandas/plotting/_converter.py b/pandas/plotting/_converter.py index 96ea8a542a451..fe773a6054db5 100644 --- a/pandas/plotting/_converter.py +++ b/pandas/plotting/_converter.py @@ -35,8 +35,6 @@ from pandas.tseries.frequencies import FreqGroup from pandas.core.indexes.period import Period, PeriodIndex -from pandas.plotting._compat import _mpl_le_2_0_0 - # constants HOURS_PER_DAY = 24. MIN_PER_HOUR = 60. @@ -371,13 +369,6 @@ def __init__(self, locator, tz=None, defaultfmt='%Y-%m-%d'): if self._tz is dates.UTC: self._tz._utcoffset = self._tz.utcoffset(None) - # For mpl > 2.0 the format strings are controlled via rcparams - # so do not mess with them. For mpl < 2.0 change the second - # break point and add a musec break point - if _mpl_le_2_0_0(): - self.scaled[1. / SEC_PER_DAY] = '%H:%M:%S' - self.scaled[1. / MUSEC_PER_DAY] = '%H:%M:%S.%f' - class PandasAutoDateLocator(dates.AutoDateLocator): diff --git a/pandas/plotting/_core.py b/pandas/plotting/_core.py index 77c97412bd3d7..405c534e8528b 100644 --- a/pandas/plotting/_core.py +++ b/pandas/plotting/_core.py @@ -30,10 +30,7 @@ from pandas.io.formats.printing import pprint_thing -from pandas.plotting._compat import (_mpl_ge_1_3_1, - _mpl_ge_1_5_0, - _mpl_ge_2_0_0, - _mpl_ge_3_0_0) +from pandas.plotting._compat import _mpl_ge_3_0_0 from pandas.plotting._style import (plot_params, _get_standard_colors) from pandas.plotting._tools import (_subplots, _flatten, table, @@ -551,14 +548,6 @@ def plt(self): import matplotlib.pyplot as plt return plt - @staticmethod - def mpl_ge_1_3_1(): - return _mpl_ge_1_3_1() - - @staticmethod - def mpl_ge_1_5_0(): - return _mpl_ge_1_5_0() - _need_to_set_index = False def _get_xticks(self, convert_period=False): @@ -908,8 +897,7 @@ def _make_plot(self): scatter = ax.scatter(data[x].values, data[y].values, c=c_values, label=label, cmap=cmap, **self.kwds) if cb: - if self.mpl_ge_1_3_1(): - cbar_label = c if c_is_column else '' + cbar_label = c if c_is_column else '' self._plot_colorbar(ax, label=cbar_label) if label is not None: @@ -1012,10 +1000,9 @@ def _make_plot(self): **kwds) self._add_legend_handle(newlines[0], label, index=i) - if not _mpl_ge_2_0_0(): - lines = _get_all_lines(ax) - left, right = _get_xlim(lines) - ax.set_xlim(left, right) + lines = _get_all_lines(ax) + left, right = _get_xlim(lines) + ax.set_xlim(left, right) @classmethod def _plot(cls, ax, x, y, style=None, column_num=None, @@ -1141,8 +1128,7 @@ def _plot(cls, ax, x, y, style=None, column_num=None, # need to remove label, because subplots uses mpl legend as it is line_kwds = kwds.copy() - if cls.mpl_ge_1_5_0(): - line_kwds.pop('label') + line_kwds.pop('label') lines = MPLPlot._plot(ax, x, y_values, style=style, **line_kwds) # get data from the line to get coordinates for fill_between @@ -1165,19 +1151,9 @@ def _plot(cls, ax, x, y, style=None, column_num=None, cls._update_stacker(ax, stacking_id, y) # LinePlot expects list of artists - res = [rect] if cls.mpl_ge_1_5_0() else lines + res = [rect] return res - def _add_legend_handle(self, handle, label, index=None): - if not self.mpl_ge_1_5_0(): - from matplotlib.patches import Rectangle - # Because fill_between isn't supported in legend, - # specifically add Rectangle handle here - alpha = self.kwds.get('alpha', None) - handle = Rectangle((0, 0), 1, 1, fc=handle.get_color(), - alpha=alpha) - LinePlot._add_legend_handle(self, handle, label, index=index) - def _post_plot_logic(self, ax, data): LinePlot._post_plot_logic(self, ax, data) diff --git a/pandas/plotting/_style.py b/pandas/plotting/_style.py index c72e092c73aa2..9bc12d22e1685 100644 --- a/pandas/plotting/_style.py +++ b/pandas/plotting/_style.py @@ -4,14 +4,12 @@ import warnings from contextlib import contextmanager -import re import numpy as np from pandas.core.dtypes.common import is_list_like from pandas.compat import lrange, lmap import pandas.compat as compat -from pandas.plotting._compat import _mpl_ge_2_0_0 def _get_standard_colors(num_colors=None, colormap=None, color_type='default', @@ -72,18 +70,9 @@ def _maybe_valid_colors(colors): # check whether each character can be convertible to colors maybe_color_cycle = _maybe_valid_colors(list(colors)) if maybe_single_color and maybe_color_cycle and len(colors) > 1: - # Special case for single str 'CN' match and convert to hex - # for supporting matplotlib < 2.0.0 - if re.match(r'\AC[0-9]\Z', colors) and _mpl_ge_2_0_0(): - hex_color = [c['color'] - for c in list(plt.rcParams['axes.prop_cycle'])] - colors = [hex_color[int(colors[1])]] - else: - # this may no longer be required - msg = ("'{0}' can be parsed as both single color and " - "color cycle. Specify each color using a list " - "like ['{0}'] or {1}") - raise ValueError(msg.format(colors, list(colors))) + hex_color = [c['color'] + for c in list(plt.rcParams['axes.prop_cycle'])] + colors = [hex_color[int(colors[1])]] elif maybe_single_color: colors = [colors] else: diff --git a/pandas/tests/arithmetic/test_period.py b/pandas/tests/arithmetic/test_period.py index d81ab2b3a2ec3..fe98b74499983 100644 --- a/pandas/tests/arithmetic/test_period.py +++ b/pandas/tests/arithmetic/test_period.py @@ -15,9 +15,7 @@ import pandas.core.indexes.period as period from pandas.core import ops -from pandas import ( - Period, PeriodIndex, period_range, Series, - _np_version_under1p10) +from pandas import Period, PeriodIndex, period_range, Series # ------------------------------------------------------------------ @@ -897,20 +895,14 @@ def test_pi_ops_errors(self, ng): with pytest.raises(TypeError): np.add(obj, ng) - if _np_version_under1p10: - assert np.add(ng, obj) is NotImplemented - else: - with pytest.raises(TypeError): - np.add(ng, obj) + with pytest.raises(TypeError): + np.add(ng, obj) with pytest.raises(TypeError): np.subtract(obj, ng) - if _np_version_under1p10: - assert np.subtract(ng, obj) is NotImplemented - else: - with pytest.raises(TypeError): - np.subtract(ng, obj) + with pytest.raises(TypeError): + np.subtract(ng, obj) def test_pi_ops_nat(self): idx = PeriodIndex(['2011-01', '2011-02', 'NaT', '2011-04'], @@ -1014,10 +1006,7 @@ def test_pi_sub_period(self): tm.assert_index_equal(result, exp) result = np.subtract(pd.Period('2012-01', freq='M'), idx) - if _np_version_under1p10: - assert result is NotImplemented - else: - tm.assert_index_equal(result, exp) + tm.assert_index_equal(result, exp) exp = pd.TimedeltaIndex([np.nan, np.nan, np.nan, np.nan], name='idx') tm.assert_index_equal(idx - pd.Period('NaT', freq='M'), exp) diff --git a/pandas/tests/frame/test_analytics.py b/pandas/tests/frame/test_analytics.py index 8864e5fffeb12..b83fba7e7b277 100644 --- a/pandas/tests/frame/test_analytics.py +++ b/pandas/tests/frame/test_analytics.py @@ -15,7 +15,6 @@ from pandas.compat import lrange, PY35 from pandas import (compat, isna, notna, DataFrame, Series, MultiIndex, date_range, Timestamp, Categorical, - _np_version_under1p12, to_datetime, to_timedelta) import pandas as pd import pandas.core.nanops as nanops @@ -2021,9 +2020,6 @@ def test_dot(self): @pytest.mark.skipif(not PY35, reason='matmul supported for Python>=3.5') - @pytest.mark.xfail( - _np_version_under1p12, - reason="unpredictable return types under numpy < 1.12") def test_matmul(self): # matmul test is for GH 10259 a = DataFrame(np.random.randn(3, 4), index=['a', 'b', 'c'], diff --git a/pandas/tests/frame/test_quantile.py b/pandas/tests/frame/test_quantile.py index 2f264874378bc..3dbac79fed02b 100644 --- a/pandas/tests/frame/test_quantile.py +++ b/pandas/tests/frame/test_quantile.py @@ -6,7 +6,7 @@ import pytest import numpy as np -from pandas import (DataFrame, Series, Timestamp, _np_version_under1p11) +from pandas import DataFrame, Series, Timestamp import pandas as pd from pandas.util.testing import assert_series_equal, assert_frame_equal @@ -154,12 +154,8 @@ def test_quantile_interpolation(self): result = df.quantile([.25, .5], interpolation='midpoint') # https://github.com/numpy/numpy/issues/7163 - if _np_version_under1p11: - expected = DataFrame([[1.5, 1.5, 1.5], [2.5, 2.5, 2.5]], - index=[.25, .5], columns=['a', 'b', 'c']) - else: - expected = DataFrame([[1.5, 1.5, 1.5], [2.0, 2.0, 2.0]], - index=[.25, .5], columns=['a', 'b', 'c']) + expected = DataFrame([[1.5, 1.5, 1.5], [2.0, 2.0, 2.0]], + index=[.25, .5], columns=['a', 'b', 'c']) assert_frame_equal(result, expected) def test_quantile_multi(self): diff --git a/pandas/tests/indexes/datetimes/test_ops.py b/pandas/tests/indexes/datetimes/test_ops.py index b60b222d095b9..9ce77326d37b7 100644 --- a/pandas/tests/indexes/datetimes/test_ops.py +++ b/pandas/tests/indexes/datetimes/test_ops.py @@ -7,8 +7,7 @@ import pandas._libs.tslib as tslib import pandas.util.testing as tm from pandas import (DatetimeIndex, PeriodIndex, Series, Timestamp, - date_range, _np_version_under1p10, Index, - bdate_range) + date_range, bdate_range, Index) from pandas.tseries.offsets import BMonthEnd, CDay, BDay, Day, Hour from pandas.tests.test_base import Ops from pandas.core.dtypes.generic import ABCDateOffset @@ -89,12 +88,11 @@ def test_numpy_minmax(self): assert np.argmin(dr) == 0 assert np.argmax(dr) == 5 - if not _np_version_under1p10: - errmsg = "the 'out' parameter is not supported" - tm.assert_raises_regex( - ValueError, errmsg, np.argmin, dr, out=0) - tm.assert_raises_regex( - ValueError, errmsg, np.argmax, dr, out=0) + errmsg = "the 'out' parameter is not supported" + tm.assert_raises_regex( + ValueError, errmsg, np.argmin, dr, out=0) + tm.assert_raises_regex( + ValueError, errmsg, np.argmax, dr, out=0) def test_repeat_range(self, tz_naive_fixture): tz = tz_naive_fixture diff --git a/pandas/tests/indexes/period/test_ops.py b/pandas/tests/indexes/period/test_ops.py index 85aa3f6a38fb3..a59efe57f83c4 100644 --- a/pandas/tests/indexes/period/test_ops.py +++ b/pandas/tests/indexes/period/test_ops.py @@ -5,8 +5,7 @@ import pandas as pd import pandas._libs.tslib as tslib import pandas.util.testing as tm -from pandas import (DatetimeIndex, PeriodIndex, Series, Period, - _np_version_under1p10, Index) +from pandas import DatetimeIndex, PeriodIndex, Series, Period, Index from pandas.tests.test_base import Ops @@ -73,12 +72,11 @@ def test_numpy_minmax(self): assert np.argmin(pr) == 0 assert np.argmax(pr) == 5 - if not _np_version_under1p10: - errmsg = "the 'out' parameter is not supported" - tm.assert_raises_regex( - ValueError, errmsg, np.argmin, pr, out=0) - tm.assert_raises_regex( - ValueError, errmsg, np.argmax, pr, out=0) + errmsg = "the 'out' parameter is not supported" + tm.assert_raises_regex( + ValueError, errmsg, np.argmin, pr, out=0) + tm.assert_raises_regex( + ValueError, errmsg, np.argmax, pr, out=0) def test_resolution(self): for freq, expected in zip(['A', 'Q', 'M', 'D', 'H', diff --git a/pandas/tests/indexes/period/test_partial_slicing.py b/pandas/tests/indexes/period/test_partial_slicing.py index 6d142722c315a..82527464ea6e7 100644 --- a/pandas/tests/indexes/period/test_partial_slicing.py +++ b/pandas/tests/indexes/period/test_partial_slicing.py @@ -5,7 +5,7 @@ import pandas as pd from pandas.util import testing as tm from pandas import (Series, period_range, DatetimeIndex, PeriodIndex, - DataFrame, _np_version_under1p12, Period) + DataFrame, Period) class TestPeriodIndex(object): @@ -68,16 +68,12 @@ def test_range_slice_day(self): didx = DatetimeIndex(start='2013/01/01', freq='D', periods=400) pidx = PeriodIndex(start='2013/01/01', freq='D', periods=400) - # changed to TypeError in 1.12 - # https://github.com/numpy/numpy/pull/6271 - exc = IndexError if _np_version_under1p12 else TypeError - for idx in [didx, pidx]: # slices against index should raise IndexError values = ['2014', '2013/02', '2013/01/02', '2013/02/01 9H', '2013/02/01 09:00'] for v in values: - with pytest.raises(exc): + with pytest.raises(TypeError): idx[v:] s = Series(np.random.rand(len(idx)), index=idx) @@ -89,7 +85,7 @@ def test_range_slice_day(self): invalid = ['2013/02/01 9H', '2013/02/01 09:00'] for v in invalid: - with pytest.raises(exc): + with pytest.raises(TypeError): idx[v:] def test_range_slice_seconds(self): @@ -98,16 +94,12 @@ def test_range_slice_seconds(self): periods=4000) pidx = PeriodIndex(start='2013/01/01 09:00:00', freq='S', periods=4000) - # changed to TypeError in 1.12 - # https://github.com/numpy/numpy/pull/6271 - exc = IndexError if _np_version_under1p12 else TypeError - for idx in [didx, pidx]: # slices against index should raise IndexError values = ['2014', '2013/02', '2013/01/02', '2013/02/01 9H', '2013/02/01 09:00'] for v in values: - with pytest.raises(exc): + with pytest.raises(TypeError): idx[v:] s = Series(np.random.rand(len(idx)), index=idx) diff --git a/pandas/tests/indexes/timedeltas/test_ops.py b/pandas/tests/indexes/timedeltas/test_ops.py index d7bdd18f48523..9f8a3e893c3de 100644 --- a/pandas/tests/indexes/timedeltas/test_ops.py +++ b/pandas/tests/indexes/timedeltas/test_ops.py @@ -5,10 +5,8 @@ import pandas as pd import pandas.util.testing as tm -from pandas import to_timedelta from pandas import (Series, Timedelta, Timestamp, TimedeltaIndex, - timedelta_range, - _np_version_under1p10) + timedelta_range, to_timedelta) from pandas._libs.tslib import iNaT from pandas.tests.test_base import Ops from pandas.tseries.offsets import Day, Hour @@ -68,12 +66,11 @@ def test_numpy_minmax(self): assert np.argmin(td) == 0 assert np.argmax(td) == 5 - if not _np_version_under1p10: - errmsg = "the 'out' parameter is not supported" - tm.assert_raises_regex( - ValueError, errmsg, np.argmin, td, out=0) - tm.assert_raises_regex( - ValueError, errmsg, np.argmax, td, out=0) + errmsg = "the 'out' parameter is not supported" + tm.assert_raises_regex( + ValueError, errmsg, np.argmin, td, out=0) + tm.assert_raises_regex( + ValueError, errmsg, np.argmax, td, out=0) def test_value_counts_unique(self): # GH 7735 diff --git a/pandas/tests/plotting/common.py b/pandas/tests/plotting/common.py index b142ce339879c..f41a3a10604af 100644 --- a/pandas/tests/plotting/common.py +++ b/pandas/tests/plotting/common.py @@ -39,7 +39,7 @@ def _ok_for_gaussian_kde(kind): except ImportError: return False - return plotting._compat._mpl_ge_1_5_0() + return True @td.skip_if_no_mpl @@ -50,31 +50,16 @@ def setup_method(self, method): import matplotlib as mpl mpl.rcdefaults() - self.mpl_le_1_2_1 = plotting._compat._mpl_le_1_2_1() - self.mpl_ge_1_3_1 = plotting._compat._mpl_ge_1_3_1() - self.mpl_ge_1_4_0 = plotting._compat._mpl_ge_1_4_0() - self.mpl_ge_1_5_0 = plotting._compat._mpl_ge_1_5_0() - self.mpl_ge_2_0_0 = plotting._compat._mpl_ge_2_0_0() self.mpl_ge_2_0_1 = plotting._compat._mpl_ge_2_0_1() + self.mpl_ge_2_1_0 = plotting._compat._mpl_ge_2_1_0() self.mpl_ge_2_2_0 = plotting._compat._mpl_ge_2_2_0() + self.mpl_ge_2_2_2 = plotting._compat._mpl_ge_2_2_2() self.mpl_ge_3_0_0 = plotting._compat._mpl_ge_3_0_0() - if self.mpl_ge_1_4_0: - self.bp_n_objects = 7 - else: - self.bp_n_objects = 8 - if self.mpl_ge_1_5_0: - # 1.5 added PolyCollections to legend handler - # so we have twice as many items. - self.polycollection_factor = 2 - 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' + self.bp_n_objects = 7 + self.polycollection_factor = 2 + self.default_figsize = (6.4, 4.8) + self.default_tick_position = 'left' n = 100 with tm.RNGContext(42): @@ -462,7 +447,7 @@ def _check_box_return_type(self, returned, return_type, expected_keys=None, assert isinstance(value.lines, dict) elif return_type == 'dict': line = value['medians'][0] - axes = line.axes if self.mpl_ge_1_5_0 else line.get_axes() + axes = line.axes if check_ax_title: assert axes.get_title() == key else: @@ -510,19 +495,11 @@ def is_grid_on(): obj.plot(kind=kind, grid=True, **kws) assert is_grid_on() - def _maybe_unpack_cycler(self, rcParams, field='color'): + def _unpack_cycler(self, rcParams, field='color'): """ - Compat layer for MPL 1.5 change to color cycle - - Before: plt.rcParams['axes.color_cycle'] -> ['b', 'g', 'r'...] - After : plt.rcParams['axes.prop_cycle'] -> cycler(...) + Auxiliary function for correctly unpacking cycler after MPL >= 1.5 """ - if self.mpl_ge_1_5_0: - cyl = rcParams['axes.prop_cycle'] - colors = [v[field] for v in cyl] - else: - colors = rcParams['axes.color_cycle'] - return colors + return [v[field] for v in rcParams['axes.prop_cycle']] def _check_plot_works(f, filterwarnings='always', **kwargs): diff --git a/pandas/tests/plotting/test_boxplot_method.py b/pandas/tests/plotting/test_boxplot_method.py index 7661b46a79061..e89584ca35d94 100644 --- a/pandas/tests/plotting/test_boxplot_method.py +++ b/pandas/tests/plotting/test_boxplot_method.py @@ -3,7 +3,6 @@ import pytest import itertools import string -from distutils.version import LooseVersion from pandas import Series, DataFrame, MultiIndex from pandas.compat import range, lzip @@ -21,15 +20,6 @@ """ Test cases for .boxplot method """ -def _skip_if_mpl_14_or_dev_boxplot(): - # GH 8382 - # Boxplot failures on 1.4 and 1.4.1 - # Don't need try / except since that's done at class level - import matplotlib - if LooseVersion(matplotlib.__version__) >= LooseVersion('1.4'): - pytest.skip("Matplotlib Regression in 1.4 and current dev.") - - @td.skip_if_no_mpl class TestDataFramePlots(TestPlotBase): @@ -71,12 +61,12 @@ def test_boxplot_legacy2(self): # passed ax should be used: fig, ax = self.plt.subplots() axes = df.boxplot('Col1', by='X', ax=ax) - ax_axes = ax.axes if self.mpl_ge_1_5_0 else ax.get_axes() + ax_axes = ax.axes assert ax_axes is axes fig, ax = self.plt.subplots() axes = df.groupby('Y').boxplot(ax=ax, return_type='axes') - ax_axes = ax.axes if self.mpl_ge_1_5_0 else ax.get_axes() + ax_axes = ax.axes assert ax_axes is axes['A'] # Multiple columns with an ax argument should use same figure @@ -155,7 +145,6 @@ def _check_ax_limits(col, ax): @pytest.mark.slow def test_boxplot_empty_column(self): - _skip_if_mpl_14_or_dev_boxplot() df = DataFrame(np.random.randn(20, 4)) df.loc[:, 0] = np.nan _check_plot_works(df.boxplot, return_type='axes') diff --git a/pandas/tests/plotting/test_datetimelike.py b/pandas/tests/plotting/test_datetimelike.py index c66e03fe7b2a2..4865638671ea9 100644 --- a/pandas/tests/plotting/test_datetimelike.py +++ b/pandas/tests/plotting/test_datetimelike.py @@ -7,7 +7,7 @@ from pandas.compat import lrange, zip import numpy as np -from pandas import Index, Series, DataFrame, NaT +from pandas import Index, Series, DataFrame, NaT, isna from pandas.compat import PY3 from pandas.core.indexes.datetimes import date_range, bdate_range from pandas.core.indexes.timedeltas import timedelta_range @@ -135,7 +135,7 @@ def f(*args, **kwds): _, ax = self.plt.subplots() ts.plot(style='k', ax=ax) - color = (0., 0., 0., 1) if self.mpl_ge_2_0_0 else (0., 0., 0.) + color = (0., 0., 0., 1) assert color == ax.get_lines()[0].get_color() def test_both_style_and_color(self): @@ -403,80 +403,92 @@ def test_get_finder(self): def test_finder_daily(self): day_lst = [10, 40, 252, 400, 950, 2750, 10000] - if self.mpl_ge_2_0_0: + if (self.mpl_ge_3_0_0 or not self.mpl_ge_2_0_1 + or (self.mpl_ge_2_1_0 and not self.mpl_ge_2_2_2)): + # 2.0.0, 2.2.0 (exactly) or >= 3.0.0 + xpl1 = xpl2 = [Period('1999-1-1', freq='B').ordinal] * len(day_lst) + else: # 2.0.1, 2.1.0, 2.2.2, 2.2.3 xpl1 = [7565, 7564, 7553, 7546, 7518, 7428, 7066] xpl2 = [7566, 7564, 7554, 7546, 7519, 7429, 7066] - else: - xpl1 = xpl2 = [Period('1999-1-1', freq='B').ordinal] * len(day_lst) + rs1 = [] + rs2 = [] for i, n in enumerate(day_lst): - xp = xpl1[i] rng = bdate_range('1999-1-1', periods=n) ser = Series(np.random.randn(len(rng)), rng) _, ax = self.plt.subplots() ser.plot(ax=ax) xaxis = ax.get_xaxis() - rs = xaxis.get_majorticklocs()[0] - assert xp == rs - xp = xpl2[i] + rs1.append(xaxis.get_majorticklocs()[0]) + vmin, vmax = ax.get_xlim() ax.set_xlim(vmin + 0.9, vmax) - rs = xaxis.get_majorticklocs()[0] - assert xp == rs + rs2.append(xaxis.get_majorticklocs()[0]) self.plt.close(ax.get_figure()) + assert rs1 == xpl1 + assert rs2 == xpl2 + @pytest.mark.slow def test_finder_quarterly(self): yrs = [3.5, 11] - if self.mpl_ge_2_0_0: + if (self.mpl_ge_3_0_0 or not self.mpl_ge_2_0_1 + or (self.mpl_ge_2_1_0 and not self.mpl_ge_2_2_2)): + # 2.0.0, 2.2.0 (exactly) or >= 3.0.0 + xpl1 = xpl2 = [Period('1988Q1').ordinal] * len(yrs) + else: # 2.0.1, 2.1.0, 2.2.2, 2.2.3 xpl1 = [68, 68] xpl2 = [72, 68] - else: - xpl1 = xpl2 = [Period('1988Q1').ordinal] * len(yrs) + rs1 = [] + rs2 = [] for i, n in enumerate(yrs): - xp = xpl1[i] rng = period_range('1987Q2', periods=int(n * 4), freq='Q') ser = Series(np.random.randn(len(rng)), rng) _, ax = self.plt.subplots() ser.plot(ax=ax) xaxis = ax.get_xaxis() - rs = xaxis.get_majorticklocs()[0] - assert rs == xp - xp = xpl2[i] + rs1.append(xaxis.get_majorticklocs()[0]) + (vmin, vmax) = ax.get_xlim() ax.set_xlim(vmin + 0.9, vmax) - rs = xaxis.get_majorticklocs()[0] - assert xp == rs + rs2.append(xaxis.get_majorticklocs()[0]) self.plt.close(ax.get_figure()) + assert rs1 == xpl1 + assert rs2 == xpl2 + @pytest.mark.slow def test_finder_monthly(self): yrs = [1.15, 2.5, 4, 11] - if self.mpl_ge_2_0_0: + if (self.mpl_ge_3_0_0 or not self.mpl_ge_2_0_1 + or (self.mpl_ge_2_1_0 and not self.mpl_ge_2_2_2)): + # 2.0.0, 2.2.0 (exactly) or >= 3.0.0 + xpl1 = xpl2 = [Period('Jan 1988').ordinal] * len(yrs) + else: # 2.0.1, 2.1.0, 2.2.2, 2.2.3 xpl1 = [216, 216, 204, 204] xpl2 = [216, 216, 216, 204] - else: - xpl1 = xpl2 = [Period('Jan 1988').ordinal] * len(yrs) + rs1 = [] + rs2 = [] for i, n in enumerate(yrs): - xp = xpl1[i] rng = period_range('1987Q2', periods=int(n * 12), freq='M') ser = Series(np.random.randn(len(rng)), rng) _, ax = self.plt.subplots() ser.plot(ax=ax) xaxis = ax.get_xaxis() - rs = xaxis.get_majorticklocs()[0] - assert rs == xp - xp = xpl2[i] + rs1.append(xaxis.get_majorticklocs()[0]) + vmin, vmax = ax.get_xlim() ax.set_xlim(vmin + 0.9, vmax) - rs = xaxis.get_majorticklocs()[0] - assert xp == rs + rs2.append(xaxis.get_majorticklocs()[0]) self.plt.close(ax.get_figure()) + assert rs1 == xpl1 + assert rs2 == xpl2 + def test_finder_monthly_long(self): rng = period_range('1988Q1', periods=24 * 12, freq='M') ser = Series(np.random.randn(len(rng)), rng) @@ -489,21 +501,26 @@ def test_finder_monthly_long(self): @pytest.mark.slow def test_finder_annual(self): - if self.mpl_ge_2_0_0: - xp = [1986, 1986, 1990, 1990, 1995, 2020, 1970, 1970] - else: + if (self.mpl_ge_3_0_0 or not self.mpl_ge_2_0_1 + or (self.mpl_ge_2_1_0 and not self.mpl_ge_2_2_2)): + # 2.0.0, 2.2.0 (exactly) or >= 3.0.0 xp = [1987, 1988, 1990, 1990, 1995, 2020, 2070, 2170] + else: # 2.0.1, 2.1.0, 2.2.2, 2.2.3 + xp = [1986, 1986, 1990, 1990, 1995, 2020, 1970, 1970] + xp = [Period(x, freq='A').ordinal for x in xp] + rs = [] for i, nyears in enumerate([5, 10, 19, 49, 99, 199, 599, 1001]): rng = period_range('1987', periods=nyears, freq='A') ser = Series(np.random.randn(len(rng)), rng) _, ax = self.plt.subplots() ser.plot(ax=ax) xaxis = ax.get_xaxis() - rs = xaxis.get_majorticklocs()[0] - assert rs == Period(xp[i], freq='A').ordinal + rs.append(xaxis.get_majorticklocs()[0]) self.plt.close(ax.get_figure()) + assert rs == xp + @pytest.mark.slow def test_finder_minutely(self): nminutes = 50 * 24 * 60 @@ -513,10 +530,8 @@ def test_finder_minutely(self): ser.plot(ax=ax) xaxis = ax.get_xaxis() rs = xaxis.get_majorticklocs()[0] - if self.mpl_ge_2_0_0: - xp = Period('1998-12-29 12:00', freq='Min').ordinal - else: - xp = Period('1/1/1999', freq='Min').ordinal + xp = Period('1/1/1999', freq='Min').ordinal + assert rs == xp def test_finder_hourly(self): @@ -527,13 +542,13 @@ def test_finder_hourly(self): ser.plot(ax=ax) xaxis = ax.get_xaxis() rs = xaxis.get_majorticklocs()[0] - if self.mpl_ge_2_0_0: - xp = Period('1998-12-31 22:00', freq='H').ordinal - else: + if self.mpl_ge_2_0_1: xp = Period('1/1/1999', freq='H').ordinal + else: # 2.0.0 + xp = Period('1998-12-31 22:00', freq='H').ordinal + assert rs == xp - @td.skip_if_mpl_1_5 @pytest.mark.slow def test_gaps(self): ts = tm.makeTimeSeries() @@ -544,6 +559,12 @@ def test_gaps(self): assert len(lines) == 1 line = lines[0] data = line.get_xydata() + + if (self.mpl_ge_3_0_0 or not self.mpl_ge_2_0_1 + or (self.mpl_ge_2_1_0 and not self.mpl_ge_2_2_2)): + # 2.0.0, 2.2.0 (exactly) or >= 3.0.0 + data = np.ma.MaskedArray(data, mask=isna(data), fill_value=np.nan) + assert isinstance(data, np.ma.core.MaskedArray) mask = data.mask assert mask[5:25, 1].all() @@ -559,6 +580,12 @@ def test_gaps(self): assert len(lines) == 1 line = lines[0] data = line.get_xydata() + + if (self.mpl_ge_3_0_0 or not self.mpl_ge_2_0_1 + or (self.mpl_ge_2_1_0 and not self.mpl_ge_2_2_2)): + # 2.0.0, 2.2.0 (exactly) or >= 3.0.0 + data = np.ma.MaskedArray(data, mask=isna(data), fill_value=np.nan) + assert isinstance(data, np.ma.core.MaskedArray) mask = data.mask assert mask[2:5, 1].all() @@ -574,11 +601,15 @@ def test_gaps(self): assert len(lines) == 1 line = lines[0] data = line.get_xydata() + if (self.mpl_ge_3_0_0 or not self.mpl_ge_2_0_1 + or (self.mpl_ge_2_1_0 and not self.mpl_ge_2_2_2)): + # 2.0.0, 2.2.0 (exactly) or >= 3.0.0 + data = np.ma.MaskedArray(data, mask=isna(data), fill_value=np.nan) + assert isinstance(data, np.ma.core.MaskedArray) mask = data.mask assert mask[2:5, 1].all() - @td.skip_if_mpl_1_5 @pytest.mark.slow def test_gap_upsample(self): low = tm.makeTimeSeries() @@ -592,8 +623,13 @@ def test_gap_upsample(self): lines = ax.get_lines() assert len(lines) == 1 assert len(ax.right_ax.get_lines()) == 1 + line = lines[0] data = line.get_xydata() + if (self.mpl_ge_3_0_0 or not self.mpl_ge_2_0_1 + or (self.mpl_ge_2_1_0 and not self.mpl_ge_2_2_2)): + # 2.0.0, 2.2.0 (exactly) or >= 3.0.0 + data = np.ma.MaskedArray(data, mask=isna(data), fill_value=np.nan) assert isinstance(data, np.ma.core.MaskedArray) mask = data.mask @@ -659,8 +695,6 @@ def test_secondary_y_ts(self): @pytest.mark.slow @td.skip_if_no_scipy def test_secondary_kde(self): - if not self.mpl_ge_1_5_0: - pytest.skip("mpl is not supported") _skip_if_no_scipy_gaussian_kde() ser = Series(np.random.randn(10)) @@ -1359,18 +1393,13 @@ def test_plot_outofbounds_datetime(self): def test_format_timedelta_ticks_narrow(self): - if self.mpl_ge_2_2_0: - expected_labels = (['-1 days 23:59:59.999999998'] + - ['00:00:00.0000000{:0>2d}'.format(2 * i) - for i in range(6)]) - elif self.mpl_ge_2_0_0: + if self.mpl_ge_2_0_1: + expected_labels = (['00:00:00.0000000{:0>2d}'.format(i) + for i in range(10)]) + else: # 2.0.0 expected_labels = [''] + [ '00:00:00.00000000{:d}'.format(2 * i) for i in range(5)] + [''] - else: - expected_labels = [ - '00:00:00.00000000{:d}'.format(i) - for i in range(10)] rng = timedelta_range('0', periods=10, freq='ns') df = DataFrame(np.random.randn(len(rng), 3), rng) @@ -1378,41 +1407,30 @@ def test_format_timedelta_ticks_narrow(self): df.plot(fontsize=2, ax=ax) fig.canvas.draw() labels = ax.get_xticklabels() - assert len(labels) == len(expected_labels) - for l, l_expected in zip(labels, expected_labels): - assert l.get_text() == l_expected - def test_format_timedelta_ticks_wide(self): + result_labels = [x.get_text() for x in labels] + assert len(result_labels) == len(expected_labels) + assert result_labels == expected_labels - if self.mpl_ge_2_0_0: - expected_labels = [ - '', - '00:00:00', - '1 days 03:46:40', - '2 days 07:33:20', - '3 days 11:20:00', - '4 days 15:06:40', - '5 days 18:53:20', - '6 days 22:40:00', - '8 days 02:26:40', - '9 days 06:13:20', - '' - ] - if self.mpl_ge_2_2_0: - expected_labels[0] = '-2 days 20:13:20' - expected_labels[-1] = '10 days 10:00:00' - else: - expected_labels = [ - '00:00:00', - '1 days 03:46:40', - '2 days 07:33:20', - '3 days 11:20:00', - '4 days 15:06:40', - '5 days 18:53:20', - '6 days 22:40:00', - '8 days 02:26:40', - '' - ] + def test_format_timedelta_ticks_wide(self): + expected_labels = [ + '', + '00:00:00', + '1 days 03:46:40', + '2 days 07:33:20', + '3 days 11:20:00', + '4 days 15:06:40', + '5 days 18:53:20', + '6 days 22:40:00', + '8 days 02:26:40', + '9 days 06:13:20', + '' + ] + if self.mpl_ge_2_2_0: + expected_labels = expected_labels[1:-1] + elif self.mpl_ge_2_0_1: + expected_labels = expected_labels[1:-1] + expected_labels[-1] = '' rng = timedelta_range('0', periods=10, freq='1 d') df = DataFrame(np.random.randn(len(rng), 3), rng) @@ -1420,9 +1438,10 @@ def test_format_timedelta_ticks_wide(self): ax = df.plot(fontsize=2, ax=ax) fig.canvas.draw() labels = ax.get_xticklabels() - assert len(labels) == len(expected_labels) - for l, l_expected in zip(labels, expected_labels): - assert l.get_text() == l_expected + + result_labels = [x.get_text() for x in labels] + assert len(result_labels) == len(expected_labels) + assert result_labels == expected_labels def test_timedelta_plot(self): # test issue #8711 diff --git a/pandas/tests/plotting/test_frame.py b/pandas/tests/plotting/test_frame.py index a4f5d8e2f4ff2..25dfbaba762c9 100644 --- a/pandas/tests/plotting/test_frame.py +++ b/pandas/tests/plotting/test_frame.py @@ -141,22 +141,15 @@ def test_plot(self): fig, ax = self.plt.subplots() axes = df.plot.bar(subplots=True, ax=ax) assert len(axes) == 1 - if self.mpl_ge_1_5_0: - result = ax.axes - else: - result = ax.get_axes() # deprecated + result = ax.axes assert result is axes[0] # GH 15516 def test_mpl2_color_cycle_str(self): - # test CN mpl 2.0 color cycle - if self.mpl_ge_2_0_0: - colors = ['C' + str(x) for x in range(10)] - df = DataFrame(randn(10, 3), columns=['a', 'b', 'c']) - for c in colors: - _check_plot_works(df.plot, color=c) - else: - pytest.skip("not supported in matplotlib < 2.0.0") + colors = ['C' + str(x) for x in range(10)] + df = DataFrame(randn(10, 3), columns=['a', 'b', 'c']) + for c in colors: + _check_plot_works(df.plot, color=c) def test_color_single_series_list(self): # GH 3486 @@ -854,7 +847,7 @@ def test_area_lim(self): @pytest.mark.slow def test_bar_colors(self): import matplotlib.pyplot as plt - default_colors = self._maybe_unpack_cycler(plt.rcParams) + default_colors = self._unpack_cycler(plt.rcParams) df = DataFrame(randn(5, 5)) ax = df.plot.bar() @@ -1180,11 +1173,9 @@ def test_plot_scatter_with_c(self): # default to Greys assert ax.collections[0].cmap.name == 'Greys' - if self.mpl_ge_1_3_1: - - # n.b. there appears to be no public method to get the colorbar - # label - assert ax.collections[0].colorbar._label == 'z' + # n.b. there appears to be no public method + # to get the colorbar label + assert ax.collections[0].colorbar._label == 'z' cm = 'cubehelix' ax = df.plot.scatter(x='x', y='y', c='z', colormap=cm) @@ -1227,7 +1218,7 @@ def test_scatter_colors(self): with pytest.raises(TypeError): df.plot.scatter(x='a', y='b', c='c', color='green') - default_colors = self._maybe_unpack_cycler(self.plt.rcParams) + default_colors = self._unpack_cycler(self.plt.rcParams) ax = df.plot.scatter(x='a', y='b', c='c') tm.assert_numpy_array_equal( @@ -1392,10 +1383,7 @@ def test_bar_edge(self): def test_bar_log_no_subplots(self): # GH3254, GH3298 matplotlib/matplotlib#1882, #1892 # regressions in 1.2.1 - expected = np.array([1., 10.]) - - if not self.mpl_le_1_2_1: - expected = np.hstack((.1, expected, 100)) + expected = np.array([.1, 1., 10., 100]) # no subplots df = DataFrame({'A': [3] * 5, 'B': lrange(1, 6)}, index=lrange(5)) @@ -1404,9 +1392,7 @@ def test_bar_log_no_subplots(self): @pytest.mark.slow def test_bar_log_subplots(self): - expected = np.array([1., 10., 100., 1000.]) - if not self.mpl_le_1_2_1: - expected = np.hstack((.1, expected, 1e4)) + expected = np.array([.1, 1., 10., 100., 1000., 1e4]) ax = DataFrame([Series([200, 300]), Series([300, 500])]).plot.bar( log=True, subplots=True) @@ -1521,8 +1507,6 @@ def test_boxplot_subplots_return_type(self): @td.skip_if_no_scipy def test_kde_df(self): _skip_if_no_scipy_gaussian_kde() - if not self.mpl_ge_1_5_0: - pytest.skip("mpl is not supported") df = DataFrame(randn(100, 4)) ax = _check_plot_works(df.plot, kind='kde') @@ -1545,8 +1529,6 @@ def test_kde_df(self): @td.skip_if_no_scipy def test_kde_missing_vals(self): _skip_if_no_scipy_gaussian_kde() - if not self.mpl_ge_1_5_0: - pytest.skip("mpl is not supported") df = DataFrame(np.random.uniform(size=(100, 4))) df.loc[0, 0] = np.nan @@ -1555,8 +1537,6 @@ def test_kde_missing_vals(self): @pytest.mark.slow def test_hist_df(self): from matplotlib.patches import Rectangle - if self.mpl_le_1_2_1: - pytest.skip("not supported in matplotlib <= 1.2.x") df = DataFrame(randn(100, 4)) series = df[0] @@ -1668,44 +1648,42 @@ def test_hist_df_coord(self): expected_y=np.array([0, 0, 0, 0, 0]), expected_h=np.array([6, 7, 8, 9, 10])) - if self.mpl_ge_1_3_1: - - # horizontal - ax = df.plot.hist(bins=5, orientation='horizontal') - self._check_box_coord(ax.patches[:5], - expected_x=np.array([0, 0, 0, 0, 0]), - expected_w=np.array([10, 9, 8, 7, 6])) - self._check_box_coord(ax.patches[5:10], - expected_x=np.array([0, 0, 0, 0, 0]), - expected_w=np.array([8, 8, 8, 8, 8])) - self._check_box_coord(ax.patches[10:], - expected_x=np.array([0, 0, 0, 0, 0]), - expected_w=np.array([6, 7, 8, 9, 10])) - - ax = df.plot.hist(bins=5, stacked=True, - orientation='horizontal') - self._check_box_coord(ax.patches[:5], - expected_x=np.array([0, 0, 0, 0, 0]), - expected_w=np.array([10, 9, 8, 7, 6])) - self._check_box_coord(ax.patches[5:10], - expected_x=np.array([10, 9, 8, 7, 6]), - expected_w=np.array([8, 8, 8, 8, 8])) - self._check_box_coord( - ax.patches[10:], - expected_x=np.array([18, 17, 16, 15, 14]), - expected_w=np.array([6, 7, 8, 9, 10])) - - axes = df.plot.hist(bins=5, stacked=True, subplots=True, - orientation='horizontal') - self._check_box_coord(axes[0].patches, - expected_x=np.array([0, 0, 0, 0, 0]), - expected_w=np.array([10, 9, 8, 7, 6])) - self._check_box_coord(axes[1].patches, - expected_x=np.array([0, 0, 0, 0, 0]), - expected_w=np.array([8, 8, 8, 8, 8])) - self._check_box_coord(axes[2].patches, - expected_x=np.array([0, 0, 0, 0, 0]), - expected_w=np.array([6, 7, 8, 9, 10])) + # horizontal + ax = df.plot.hist(bins=5, orientation='horizontal') + self._check_box_coord(ax.patches[:5], + expected_x=np.array([0, 0, 0, 0, 0]), + expected_w=np.array([10, 9, 8, 7, 6])) + self._check_box_coord(ax.patches[5:10], + expected_x=np.array([0, 0, 0, 0, 0]), + expected_w=np.array([8, 8, 8, 8, 8])) + self._check_box_coord(ax.patches[10:], + expected_x=np.array([0, 0, 0, 0, 0]), + expected_w=np.array([6, 7, 8, 9, 10])) + + ax = df.plot.hist(bins=5, stacked=True, + orientation='horizontal') + self._check_box_coord(ax.patches[:5], + expected_x=np.array([0, 0, 0, 0, 0]), + expected_w=np.array([10, 9, 8, 7, 6])) + self._check_box_coord(ax.patches[5:10], + expected_x=np.array([10, 9, 8, 7, 6]), + expected_w=np.array([8, 8, 8, 8, 8])) + self._check_box_coord( + ax.patches[10:], + expected_x=np.array([18, 17, 16, 15, 14]), + expected_w=np.array([6, 7, 8, 9, 10])) + + axes = df.plot.hist(bins=5, stacked=True, subplots=True, + orientation='horizontal') + self._check_box_coord(axes[0].patches, + expected_x=np.array([0, 0, 0, 0, 0]), + expected_w=np.array([10, 9, 8, 7, 6])) + self._check_box_coord(axes[1].patches, + expected_x=np.array([0, 0, 0, 0, 0]), + expected_w=np.array([8, 8, 8, 8, 8])) + self._check_box_coord(axes[2].patches, + expected_x=np.array([0, 0, 0, 0, 0]), + expected_w=np.array([6, 7, 8, 9, 10])) @pytest.mark.slow def test_plot_int_columns(self): @@ -1904,14 +1882,13 @@ def test_dont_modify_colors(self): def test_line_colors_and_styles_subplots(self): # GH 9894 from matplotlib import cm - default_colors = self._maybe_unpack_cycler(self.plt.rcParams) + default_colors = self._unpack_cycler(self.plt.rcParams) df = DataFrame(randn(5, 5)) axes = df.plot(subplots=True) for ax, c in zip(axes, list(default_colors)): - if self.mpl_ge_2_0_0: - c = [c] + c = [c] self._check_colors(ax.get_lines(), linecolors=c) tm.close() @@ -1992,13 +1969,7 @@ def test_area_colors(self): self._check_colors(poly, facecolors=custom_colors) handles, labels = ax.get_legend_handles_labels() - 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) + self._check_colors(handles, facecolors=custom_colors) for h in handles: assert h.get_alpha() is None @@ -2011,12 +1982,7 @@ def test_area_colors(self): self._check_colors(poly, facecolors=jet_colors) handles, labels = ax.get_legend_handles_labels() - 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) + self._check_colors(handles, facecolors=jet_colors) for h in handles: assert h.get_alpha() is None tm.close() @@ -2029,18 +1995,14 @@ def test_area_colors(self): self._check_colors(poly, facecolors=jet_with_alpha) handles, labels = ax.get_legend_handles_labels() - if self.mpl_ge_1_5_0: - linecolors = jet_with_alpha - else: - # Line2D can't have alpha in its linecolor - linecolors = jet_colors + linecolors = jet_with_alpha self._check_colors(handles[:len(jet_colors)], linecolors=linecolors) for h in handles: assert h.get_alpha() == 0.5 @pytest.mark.slow def test_hist_colors(self): - default_colors = self._maybe_unpack_cycler(self.plt.rcParams) + default_colors = self._unpack_cycler(self.plt.rcParams) df = DataFrame(randn(5, 5)) ax = df.plot.hist() @@ -2076,8 +2038,6 @@ def test_hist_colors(self): @td.skip_if_no_scipy def test_kde_colors(self): _skip_if_no_scipy_gaussian_kde() - if not self.mpl_ge_1_5_0: - pytest.skip("mpl is not supported") from matplotlib import cm @@ -2101,11 +2061,9 @@ def test_kde_colors(self): @td.skip_if_no_scipy def test_kde_colors_and_styles_subplots(self): _skip_if_no_scipy_gaussian_kde() - if not self.mpl_ge_1_5_0: - pytest.skip("mpl is not supported") from matplotlib import cm - default_colors = self._maybe_unpack_cycler(self.plt.rcParams) + default_colors = self._unpack_cycler(self.plt.rcParams) df = DataFrame(randn(5, 5)) @@ -2164,7 +2122,7 @@ def _check_colors(bp, box_c, whiskers_c, medians_c, caps_c='k', fliers_c=None): # TODO: outside this func? if fliers_c is None: - fliers_c = 'k' if self.mpl_ge_2_0_0 else 'b' + fliers_c = 'k' self._check_colors(bp['boxes'], linecolors=[box_c] * len(bp['boxes'])) self._check_colors(bp['whiskers'], @@ -2176,7 +2134,7 @@ def _check_colors(bp, box_c, whiskers_c, medians_c, caps_c='k', self._check_colors(bp['caps'], linecolors=[caps_c] * len(bp['caps'])) - default_colors = self._maybe_unpack_cycler(self.plt.rcParams) + default_colors = self._unpack_cycler(self.plt.rcParams) df = DataFrame(randn(5, 5)) bp = df.plot.box(return_type='dict') @@ -2225,17 +2183,14 @@ def _check_colors(bp, box_c, whiskers_c, medians_c, caps_c='k', def test_default_color_cycle(self): import matplotlib.pyplot as plt + import cycler colors = list('rgbk') - if self.mpl_ge_1_5_0: - import cycler - plt.rcParams['axes.prop_cycle'] = cycler.cycler('color', colors) - else: - plt.rcParams['axes.color_cycle'] = colors + plt.rcParams['axes.prop_cycle'] = cycler.cycler('color', colors) df = DataFrame(randn(5, 3)) ax = df.plot() - expected = self._maybe_unpack_cycler(plt.rcParams)[:3] + expected = self._unpack_cycler(plt.rcParams)[:3] self._check_colors(ax.get_lines(), linecolors=expected) def test_unordered_ts(self): @@ -2591,19 +2546,12 @@ def test_errorbar_asymmetrical(self): # 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) - 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: - assert ax.lines[7].get_ydata()[0] == data[0, 1] - err[1, 0, 0] - assert ax.lines[8].get_ydata()[0] == data[0, 1] + err[1, 1, 0] - assert ax.lines[5].get_xdata()[0] == -err[1, 0, 0] / 2 - assert ax.lines[6].get_xdata()[0] == err[1, 1, 0] / 2 + 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) with pytest.raises(ValueError): df.plot(yerr=err.T) diff --git a/pandas/tests/plotting/test_hist_method.py b/pandas/tests/plotting/test_hist_method.py index 2864877550bac..1d9942603a269 100644 --- a/pandas/tests/plotting/test_hist_method.py +++ b/pandas/tests/plotting/test_hist_method.py @@ -122,7 +122,7 @@ def test_hist_no_overlap(self): subplot(122) y.hist() fig = gcf() - axes = fig.axes if self.mpl_ge_1_5_0 else fig.get_axes() + axes = fig.axes assert len(axes) == 2 @pytest.mark.slow diff --git a/pandas/tests/plotting/test_misc.py b/pandas/tests/plotting/test_misc.py index 8c84b785c88e4..54d17a4773749 100644 --- a/pandas/tests/plotting/test_misc.py +++ b/pandas/tests/plotting/test_misc.py @@ -76,10 +76,7 @@ def test_scatter_matrix_axis(self): axes0_labels = axes[0][0].yaxis.get_majorticklabels() # GH 5662 - if self.mpl_ge_2_0_0: - expected = ['-2', '0', '2'] - else: - expected = ['-2', '-1', '0', '1', '2'] + expected = ['-2', '0', '2'] self._check_text_labels(axes0_labels, expected) self._check_ticks_props( axes, xlabelsize=8, xrot=90, ylabelsize=8, yrot=0) @@ -91,10 +88,7 @@ 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() - 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'] + expected = ['-1.0', '-0.5', '0.0'] self._check_text_labels(axes0_labels, expected) self._check_ticks_props( axes, xlabelsize=8, xrot=90, ylabelsize=8, yrot=0) diff --git a/pandas/tests/plotting/test_series.py b/pandas/tests/plotting/test_series.py index 5dc7d52e05778..dc708278836d2 100644 --- a/pandas/tests/plotting/test_series.py +++ b/pandas/tests/plotting/test_series.py @@ -88,10 +88,7 @@ def test_plot_figsize_and_title(self): def test_dont_modify_rcParams(self): # GH 8242 - if self.mpl_ge_1_5_0: - key = 'axes.prop_cycle' - else: - key = 'axes.color_cycle' + key = 'axes.prop_cycle' colors = self.plt.rcParams[key] _, ax = self.plt.subplots() Series([1, 2, 3]).plot(ax=ax) @@ -211,10 +208,7 @@ def test_line_use_index_false(self): @pytest.mark.slow def test_bar_log(self): - expected = np.array([1., 10., 100., 1000.]) - - if not self.mpl_le_1_2_1: - expected = np.hstack((.1, expected, 1e4)) + expected = np.array([1e-1, 1e0, 1e1, 1e2, 1e3, 1e4]) _, ax = self.plt.subplots() ax = Series([200, 500]).plot.bar(log=True, ax=ax) @@ -227,17 +221,12 @@ def test_bar_log(self): tm.close() # GH 9905 - expected = np.array([1.0e-03, 1.0e-02, 1.0e-01, 1.0e+00]) - - if not self.mpl_le_1_2_1: - expected = np.hstack((1.0e-04, expected, 1.0e+01)) - if self.mpl_ge_2_0_0: - expected = np.hstack((1.0e-05, expected)) + expected = np.array([1e-5, 1e-4, 1e-3, 1e-2, 1e-1, 1e0, 1e1]) _, ax = self.plt.subplots() ax = Series([0.1, 0.01, 0.001]).plot(log=True, kind='bar', ax=ax) - ymin = 0.0007943282347242822 if self.mpl_ge_2_0_0 else 0.001 - ymax = 0.12589254117941673 if self.mpl_ge_2_0_0 else .10000000000000001 + ymin = 0.0007943282347242822 + ymax = 0.12589254117941673 res = ax.get_ylim() tm.assert_almost_equal(res[0], ymin) tm.assert_almost_equal(res[1], ymax) @@ -474,7 +463,7 @@ def test_hist_no_overlap(self): subplot(122) y.hist() fig = gcf() - axes = fig.axes if self.mpl_ge_1_5_0 else fig.get_axes() + axes = fig.axes assert len(axes) == 2 @pytest.mark.slow @@ -591,8 +580,6 @@ def test_plot_fails_with_dupe_color_and_style(self): @pytest.mark.slow @td.skip_if_no_scipy def test_hist_kde(self): - if not self.mpl_ge_1_5_0: - pytest.skip("mpl is not supported") _, ax = self.plt.subplots() ax = self.ts.plot.hist(logy=True, ax=ax) @@ -618,8 +605,6 @@ def test_hist_kde(self): @td.skip_if_no_scipy def test_kde_kwargs(self): _skip_if_no_scipy_gaussian_kde() - if not self.mpl_ge_1_5_0: - pytest.skip("mpl is not supported") sample_points = np.linspace(-100, 100, 20) _check_plot_works(self.ts.plot.kde, bw_method='scott', ind=20) @@ -638,8 +623,6 @@ def test_kde_kwargs(self): @td.skip_if_no_scipy def test_kde_missing_vals(self): _skip_if_no_scipy_gaussian_kde() - if not self.mpl_ge_1_5_0: - pytest.skip("mpl is not supported") s = Series(np.random.uniform(size=50)) s[0] = np.nan @@ -656,22 +639,18 @@ def test_hist_kwargs(self): self._check_text_labels(ax.yaxis.get_label(), 'Frequency') tm.close() - if self.mpl_ge_1_3_1: - _, ax = self.plt.subplots() - ax = self.ts.plot.hist(orientation='horizontal', ax=ax) - self._check_text_labels(ax.xaxis.get_label(), 'Frequency') - tm.close() + _, ax = self.plt.subplots() + ax = self.ts.plot.hist(orientation='horizontal', ax=ax) + self._check_text_labels(ax.xaxis.get_label(), 'Frequency') + tm.close() - _, ax = self.plt.subplots() - ax = self.ts.plot.hist(align='left', stacked=True, ax=ax) - tm.close() + _, ax = self.plt.subplots() + ax = self.ts.plot.hist(align='left', stacked=True, ax=ax) + tm.close() @pytest.mark.slow @td.skip_if_no_scipy def test_hist_kde_color(self): - if not self.mpl_ge_1_5_0: - pytest.skip("mpl is not supported") - _, ax = self.plt.subplots() ax = self.ts.plot.hist(logy=True, bins=10, color='b', ax=ax) self._check_ax_scales(ax, yaxis='log') @@ -870,10 +849,7 @@ def test_time_series_plot_color_kwargs(self): def test_time_series_plot_color_with_empty_kwargs(self): import matplotlib as mpl - if self.mpl_ge_1_5_0: - def_colors = self._maybe_unpack_cycler(mpl.rcParams) - else: - def_colors = mpl.rcParams['axes.color_cycle'] + def_colors = self._unpack_cycler(mpl.rcParams) index = date_range('1/1/2000', periods=12) s = Series(np.arange(1, 13), index=index) diff --git a/pandas/tests/series/test_analytics.py b/pandas/tests/series/test_analytics.py index 517bb9511552c..d4a204ed265b5 100644 --- a/pandas/tests/series/test_analytics.py +++ b/pandas/tests/series/test_analytics.py @@ -11,8 +11,7 @@ import pandas as pd from pandas import (Series, Categorical, DataFrame, isna, notna, - bdate_range, date_range, _np_version_under1p10, - CategoricalIndex) + bdate_range, date_range, CategoricalIndex) from pandas.core.index import MultiIndex from pandas.core.indexes.datetimes import Timestamp from pandas.core.indexes.timedeltas import Timedelta @@ -1246,12 +1245,11 @@ def test_numpy_argmin_deprecated(self): assert result == 1 - if not _np_version_under1p10: - with tm.assert_produces_warning(FutureWarning, - check_stacklevel=False): - msg = "the 'out' parameter is not supported" - tm.assert_raises_regex(ValueError, msg, np.argmin, - s, out=data) + with tm.assert_produces_warning(FutureWarning, + check_stacklevel=False): + msg = "the 'out' parameter is not supported" + tm.assert_raises_regex(ValueError, msg, np.argmin, + s, out=data) def test_idxmax(self): # test idxmax @@ -1315,12 +1313,11 @@ def test_numpy_argmax_deprecated(self): assert result == 10 - if not _np_version_under1p10: - with tm.assert_produces_warning(FutureWarning, - check_stacklevel=False): - msg = "the 'out' parameter is not supported" - tm.assert_raises_regex(ValueError, msg, np.argmax, - s, out=data) + with tm.assert_produces_warning(FutureWarning, + check_stacklevel=False): + msg = "the 'out' parameter is not supported" + tm.assert_raises_regex(ValueError, msg, np.argmax, + s, out=data) def test_ptp(self): # GH21614 diff --git a/pandas/tests/sparse/series/test_series.py b/pandas/tests/sparse/series/test_series.py index a1ec8314841e3..1cd7c73337e4f 100644 --- a/pandas/tests/sparse/series/test_series.py +++ b/pandas/tests/sparse/series/test_series.py @@ -9,8 +9,8 @@ import numpy as np import pandas as pd -from pandas import (Series, DataFrame, bdate_range, - isna, compat, _np_version_under1p12) + +from pandas import Series, DataFrame, bdate_range, isna, compat from pandas.errors import PerformanceWarning from pandas.tseries.offsets import BDay import pandas.util.testing as tm @@ -559,17 +559,16 @@ def test_numpy_take(self): sp = SparseSeries([1.0, 2.0, 3.0]) indices = [1, 2] - if not _np_version_under1p12: - tm.assert_series_equal(np.take(sp, indices, axis=0).to_dense(), - np.take(sp.to_dense(), indices, axis=0)) + tm.assert_series_equal(np.take(sp, indices, axis=0).to_dense(), + np.take(sp.to_dense(), indices, axis=0)) - msg = "the 'out' parameter is not supported" - tm.assert_raises_regex(ValueError, msg, np.take, - sp, indices, out=np.empty(sp.shape)) + msg = "the 'out' parameter is not supported" + tm.assert_raises_regex(ValueError, msg, np.take, + sp, indices, out=np.empty(sp.shape)) - msg = "the 'mode' parameter is not supported" - tm.assert_raises_regex(ValueError, msg, np.take, - sp, indices, out=None, mode='clip') + msg = "the 'mode' parameter is not supported" + tm.assert_raises_regex(ValueError, msg, np.take, + sp, indices, out=None, mode='clip') def test_setitem(self): self.bseries[5] = 7. diff --git a/pandas/tests/test_algos.py b/pandas/tests/test_algos.py index d2b7979aed98d..1fd801c68fdde 100644 --- a/pandas/tests/test_algos.py +++ b/pandas/tests/test_algos.py @@ -224,10 +224,6 @@ def test_factorize_tuple_list(self, data, expected_label, expected_level): def test_complex_sorting(self): # gh 12666 - check no segfault - # Test not valid numpy versions older than 1.11 - if pd._np_version_under1p11: - pytest.skip("Test valid only for numpy 1.11+") - x17 = np.array([complex(i) for i in range(17)], dtype=object) pytest.raises(TypeError, algos.factorize, x17[::-1], sort=True) diff --git a/pandas/tests/test_expressions.py b/pandas/tests/test_expressions.py index c101fd25ce5e5..a7b9bf9c9a351 100644 --- a/pandas/tests/test_expressions.py +++ b/pandas/tests/test_expressions.py @@ -13,7 +13,7 @@ from pandas.core.api import DataFrame, Panel from pandas.core.computation import expressions as expr -from pandas import compat, _np_version_under1p11, _np_version_under1p13 +from pandas import compat, _np_version_under1p13 from pandas.util.testing import (assert_almost_equal, assert_series_equal, assert_frame_equal, assert_panel_equal) from pandas.io.formats.printing import pprint_thing @@ -272,10 +272,7 @@ def testit(): for op, op_str in [('add', '+'), ('sub', '-'), ('mul', '*'), ('div', '/'), ('pow', '**')]: - # numpy >= 1.11 doesn't handle integers - # raised to integer powers - # https://github.com/pandas-dev/pandas/issues/15363 - if op == 'pow' and not _np_version_under1p11: + if op == 'pow': continue if op == 'div': diff --git a/pandas/tests/test_sorting.py b/pandas/tests/test_sorting.py index 98026f6d4cf0e..aa5d0016eca95 100644 --- a/pandas/tests/test_sorting.py +++ b/pandas/tests/test_sorting.py @@ -7,8 +7,7 @@ import numpy as np from numpy import nan from pandas.core import common as com -from pandas import (DataFrame, MultiIndex, merge, concat, Series, compat, - _np_version_under1p10) +from pandas import DataFrame, MultiIndex, merge, concat, Series, compat from pandas.util import testing as tm from pandas.util.testing import assert_frame_equal, assert_series_equal from pandas.core.sorting import (is_int64_overflow_possible, @@ -416,7 +415,7 @@ def test_mixed_integer_from_list(self): def test_unsortable(self): # GH 13714 arr = np.array([1, 2, datetime.now(), 0, 3], dtype=object) - if compat.PY2 and not _np_version_under1p10: + if compat.PY2: # RuntimeWarning: tp_compare didn't return -1 or -2 for exception with warnings.catch_warnings(): pytest.raises(TypeError, safe_sort, arr) diff --git a/pandas/tests/test_window.py b/pandas/tests/test_window.py index cc663fc59cbf1..4b0c4d581a008 100644 --- a/pandas/tests/test_window.py +++ b/pandas/tests/test_window.py @@ -7,7 +7,6 @@ from datetime import datetime, timedelta from numpy.random import randn import numpy as np -from pandas import _np_version_under1p12 import pandas as pd from pandas import (Series, DataFrame, bdate_range, @@ -1292,8 +1291,6 @@ def test_rolling_quantile_np_percentile(self): tm.assert_almost_equal(df_quantile.values, np.array(np_percentile)) - @pytest.mark.skipif(_np_version_under1p12, - reason='numpy midpoint interpolation is broken') @pytest.mark.parametrize('quantile', [0.0, 0.1, 0.45, 0.5, 1]) @pytest.mark.parametrize('interpolation', ['linear', 'lower', 'higher', 'nearest', 'midpoint']) diff --git a/pandas/util/_test_decorators.py b/pandas/util/_test_decorators.py index 5d7b23894e745..2fe891346065d 100644 --- a/pandas/util/_test_decorators.py +++ b/pandas/util/_test_decorators.py @@ -78,17 +78,6 @@ def _skip_if_no_mpl(): return True -def _skip_if_mpl_1_5(): - mod = safe_import("matplotlib") - - if mod: - v = mod.__version__ - if LooseVersion(v) > LooseVersion('1.4.3') or str(v)[0] == '0': - return True - else: - mod.use("Agg", warn=False) - - def _skip_if_mpl_2_2(): mod = safe_import("matplotlib") @@ -164,8 +153,6 @@ def decorated_func(func): reason="NumPy 1.15 or greater required") skip_if_mpl = pytest.mark.skipif(not _skip_if_no_mpl(), reason="matplotlib is present") -skip_if_mpl_1_5 = pytest.mark.skipif(_skip_if_mpl_1_5(), - reason="matplotlib 1.5") xfail_if_mpl_2_2 = pytest.mark.xfail(_skip_if_mpl_2_2(), reason="matplotlib 2.2") skip_if_32bit = pytest.mark.skipif(is_platform_32bit(), diff --git a/setup.py b/setup.py index bfd0c50c9e9be..f31aaa7e79a0d 100755 --- a/setup.py +++ b/setup.py @@ -24,7 +24,7 @@ def is_platform_windows(): return sys.platform == 'win32' or sys.platform == 'cygwin' -min_numpy_ver = '1.9.0' +min_numpy_ver = '1.12.0' setuptools_kwargs = { 'install_requires': [ 'python-dateutil >= 2.5.0',