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));" ] }, { 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 cde418801..ff2b806a5 100644 --- a/hvplot/tests/testgeo.py +++ b/hvplot/tests/testgeo.py @@ -1,14 +1,26 @@ +""" +These tests depends on GeoViews. +""" import pathlib import sys 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'] + +@pytest.fixture +def simple_df(): + return pd.DataFrame(np.random.rand(10, 2), columns=['x', 'y']) class TestGeo(TestCase): @@ -245,6 +257,7 @@ def test_plot_with_features_properly_overlaid_underlaid(self): assert plot.get(0).group == "Land" assert plot.get(2).group == "Borders" + class TestGeoElements(TestCase): def setUp(self): @@ -379,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