From f550a55ac3064598bbaa92c9fe9051ddc5378834 Mon Sep 17 00:00:00 2001 From: maximlt Date: Fri, 21 Jul 2023 13:14:34 +0200 Subject: [PATCH 1/3] test that no projection is set when tiles is used without geo=True --- hvplot/tests/testgeo.py | 48 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/hvplot/tests/testgeo.py b/hvplot/tests/testgeo.py index 6a3435421..b7d59023f 100644 --- a/hvplot/tests/testgeo.py +++ b/hvplot/tests/testgeo.py @@ -1,6 +1,8 @@ import pathlib import sys +import pytest + from unittest import TestCase, SkipTest from packaging.version import Version @@ -11,6 +13,13 @@ from hvplot.util import proj_to_cartopy +bk_renderer = hv.Store.renderers['bokeh'] + +@pytest.fixture +def simple_df(): + return pd.DataFrame(np.random.rand(10, 2), columns=['x', 'y']) + + class TestGeo(TestCase): def setUp(self): @@ -174,6 +183,45 @@ def test_plot_with_specific_gv_tile_obj(self): self.assertIsInstance(plot.get(0), gv.element.WMTS) +class TestAnnotationNotGeo: + + @classmethod + def setup_class(cls): + import hvplot.pandas # noqa + + def test_plot_tiles_doesnt_set_geo(self, simple_df): + plot = simple_df.hvplot.points('x', 'y', tiles=True) + assert len(plot) == 2 + assert isinstance(plot.get(0), hv.Tiles) + assert 'openstreetmap' in plot.get(0).data + bk_plot = bk_renderer.get_plot(plot) + assert bk_plot.projection == 'mercator' + + def test_plot_specific_tiles_doesnt_set_geo(self, simple_df): + plot = simple_df.hvplot.points('x', 'y', tiles='ESRI') + assert len(plot) == 2 + assert isinstance(plot.get(0), hv.Tiles) + assert 'ArcGIS' in plot.get(0).data + bk_plot = bk_renderer.get_plot(plot) + assert bk_plot.projection == 'mercator' + + def test_plot_with_specific_tile_class(self, simple_df): + plot = simple_df.hvplot.points('x', 'y', tiles=hv.element.tiles.EsriImagery) + assert len(plot) == 2 + assert isinstance(plot.get(0), hv.Tiles) + assert 'ArcGIS' in plot.get(0).data + bk_plot = bk_renderer.get_plot(plot) + assert bk_plot.projection == 'mercator' + + def test_plot_with_specific_tile_obj(self, simple_df): + plot = simple_df.hvplot.points('x', 'y', tiles=hv.element.tiles.EsriImagery()) + assert len(plot) == 2 + assert isinstance(plot.get(0), hv.Tiles) + assert 'ArcGIS' in plot.get(0).data + bk_plot = bk_renderer.get_plot(plot) + assert bk_plot.projection == 'mercator' + + class TestGeoElements(TestCase): def setUp(self): From 0682dd1a01687b49705caf1503c30e2b33faeefb Mon Sep 17 00:00:00 2001 From: maximlt Date: Wed, 11 Oct 2023 17:42:21 +0200 Subject: [PATCH 2/3] small refactor of the geo tests --- hvplot/tests/conftest.py | 37 ++++++++++++++++ hvplot/tests/testgeo.py | 75 ++++++++++++++------------------ hvplot/tests/testgeowithoutgv.py | 50 +++++++++++++++++++++ hvplot/tests/testutil.py | 29 ------------ tox.ini | 1 + 5 files changed, 121 insertions(+), 71 deletions(-) create mode 100644 hvplot/tests/conftest.py create mode 100644 hvplot/tests/testgeowithoutgv.py diff --git a/hvplot/tests/conftest.py b/hvplot/tests/conftest.py new file mode 100644 index 000000000..774d8f73e --- /dev/null +++ b/hvplot/tests/conftest.py @@ -0,0 +1,37 @@ +optional_markers = { + "geo": { + "help": "Run the tests that require GeoViews", + "marker-descr": "Geo test marker", + "skip-reason": "Test only runs with the --geo option." + }, +} + + +def pytest_addoption(parser): + for marker, info in optional_markers.items(): + parser.addoption("--{}".format(marker), action="store_true", + default=False, help=info['help']) + + +def pytest_configure(config): + for marker, info in optional_markers.items(): + config.addinivalue_line("markers", + "{}: {}".format(marker, info['marker-descr'])) + + +def pytest_collection_modifyitems(config, items): + skipped, selected = [], [] + markers = [m for m in optional_markers if config.getoption(f"--{m}")] + empty = not markers + for item in items: + if empty and any(m in item.keywords for m in optional_markers): + skipped.append(item) + elif empty: + selected.append(item) + elif not empty and any(m in item.keywords for m in markers): + selected.append(item) + else: + skipped.append(item) + + config.hook.pytest_deselected(items=skipped) + items[:] = selected diff --git a/hvplot/tests/testgeo.py b/hvplot/tests/testgeo.py index a3982d3e5..ff2b806a5 100644 --- a/hvplot/tests/testgeo.py +++ b/hvplot/tests/testgeo.py @@ -1,17 +1,20 @@ +""" +These tests depends on GeoViews. +""" import pathlib import sys -import pytest - from unittest import TestCase, SkipTest -from packaging.version import Version +import holoviews as hv import numpy as np import pandas as pd -import holoviews as hv +import pytest from hvplot.util import proj_to_cartopy +from packaging.version import Version +pytestmark = pytest.mark.geo bk_renderer = hv.Store.renderers['bokeh'] @@ -254,44 +257,6 @@ def test_plot_with_features_properly_overlaid_underlaid(self): assert plot.get(0).group == "Land" assert plot.get(2).group == "Borders" -class TestAnnotationNotGeo: - - @classmethod - def setup_class(cls): - import hvplot.pandas # noqa - - def test_plot_tiles_doesnt_set_geo(self, simple_df): - plot = simple_df.hvplot.points('x', 'y', tiles=True) - assert len(plot) == 2 - assert isinstance(plot.get(0), hv.Tiles) - assert 'openstreetmap' in plot.get(0).data - bk_plot = bk_renderer.get_plot(plot) - assert bk_plot.projection == 'mercator' - - def test_plot_specific_tiles_doesnt_set_geo(self, simple_df): - plot = simple_df.hvplot.points('x', 'y', tiles='ESRI') - assert len(plot) == 2 - assert isinstance(plot.get(0), hv.Tiles) - assert 'ArcGIS' in plot.get(0).data - bk_plot = bk_renderer.get_plot(plot) - assert bk_plot.projection == 'mercator' - - def test_plot_with_specific_tile_class(self, simple_df): - plot = simple_df.hvplot.points('x', 'y', tiles=hv.element.tiles.EsriImagery) - assert len(plot) == 2 - assert isinstance(plot.get(0), hv.Tiles) - assert 'ArcGIS' in plot.get(0).data - bk_plot = bk_renderer.get_plot(plot) - assert bk_plot.projection == 'mercator' - - def test_plot_with_specific_tile_obj(self, simple_df): - plot = simple_df.hvplot.points('x', 'y', tiles=hv.element.tiles.EsriImagery()) - assert len(plot) == 2 - assert isinstance(plot.get(0), hv.Tiles) - assert 'ArcGIS' in plot.get(0).data - bk_plot = bk_renderer.get_plot(plot) - assert bk_plot.projection == 'mercator' - class TestGeoElements(TestCase): @@ -427,3 +392,29 @@ def test_polygons_turns_off_hover_when_there_are_no_fields_to_include(self): polygons = self.polygons.hvplot(geo=True) opts = hv.Store.lookup_options('bokeh', polygons, 'plot').kwargs assert 'hover' not in opts.get('tools') + + +class TestGeoUtil(TestCase): + + def setUp(self): + if sys.platform == "win32": + raise SkipTest("Skip geo tests on windows for now") + try: + import cartopy.crs as ccrs + except: + raise SkipTest('cartopy not available') + self.ccrs = ccrs + + def test_proj_to_cartopy(self): + from ..util import proj_to_cartopy + crs = proj_to_cartopy('+init=epsg:26911') + + assert isinstance(crs, self.ccrs.CRS) + + def test_proj_to_cartopy_wkt_string(self): + from ..util import proj_to_cartopy + crs = proj_to_cartopy('GEOGCRS["unnamed",BASEGEOGCRS["unknown",DATUM["unknown",ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1,ID["EPSG",9001]]]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8901]]],DERIVINGCONVERSION["unknown",METHOD["PROJ ob_tran o_proj=latlon"],PARAMETER["o_lon_p",0,ANGLEUNIT["degree",0.0174532925199433,ID["EPSG",9122]]],PARAMETER["o_lat_p",37.5,ANGLEUNIT["degree",0.0174532925199433,ID["EPSG",9122]]],PARAMETER["lon_0",357.5,ANGLEUNIT["degree",0.0174532925199433,ID["EPSG",9122]]]],CS[ellipsoidal,2],AXIS["longitude",east,ORDER[1],ANGLEUNIT["degree",0.0174532925199433,ID["EPSG",9122]]],AXIS["latitude",north,ORDER[2],ANGLEUNIT["degree",0.0174532925199433,ID["EPSG",9122]]]]') # noqa: E501 + + assert isinstance(crs, self.ccrs.RotatedPole) + assert crs.proj4_params["lon_0"] == 357.5 + assert crs.proj4_params["o_lat_p"] == 37.5 diff --git a/hvplot/tests/testgeowithoutgv.py b/hvplot/tests/testgeowithoutgv.py new file mode 100644 index 000000000..41356112f --- /dev/null +++ b/hvplot/tests/testgeowithoutgv.py @@ -0,0 +1,50 @@ +""" +Geo tests **without** importing GeoViews. +""" +import holoviews as hv +import hvplot.pandas # noqa +import numpy as np +import pandas as pd +import pytest + + +bk_renderer = hv.Store.renderers['bokeh'] + +@pytest.fixture +def simple_df(): + return pd.DataFrame(np.random.rand(10, 2), columns=['x', 'y']) + + +class TestAnnotationNotGeo: + + def test_plot_tiles_doesnt_set_geo(self, simple_df): + plot = simple_df.hvplot.points('x', 'y', tiles=True) + assert len(plot) == 2 + assert isinstance(plot.get(0), hv.Tiles) + assert 'openstreetmap' in plot.get(0).data + bk_plot = bk_renderer.get_plot(plot) + assert bk_plot.projection == 'mercator' + + def test_plot_specific_tiles_doesnt_set_geo(self, simple_df): + plot = simple_df.hvplot.points('x', 'y', tiles='ESRI') + assert len(plot) == 2 + assert isinstance(plot.get(0), hv.Tiles) + assert 'ArcGIS' in plot.get(0).data + bk_plot = bk_renderer.get_plot(plot) + assert bk_plot.projection == 'mercator' + + def test_plot_with_specific_tile_class(self, simple_df): + plot = simple_df.hvplot.points('x', 'y', tiles=hv.element.tiles.EsriImagery) + assert len(plot) == 2 + assert isinstance(plot.get(0), hv.Tiles) + assert 'ArcGIS' in plot.get(0).data + bk_plot = bk_renderer.get_plot(plot) + assert bk_plot.projection == 'mercator' + + def test_plot_with_specific_tile_obj(self, simple_df): + plot = simple_df.hvplot.points('x', 'y', tiles=hv.element.tiles.EsriImagery()) + assert len(plot) == 2 + assert isinstance(plot.get(0), hv.Tiles) + assert 'ArcGIS' in plot.get(0).data + bk_plot = bk_renderer.get_plot(plot) + assert bk_plot.projection == 'mercator' diff --git a/hvplot/tests/testutil.py b/hvplot/tests/testutil.py index d24e8377f..b2dc73df8 100644 --- a/hvplot/tests/testutil.py +++ b/hvplot/tests/testutil.py @@ -1,8 +1,6 @@ """ Tests utilities to convert data and projections """ -import sys - import numpy as np import pandas as pd import pytest @@ -199,33 +197,6 @@ def test_process_xarray_dataset_with_x_as_derived_datetime(self): assert not groupby -class TestGeoUtil(TestCase): - - def setUp(self): - if sys.platform == "win32": - raise SkipTest("Skip geo tests on windows for now") - try: - import geoviews # noqa - import cartopy.crs as ccrs - except: - raise SkipTest('geoviews or cartopy not available') - self.ccrs = ccrs - - def test_proj_to_cartopy(self): - from ..util import proj_to_cartopy - crs = proj_to_cartopy('+init=epsg:26911') - - assert isinstance(crs, self.ccrs.CRS) - - def test_proj_to_cartopy_wkt_string(self): - from ..util import proj_to_cartopy - crs = proj_to_cartopy('GEOGCRS["unnamed",BASEGEOGCRS["unknown",DATUM["unknown",ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1,ID["EPSG",9001]]]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8901]]],DERIVINGCONVERSION["unknown",METHOD["PROJ ob_tran o_proj=latlon"],PARAMETER["o_lon_p",0,ANGLEUNIT["degree",0.0174532925199433,ID["EPSG",9122]]],PARAMETER["o_lat_p",37.5,ANGLEUNIT["degree",0.0174532925199433,ID["EPSG",9122]]],PARAMETER["lon_0",357.5,ANGLEUNIT["degree",0.0174532925199433,ID["EPSG",9122]]]],CS[ellipsoidal,2],AXIS["longitude",east,ORDER[1],ANGLEUNIT["degree",0.0174532925199433,ID["EPSG",9122]]],AXIS["latitude",north,ORDER[2],ANGLEUNIT["degree",0.0174532925199433,ID["EPSG",9122]]]]') # noqa: E501 - - assert isinstance(crs, self.ccrs.RotatedPole) - assert crs.proj4_params["lon_0"] == 357.5 - assert crs.proj4_params["o_lat_p"] == 37.5 - - class TestDynamicArgs(TestCase): def setUp(self): diff --git a/tox.ini b/tox.ini index a691d2004..7e9c27f1a 100644 --- a/tox.ini +++ b/tox.ini @@ -9,6 +9,7 @@ envlist = {py38,py39,py310,py311}-{unit,examples,all}-{default}-{dev,pkg} description = Run unit tests with coverage deps = .[tests] commands = pytest -v hvplot --cov=./hvplot --cov-append + pytest -v hvplot --geo --cov=./hvplot --cov-append [_examples] description = Test that default examples run From c1a42195018a830df3152b93199aa3d230600446 Mon Sep 17 00:00:00 2001 From: maximlt Date: Wed, 11 Oct 2023 19:33:06 +0200 Subject: [PATCH 3/3] comment out cells with ; --- examples/user_guide/Plotting_with_Matplotlib.ipynb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/user_guide/Plotting_with_Matplotlib.ipynb b/examples/user_guide/Plotting_with_Matplotlib.ipynb index 478612534..03151d72a 100644 --- a/examples/user_guide/Plotting_with_Matplotlib.ipynb +++ b/examples/user_guide/Plotting_with_Matplotlib.ipynb @@ -338,7 +338,7 @@ "metadata": {}, "outputs": [], "source": [ - "flights.hvplot.hexbin(x='airtime', y='arrdelay', width=600, height=500, logz=True);" + "# flights.hvplot.hexbin(x='airtime', y='arrdelay', width=600, height=500, logz=True);" ] }, { @@ -461,7 +461,7 @@ "outputs": [], "source": [ "flight_subset = flights[flights.carrier.isin(['AA', 'US', 'OH'])]\n", - "flight_subset.hvplot.hist('depdelay', by='carrier', bins=20, bin_range=(-20, 100), width=300, subplots=True);" + "# flight_subset.hvplot.hist('depdelay', by='carrier', bins=20, bin_range=(-20, 100), width=300, subplots=True);" ] }, { @@ -575,7 +575,7 @@ "outputs": [], "source": [ "flight_subset = flights[flights.carrier.isin(['AA', 'US', 'OH'])]\n", - "flight_subset.hvplot.box('depdelay', by='carrier', ylim=(-10, 70));" + "# flight_subset.hvplot.box('depdelay', by='carrier', ylim=(-10, 70));" ] }, {