diff --git a/.appveyor.yml b/.appveyor.yml index b958416..0fbc9c4 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -8,12 +8,12 @@ environment: install: # windows config (for installation) - - cmd: "SET PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%" + - cmd: "%PYTHON%\\Scripts\\activate" - cmd: setlocal - cmd: set ANACONDA_API_TOKEN= # conda config - conda config --set always_yes yes --set changeps1 no - - conda update -q conda + - conda update -q conda tqdm - conda install conda-build anaconda-client - pip install -i https://pypi.anaconda.org/psyplot/simple --no-deps psyplot-ci-orb - conda config --add channels conda-forge diff --git a/psy_maps/plotters.py b/psy_maps/plotters.py index c6ab713..49de4c4 100755 --- a/psy_maps/plotters.py +++ b/psy_maps/plotters.py @@ -39,7 +39,6 @@ from matplotlib.colors import BoundaryNorm import numpy as np from psyplot import rcParams -from psyplot.compat.pycompat import map from psyplot.docstring import docstrings from psyplot.data import InteractiveList, _infer_interval_breaks from psyplot.plotter import ( diff --git a/tests/circumpolar_test.nc b/tests/circumpolar_test.nc deleted file mode 100644 index a95942f..0000000 Binary files a/tests/circumpolar_test.nc and /dev/null differ diff --git a/tests/test_plotters_combinedplotter_circumpolar.py b/tests/test_plotters_combinedplotter_circumpolar.py deleted file mode 100755 index 32abb26..0000000 --- a/tests/test_plotters_combinedplotter_circumpolar.py +++ /dev/null @@ -1,197 +0,0 @@ -"""Test module of the :mod:`psyplot.plotter.maps` module""" - -# Disclaimer -# ---------- -# -# Copyright (C) 2021 Helmholtz-Zentrum Hereon -# Copyright (C) 2020-2021 Helmholtz-Zentrum Geesthacht -# Copyright (C) 2016-2021 University of Lausanne -# -# This file is part of psy-maps and is released under the GNU LGPL-3.O license. -# See COPYING and COPYING.LESSER in the root of the repository for full -# licensing details. -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Lesser General Public License version 3.0 as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU LGPL-3.0 license for more details. -# -# You should have received a copy of the GNU LGPL-3.0 license -# along with this program. If not, see . - -import os -import unittest -from itertools import starmap, repeat -import numpy as np -import cartopy.crs as ccrs -from psy_maps.plotters import rcParams, InteractiveList -import _base_testing as bt -import test_plotters_combinedplotter as tpc - - -class CircumpolarCombinedPlotterTest(tpc.CombinedPlotterTest): - """Test :class:`psyplot.plotter.maps.CombinedPlotter` class for circumpolar - grid""" - - grid_type = 'circumpolar' - - ncfile = os.path.join(bt.test_dir, 'circumpolar_test.nc') - - @classmethod - def setUpClass(cls): - rcParams['plotter.maps.projection'] = 'northpole' - rcParams['plotter.maps.clat'] = 90 - rcParams['plotter.vector.arrowsize'] = 200 - rcParams['plotter.maps.lonlatbox'] = 'Europe' - super(CircumpolarCombinedPlotterTest, cls).setUpClass() - - def ref_map_grid(self, close=True): - """Create reference file for xgrid formatoption. - - Create reference file for - :attr:`~psyplot.plotter.maps.FieldPlotter.xgrid` (and others) - formatoption""" - sp = self.plot() - sp.update(xgrid=False, ygrid=False) - sp.export(os.path.join(bt.ref_dir, self.get_ref_file('grid1'))) - sp.update(xgrid='rounded', ygrid=['data', 1000]) - sp.export(os.path.join(bt.ref_dir, self.get_ref_file('grid2'))) - sp.update(xgrid=True, ygrid=True, grid_color='w') - sp.export(os.path.join(bt.ref_dir, self.get_ref_file('grid3'))) - sp.update(xgrid=True, ygrid=True, grid_color='k', grid_settings={ - 'linestyle': 'dotted'}) - sp.export(os.path.join(bt.ref_dir, self.get_ref_file('grid4'))) - if close: - sp.close(True, True, True) - - def test_bounds(self): - """Test bounds formatoption""" - # test bounds of scalar field - self.assertEqual( - np.round(self.plotter.bounds.norm.boundaries, 2).tolist(), - np.round(np.linspace(250, 290, 11, endpoint=True), 2).tolist()) - self.update(bounds='minmax') - bounds = [250.63, 254.38, 258.12, 261.87, 265.62, 269.36, 273.11, - 276.85, 280.6, 284.35, 288.09] - self.assertEqual( - np.round(self.plotter.bounds.norm.boundaries, 2).tolist(), bounds) - self.update(bounds=['rounded', 5, 5, 95]) - self.assertEqual( - np.round(self.plotter.bounds.norm.boundaries, 2).tolist(), - np.linspace(255, 290, 5, endpoint=True).tolist()) - - # test vector bounds - self.update(color='absolute') - self.assertEqual( - np.round(self.plotter.vbounds.norm.boundaries, 2).tolist(), - np.linspace(0, 15, 11, endpoint=True).tolist()) - self.update(vbounds='minmax') - bounds = [0.71, 1.74, 2.76, 3.79, 4.81, 5.84, 6.86, 7.89, 8.92, 9.94, - 10.97] - self.assertEqual( - np.round(self.plotter.vbounds.norm.boundaries, 2).tolist(), bounds) - self.update(vbounds=['rounded', 5, 5, 95]) - self.assertEqual( - np.round(self.plotter.vbounds.norm.boundaries, 2).tolist(), - np.round(np.linspace(1.0, 9.5, 5, endpoint=True), 2).tolist()) - - @property - def _minmax_cticks(self): - if not self.vector_mode: - arr = self.plotter.plot_data[0].values - arr = arr[~np.isnan(arr)] - return np.round( - np.linspace(arr.min(), arr.max(), 11, endpoint=True), - decimals=2).tolist() - arr = self.plotter.plot_data[1].values - speed = (arr[0]**2 + arr[1]**2) ** 0.5 - speed = speed[~np.isnan(speed)] - return np.round( - np.linspace(speed.min(), speed.max(), 11, endpoint=True), - decimals=2).tolist() - - def test_grid(self, *args): - """Test xgrid, ygrid, grid_color, grid_labels, grid_settings fmts""" - self.update(xgrid=False, ygrid=False) - self.compare_figures(next(iter(args), self.get_ref_file('grid1'))) - self.update(xgrid='rounded', ygrid=['data', 1000]) - self.compare_figures(next(iter(args), self.get_ref_file('grid2'))) - self.update(xgrid=True, ygrid=True, grid_color='w') - self.compare_figures(next(iter(args), self.get_ref_file('grid3'))) - self.update(xgrid=True, ygrid=True, grid_color='k', - grid_settings={'linestyle': 'dotted'}) - self.compare_figures(next(iter(args), self.get_ref_file('grid4'))) - - def test_lonlatbox(self, *args): - """Test lonlatbox formatoption""" - def get_unmasked(coord): - """return the values of the coordinate that is not masked in the - data""" - arr = data if data.ndim == 2 else data[0] - return coord.values[~np.isnan(arr.values)] - self.update(lonlatbox='Europe|India', map_extent='data') - ax = self.plotter.ax - list(starmap(self.assertAlmostEqual, zip( - ax.get_extent(ccrs.PlateCarree()), (-55.6, 120.6, -24.4, 85.9), - repeat(1), repeat("Failed to set the extent to Europe and India!")) - )) - # test whether latitudes and longitudes succeded - msg = "Failed to fit into lonlatbox limits for %s of %s." - if isinstance(self.plotter.plot_data, InteractiveList): - all_data = self.plotter.plot_data - else: - all_data = [self.plotter.plot_data] - for data in all_data: - self.assertGreaterEqual(get_unmasked(data.longitude).min(), -55.6, - msg=msg % ('longitude', 'minimum')) - self.assertLessEqual(get_unmasked(data.longitude).max(), 120.6, - msg=msg % ('longitude', 'maximum')) - self.assertGreaterEqual(get_unmasked(data.latitude).min(), -24.4, - msg=msg % ('latitude', 'minimum')) - self.assertLessEqual(get_unmasked(data.latitude).max(), 85.9, - msg=msg % ('latitude', 'maximum')) - self.compare_figures(next(iter(args), self.get_ref_file('lonlatbox'))) - - def test_map_extent(self, *args): - """Test map_extent formatoption""" - self.update(map_extent='Europe|India') - self.compare_figures(next(iter(args), self.get_ref_file('map_extent'))) - - @unittest.skip('Not implemented for circumpolar grids') - def ref_datagrid(self): - pass - - @unittest.skip('Not implemented for circumpolar grids') - def test_datagrid(self): - pass - - @unittest.skip('Not implemented for circumpolar grids') - def test_density(self): - pass - - @unittest.skip('Not implemented for circumpolar grids') - def ref_density(self): - pass - - -class CircumpolarCombinedPlotterTest2D( - bt.TestBase2D, CircumpolarCombinedPlotterTest -): - """Test :class:`psyplot.plotter.maps.CombinedPlotter` class for icon grid - without time and vertical dimension""" - - var = ['t2m', ['u_2d', 'v_2d']] - - def _label_test(self, key, label_func, has_time=None): - if has_time is None: - has_time = not bool(self.vector_mode) - tpc.CombinedPlotterTest._label_test( - self, key, label_func, has_time=has_time) - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/test_plotters_fieldplotter.py b/tests/test_plotters_fieldplotter.py index f9b13b5..98d8887 100755 --- a/tests/test_plotters_fieldplotter.py +++ b/tests/test_plotters_fieldplotter.py @@ -28,6 +28,7 @@ from itertools import starmap, repeat, chain import numpy as np import matplotlib.pyplot as plt +import cartopy import cartopy.crs as ccrs import matplotlib.colors as mcol from psy_maps.plotters import FieldPlotter, rcParams, InteractiveList @@ -220,7 +221,11 @@ def test_axiscolor(self): def test_background(self): self.update(background='0.5') - bc = mcol.to_rgba(self.plotter.ax.background_patch.get_facecolor()) + if cartopy.__version__ < "0.18": + col = self.plotter.ax.background_patch.get_facecolor() + else: + col = self.plotter.ax.patch.get_facecolor() + bc = mcol.to_rgba(col) self.assertEqual(bc, (0.5, 0.5, 0.5, 1.0)) def test_extend(self): @@ -471,7 +476,7 @@ def test_lonlatbox_projected(): ) sp.update(lonlatbox=[17.8, 18.2, 59.2, 59.4]) assert ( - np.round(ax.get_extent(ccrs.PlateCarree()), 2).tolist() + np.round(ax.get_extent(ccrs.PlateCarree()), 1).tolist() == [17.8, 18.2, 59.2, 59.4] ) diff --git a/tests/test_plotters_fieldplotter_circumpolar.py b/tests/test_plotters_fieldplotter_circumpolar.py deleted file mode 100755 index 8a41ad6..0000000 --- a/tests/test_plotters_fieldplotter_circumpolar.py +++ /dev/null @@ -1,147 +0,0 @@ -"""Test module of the :mod:`psyplot.plotter.maps` module""" - -# Disclaimer -# ---------- -# -# Copyright (C) 2021 Helmholtz-Zentrum Hereon -# Copyright (C) 2020-2021 Helmholtz-Zentrum Geesthacht -# Copyright (C) 2016-2021 University of Lausanne -# -# This file is part of psy-maps and is released under the GNU LGPL-3.O license. -# See COPYING and COPYING.LESSER in the root of the repository for full -# licensing details. -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Lesser General Public License version 3.0 as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU LGPL-3.0 license for more details. -# -# You should have received a copy of the GNU LGPL-3.0 license -# along with this program. If not, see . - -import os -import unittest -from itertools import starmap, repeat -import numpy as np -import cartopy.crs as ccrs -from psy_maps.plotters import rcParams, InteractiveList -import _base_testing as bt -import test_plotters_fieldplotter as tpf - - -class CircumpolarFieldPlotterTest(tpf.FieldPlotterTest): - """Test :class:`psyplot.plotter.maps.FieldPlotter` class for circumpolar - grid""" - - grid_type = 'circumpolar' - - ncfile = os.path.join(bt.test_dir, 'circumpolar_test.nc') - - @classmethod - def setUpClass(cls): - rcParams['plotter.maps.projection'] = 'northpole' - rcParams['plotter.maps.clat'] = 90 - super(CircumpolarFieldPlotterTest, cls).setUpClass() - - def ref_map_grid(self, close=True): - """Create reference file for xgrid formatoption. - - Create reference file for - :attr:`~psyplot.plotter.maps.FieldPlotter.xgrid` (and others) - formatoption""" - sp = self.plot(xgrid=False, ygrid=False) - sp.export(os.path.join(bt.ref_dir, self.get_ref_file('grid1'))) - sp.update(xgrid='rounded', ygrid=['data', 1000]) - sp.export(os.path.join(bt.ref_dir, self.get_ref_file('grid2'))) - sp.update(xgrid=True, ygrid=True, grid_color='w') - sp.export(os.path.join(bt.ref_dir, self.get_ref_file('grid3'))) - sp.update(xgrid=True, ygrid=True, grid_color='k', grid_settings={ - 'linestyle': 'dotted'}) - sp.export(os.path.join(bt.ref_dir, self.get_ref_file('grid4'))) - if close: - sp.close(True, True, True) - - def test_bounds(self): - """Test bounds formatoption""" - self.assertEqual( - np.round(self.plotter.bounds.norm.boundaries, 2).tolist(), - np.linspace(240, 310, 11, endpoint=True).tolist()) - self.update(bounds='minmax') - bounds = [241.29, 247.68, 254.07, 260.47, 266.86, 273.25, 279.64, - 286.03, 292.43, 298.82, 305.21] - self.assertEqual( - np.round(self.plotter.bounds.norm.boundaries, 2).tolist(), bounds) - self.update(bounds=['rounded', 5, 5, 95]) - self.assertEqual( - np.round(self.plotter.bounds.norm.boundaries, 2).tolist(), - np.linspace(250, 300, 5, endpoint=True).tolist()) - - def test_grid(self, *args): - """Test xgrid, ygrid, grid_color, grid_labels, grid_settings fmts""" - self.update(xgrid=False, ygrid=False) - self.compare_figures(next(iter(args), self.get_ref_file('grid1'))) - self.update(xgrid='rounded', ygrid=['data', 1000]) - self.compare_figures(next(iter(args), self.get_ref_file('grid2'))) - self.update(xgrid=True, ygrid=True, grid_color='w') - self.compare_figures(next(iter(args), self.get_ref_file('grid3'))) - self.update(xgrid=True, ygrid=True, grid_color='k', - grid_settings={'linestyle': 'dotted'}) - self.compare_figures(next(iter(args), self.get_ref_file('grid4'))) - - def test_lonlatbox(self, *args): - """Test lonlatbox formatoption""" - def get_unmasked(coord): - """return the values of the coordinate that is not masked in the - data""" - return coord.values[~np.isnan(data.values)] - self.update(lonlatbox='Europe|India', map_extent='data') - ax = self.plotter.ax - list(starmap(self.assertAlmostEqual, zip( - ax.get_extent(ccrs.PlateCarree()), (-55.6, 120.6, -24.4, 85.9), - repeat(1), repeat("Failed to set the extent to Europe and India!")) - )) - # test whether latitudes and longitudes succeded - msg = "Failed to fit into lonlatbox limits for %s of %s." - if isinstance(self.plotter.plot_data, InteractiveList): - all_data = self.plotter.plot_data - else: - all_data = [self.plotter.plot_data] - for data in all_data: - self.assertGreaterEqual(get_unmasked(data.longitude).min(), -55.6, - msg=msg % ('longitude', 'minimum')) - self.assertLessEqual(get_unmasked(data.longitude).max(), 120.6, - msg=msg % ('longitude', 'maximum')) - self.assertGreaterEqual(get_unmasked(data.latitude).min(), -24.4, - msg=msg % ('latitude', 'minimum')) - self.assertLessEqual(get_unmasked(data.latitude).max(), 85.9, - msg=msg % ('latitude', 'maximum')) - self.compare_figures(next(iter(args), self.get_ref_file('lonlatbox'))) - - def test_map_extent(self, *args): - """Test map_extent formatoption""" - self.update(map_extent='Europe|India') - self.compare_figures(next(iter(args), self.get_ref_file('map_extent'))) - - @unittest.skip('Not implemented for circumpolar grids') - def ref_datagrid(self): - pass - - @unittest.skip('Not implemented for circumpolar grids') - def test_datagrid(self): - pass - - -class CircumpolarFieldPlotterTest2D( - bt.TestBase2D, CircumpolarFieldPlotterTest): - """Test :class:`psyplot.plotter.maps.FieldPlotter` class without time and - vertical dimension for circumpolar grids""" - - var = 't2m_2d' - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/test_plotters_vectorplotter_circumpolar.py b/tests/test_plotters_vectorplotter_circumpolar.py deleted file mode 100755 index 67cbae6..0000000 --- a/tests/test_plotters_vectorplotter_circumpolar.py +++ /dev/null @@ -1,161 +0,0 @@ -"""Test module of the :mod:`psyplot.plotter.maps` module""" - -# Disclaimer -# ---------- -# -# Copyright (C) 2021 Helmholtz-Zentrum Hereon -# Copyright (C) 2020-2021 Helmholtz-Zentrum Geesthacht -# Copyright (C) 2016-2021 University of Lausanne -# -# This file is part of psy-maps and is released under the GNU LGPL-3.O license. -# See COPYING and COPYING.LESSER in the root of the repository for full -# licensing details. -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Lesser General Public License version 3.0 as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU LGPL-3.0 license for more details. -# -# You should have received a copy of the GNU LGPL-3.0 license -# along with this program. If not, see . - -import os -import unittest -from itertools import starmap, repeat -import numpy as np -import cartopy.crs as ccrs -from psy_maps.plotters import rcParams, InteractiveList -import _base_testing as bt -import test_plotters_vectorplotter as tpv - - -class CircumpolarVectorPlotterTest(tpv.VectorPlotterTest): - """Test :class:`psyplot.plotter.maps.VectorPlotter` class for circumpolar - grid""" - - grid_type = 'circumpolar' - - ncfile = os.path.join(bt.test_dir, 'circumpolar_test.nc') - - @classmethod - def setUpClass(cls): - rcParams['plotter.maps.projection'] = 'northpole' - rcParams['plotter.maps.clat'] = 90 - rcParams['plotter.vector.arrowsize'] = 200 - rcParams['plotter.maps.lonlatbox'] = 'Europe' - rcParams['plotter.maps.xgrid'] = False - rcParams['plotter.maps.ygrid'] = False - super(CircumpolarVectorPlotterTest, cls).setUpClass() - - def ref_map_grid(self, close=True): - """Create reference file for xgrid formatoption. - - Create reference file for - :attr:`~psyplot.plotter.maps.FieldPlotter.xgrid` (and others) - formatoption""" - sp = self.plot() - sp.update(xgrid=False, ygrid=False) - sp.export(os.path.join(bt.ref_dir, self.get_ref_file('grid1'))) - sp.update(xgrid='rounded', ygrid=['data', 1000]) - sp.export(os.path.join(bt.ref_dir, self.get_ref_file('grid2'))) - sp.update(xgrid=True, ygrid=True, grid_color='w') - sp.export(os.path.join(bt.ref_dir, self.get_ref_file('grid3'))) - sp.update(xgrid=True, ygrid=True, grid_color='k', grid_settings={ - 'linestyle': 'dotted'}) - sp.export(os.path.join(bt.ref_dir, self.get_ref_file('grid4'))) - if close: - sp.close(True, True, True) - - def test_bounds(self): - """Test bounds formatoption""" - self.update(color='absolute') - self.assertEqual( - np.round(self.plotter.bounds.norm.boundaries, 2).tolist(), - np.linspace(0, 15, 11, endpoint=True).tolist()) - self.update(bounds='minmax') - bounds = [0.71, 1.74, 2.76, 3.79, 4.81, 5.84, 6.86, 7.89, 8.92, 9.94, - 10.97] - self.assertEqual( - np.round(self.plotter.bounds.norm.boundaries, 2).tolist(), bounds) - self.update(bounds=['rounded', 5, 5, 95]) - self.assertEqual( - np.round(self.plotter.bounds.norm.boundaries, 2).tolist(), - np.round(np.linspace(1.0, 9.5, 5, endpoint=True), 2).tolist()) - - def test_grid(self, *args): - """Test xgrid, ygrid, grid_color, grid_labels, grid_settings fmts""" - self.update(xgrid=False, ygrid=False) - self.compare_figures(next(iter(args), self.get_ref_file('grid1'))) - self.update(xgrid='rounded', ygrid=['data', 1000]) - self.compare_figures(next(iter(args), self.get_ref_file('grid2'))) - self.update(xgrid=True, ygrid=True, grid_color='w') - self.compare_figures(next(iter(args), self.get_ref_file('grid3'))) - self.update(xgrid=True, ygrid=True, grid_color='k', - grid_settings={'linestyle': 'dotted'}) - self.compare_figures(next(iter(args), self.get_ref_file('grid4'))) - - def test_lonlatbox(self, *args): - """Test lonlatbox formatoption""" - def get_unmasked(coord): - """return the values of the coordinate that is not masked in the - data""" - return coord.values[~np.isnan(data[0].values)] - self.update(lonlatbox='Europe|India', map_extent='data') - ax = self.plotter.ax - list(starmap(self.assertAlmostEqual, zip( - ax.get_extent(ccrs.PlateCarree()), (-55.6, 120.6, -24.4, 85.9), - repeat(1), repeat("Failed to set the extent to Europe and India!")) - )) - # test whether latitudes and longitudes succeded - msg = "Failed to fit into lonlatbox limits for %s of %s." - if isinstance(self.plotter.plot_data, InteractiveList): - all_data = self.plotter.plot_data - else: - all_data = [self.plotter.plot_data] - for data in all_data: - self.assertGreaterEqual(get_unmasked(data.longitude).min(), -55.6, - msg=msg % ('longitude', 'minimum')) - self.assertLessEqual(get_unmasked(data.longitude).max(), 120.6, - msg=msg % ('longitude', 'maximum')) - self.assertGreaterEqual(get_unmasked(data.latitude).min(), -24.4, - msg=msg % ('latitude', 'minimum')) - self.assertLessEqual(get_unmasked(data.latitude).max(), 85.9, - msg=msg % ('latitude', 'maximum')) - self.compare_figures(next(iter(args), self.get_ref_file('lonlatbox'))) - - def test_map_extent(self, *args): - """Test map_extent formatoption""" - self.update(map_extent='Europe|India') - self.compare_figures(next(iter(args), self.get_ref_file('map_extent'))) - - @unittest.skip('Not implemented for circumpolar grids') - def ref_datagrid(self): - pass - - @unittest.skip('Not implemented for circumpolar grids') - def test_datagrid(self): - pass - - @unittest.skip('Not implemented for circumpolar grids') - def test_density(self): - pass - - @unittest.skip('Not implemented for circumpolar grids') - def ref_density(self): - pass - - -class CircumpolarVectorPlotterTest2D( - bt.TestBase2D, CircumpolarVectorPlotterTest): - """Test :class:`psyplot.plotter.maps.VectorPlotter` class without time and - vertical dimension for circumpolar grids""" - - var = ['u_2d', 'v_2d'] - - -if __name__ == '__main__': - unittest.main()