diff --git a/README.md b/README.md index 05c8d218..9c56c88d 100644 --- a/README.md +++ b/README.md @@ -151,7 +151,7 @@ colormap. ```python import geovista as gv from geovista.pantry.data import ww3_global_tri -import geovista.theme +import geovista.themes # Load the sample data. sample = ww3_global_tri() @@ -189,7 +189,7 @@ from an [FVCOM](http://fvcom.smast.umassd.edu/fvcom/) **unstructured** mesh, as ```python import geovista as gv from geovista.pantry.data import fvcom_tamar -import geovista.theme +import geovista.themes # Load the sample data. sample = fvcom_tamar() @@ -240,7 +240,7 @@ base layer. ```python import geovista as gv from geovista.pantry.data import lam_pacific -import geovista.theme +import geovista.themes # Load the sample data. sample = lam_pacific() @@ -284,7 +284,7 @@ import cartopy.crs as ccrs import geovista as gv from geovista.pantry.data import lam_pacific -import geovista.theme +import geovista.themes # Load the sample data. sample = lam_pacific() @@ -326,7 +326,7 @@ Now render a [Met Office LFRic](https://www.metoffice.gov.uk/research/approach/m ```python import geovista as gv from geovista.pantry.data import lfric_sst -import geovista.theme +import geovista.themes # Load the sample data. sample = lfric_sst() @@ -365,7 +365,7 @@ using Met Office Unified Model (UM) ORCA2 Sea Water Potential Temperature data, ```python import geovista as gv from geovista.pantry.data import um_orca2 -import geovista.theme +import geovista.themes # Load sample data. sample = um_orca2() @@ -403,7 +403,7 @@ Now let's render a [NOAA/NCEI Optimum Interpolation SST](https://www.ncei.noaa.g ```python import geovista as gv from geovista.pantry.data import oisst_avhrr_sst -import geovista.theme +import geovista.themes # Load sample data. sample = oisst_avhrr_sst() @@ -443,7 +443,7 @@ model uses hexagonal and pentagonal cells, and is a new dynamical core for ```python import geovista as gv from geovista.pantry.data import dynamico -import geovista.theme +import geovista.themes # Load sample data. sample = dynamico() diff --git a/src/geovista/__init__.py b/src/geovista/__init__.py index 7c971d3b..c7f2876a 100644 --- a/src/geovista/__init__.py +++ b/src/geovista/__init__.py @@ -34,7 +34,14 @@ except ModuleNotFoundError: __version__ = "unknown" -#: flag when performing image testing GEOVISTA_IMAGE_TESTING: bool = ( os.environ.get("GEOVISTA_IMAGE_TESTING", "false").lower() == "true" ) +"""Flag when performing image testing.""" + +if not GEOVISTA_IMAGE_TESTING: + # only load the geovista theme if we're not performing image testing, + # as the default pyvista testing theme is adopted instead + from .themes import _find_and_set_plot_theme + + _find_and_set_plot_theme() diff --git a/src/geovista/examples/clouds.py b/src/geovista/examples/clouds.py index ad631914..0c3f66c3 100755 --- a/src/geovista/examples/clouds.py +++ b/src/geovista/examples/clouds.py @@ -40,7 +40,7 @@ import geovista as gv from geovista.pantry.data import cloud_amount -import geovista.theme +import geovista.themes #: The colormap to render the clouds. CMAP = cmocean.cm.gray diff --git a/src/geovista/examples/clouds_robin.py b/src/geovista/examples/clouds_robin.py index 629e1770..2c934092 100755 --- a/src/geovista/examples/clouds_robin.py +++ b/src/geovista/examples/clouds_robin.py @@ -40,7 +40,7 @@ import geovista as gv from geovista.pantry.data import cloud_amount -import geovista.theme +import geovista.themes #: The colormap to render the clouds. CMAP = cmocean.cm.gray diff --git a/src/geovista/examples/curvilinear/from_2d__orca.py b/src/geovista/examples/curvilinear/from_2d__orca.py index c9a22aa6..47153abb 100755 --- a/src/geovista/examples/curvilinear/from_2d__orca.py +++ b/src/geovista/examples/curvilinear/from_2d__orca.py @@ -30,7 +30,7 @@ import geovista as gv from geovista.pantry.data import um_orca2 -import geovista.theme +import geovista.themes def main() -> None: diff --git a/src/geovista/examples/curvilinear/from_2d__orca_moll.py b/src/geovista/examples/curvilinear/from_2d__orca_moll.py index 9995724d..676fdc43 100755 --- a/src/geovista/examples/curvilinear/from_2d__orca_moll.py +++ b/src/geovista/examples/curvilinear/from_2d__orca_moll.py @@ -33,7 +33,7 @@ import geovista as gv from geovista.common import cast_UnstructuredGrid_to_PolyData as cast from geovista.pantry.data import um_orca2 -import geovista.theme +import geovista.themes from geovista.transform import transform_mesh diff --git a/src/geovista/examples/point_cloud/from_points__orca_cloud.py b/src/geovista/examples/point_cloud/from_points__orca_cloud.py index cde5106e..bef0e847 100755 --- a/src/geovista/examples/point_cloud/from_points__orca_cloud.py +++ b/src/geovista/examples/point_cloud/from_points__orca_cloud.py @@ -32,7 +32,7 @@ import geovista as gv from geovista.pantry.data import um_orca2_gradient from geovista.pantry.meshes import ZLEVEL_SCALE_CLOUD -import geovista.theme +import geovista.themes def main() -> None: diff --git a/src/geovista/examples/point_cloud/from_points__orca_cloud_eqc.py b/src/geovista/examples/point_cloud/from_points__orca_cloud_eqc.py index 79e75c6b..aca4faa9 100755 --- a/src/geovista/examples/point_cloud/from_points__orca_cloud_eqc.py +++ b/src/geovista/examples/point_cloud/from_points__orca_cloud_eqc.py @@ -34,7 +34,7 @@ import geovista as gv from geovista.pantry.data import um_orca2_gradient from geovista.pantry.meshes import ZLEVEL_SCALE_CLOUD -import geovista.theme +import geovista.themes def main() -> None: diff --git a/src/geovista/examples/rectilinear/from_1d__oisst.py b/src/geovista/examples/rectilinear/from_1d__oisst.py index cdbfea47..4ee47849 100755 --- a/src/geovista/examples/rectilinear/from_1d__oisst.py +++ b/src/geovista/examples/rectilinear/from_1d__oisst.py @@ -31,7 +31,7 @@ import geovista as gv from geovista.pantry.data import oisst_avhrr_sst -import geovista.theme +import geovista.themes def main() -> None: diff --git a/src/geovista/examples/rectilinear/from_1d__oisst_eqc.py b/src/geovista/examples/rectilinear/from_1d__oisst_eqc.py index 0ba7c1b4..d3726214 100755 --- a/src/geovista/examples/rectilinear/from_1d__oisst_eqc.py +++ b/src/geovista/examples/rectilinear/from_1d__oisst_eqc.py @@ -33,7 +33,7 @@ import geovista as gv from geovista.pantry.data import oisst_avhrr_sst -import geovista.theme +import geovista.themes def main() -> None: diff --git a/src/geovista/examples/rectilinear/from_1d__synthetic_face_m1_n1.py b/src/geovista/examples/rectilinear/from_1d__synthetic_face_m1_n1.py index 9f68b81b..b2ce4874 100755 --- a/src/geovista/examples/rectilinear/from_1d__synthetic_face_m1_n1.py +++ b/src/geovista/examples/rectilinear/from_1d__synthetic_face_m1_n1.py @@ -29,7 +29,7 @@ import numpy as np import geovista as gv -import geovista.theme +import geovista.themes def main() -> None: diff --git a/src/geovista/examples/rectilinear/from_1d__synthetic_face_m1_n1_robin.py b/src/geovista/examples/rectilinear/from_1d__synthetic_face_m1_n1_robin.py index 27a3b1b1..f7f979f8 100755 --- a/src/geovista/examples/rectilinear/from_1d__synthetic_face_m1_n1_robin.py +++ b/src/geovista/examples/rectilinear/from_1d__synthetic_face_m1_n1_robin.py @@ -30,7 +30,7 @@ import numpy as np import geovista as gv -import geovista.theme +import geovista.themes def main() -> None: diff --git a/src/geovista/examples/rectilinear/from_1d__synthetic_node_m1_n1.py b/src/geovista/examples/rectilinear/from_1d__synthetic_node_m1_n1.py index fb19a3d3..f2a5f904 100755 --- a/src/geovista/examples/rectilinear/from_1d__synthetic_node_m1_n1.py +++ b/src/geovista/examples/rectilinear/from_1d__synthetic_node_m1_n1.py @@ -29,7 +29,7 @@ import numpy as np import geovista as gv -import geovista.theme +import geovista.themes def main() -> None: diff --git a/src/geovista/examples/rectilinear/from_1d__synthetic_node_m1_n1_moll.py b/src/geovista/examples/rectilinear/from_1d__synthetic_node_m1_n1_moll.py index 4d733215..6dd3ac35 100755 --- a/src/geovista/examples/rectilinear/from_1d__synthetic_node_m1_n1_moll.py +++ b/src/geovista/examples/rectilinear/from_1d__synthetic_node_m1_n1_moll.py @@ -30,7 +30,7 @@ import numpy as np import geovista as gv -import geovista.theme +import geovista.themes def main() -> None: diff --git a/src/geovista/examples/rectilinear/from_2d__synthetic_face_m1n1.py b/src/geovista/examples/rectilinear/from_2d__synthetic_face_m1n1.py index bb0afae5..151e1743 100755 --- a/src/geovista/examples/rectilinear/from_2d__synthetic_face_m1n1.py +++ b/src/geovista/examples/rectilinear/from_2d__synthetic_face_m1n1.py @@ -29,7 +29,7 @@ import numpy as np import geovista as gv -import geovista.theme +import geovista.themes def main() -> None: diff --git a/src/geovista/examples/rectilinear/from_2d__synthetic_face_m1n1_robin.py b/src/geovista/examples/rectilinear/from_2d__synthetic_face_m1n1_robin.py index a1120a8d..61df5a86 100755 --- a/src/geovista/examples/rectilinear/from_2d__synthetic_face_m1n1_robin.py +++ b/src/geovista/examples/rectilinear/from_2d__synthetic_face_m1n1_robin.py @@ -30,7 +30,7 @@ import numpy as np import geovista as gv -import geovista.theme +import geovista.themes def main() -> None: diff --git a/src/geovista/examples/rectilinear/from_2d__synthetic_node_m1n1.py b/src/geovista/examples/rectilinear/from_2d__synthetic_node_m1n1.py index 88234321..6e15a373 100755 --- a/src/geovista/examples/rectilinear/from_2d__synthetic_node_m1n1.py +++ b/src/geovista/examples/rectilinear/from_2d__synthetic_node_m1n1.py @@ -29,7 +29,7 @@ import numpy as np import geovista as gv -import geovista.theme +import geovista.themes def main() -> None: diff --git a/src/geovista/examples/rectilinear/from_2d__synthetic_node_m1n1_moll.py b/src/geovista/examples/rectilinear/from_2d__synthetic_node_m1n1_moll.py index 329ddced..deef1e30 100755 --- a/src/geovista/examples/rectilinear/from_2d__synthetic_node_m1n1_moll.py +++ b/src/geovista/examples/rectilinear/from_2d__synthetic_node_m1n1_moll.py @@ -30,7 +30,7 @@ import numpy as np import geovista as gv -import geovista.theme +import geovista.themes def main() -> None: diff --git a/src/geovista/examples/scalar_data/earthquakes.py b/src/geovista/examples/scalar_data/earthquakes.py index b50483a0..568b82cc 100755 --- a/src/geovista/examples/scalar_data/earthquakes.py +++ b/src/geovista/examples/scalar_data/earthquakes.py @@ -48,7 +48,7 @@ import geovista as gv from geovista.pantry.data import usgs_earthquakes -import geovista.theme +import geovista.themes def main() -> None: diff --git a/src/geovista/examples/scalar_data/earthquakes_wink1.py b/src/geovista/examples/scalar_data/earthquakes_wink1.py index bc7de1b3..99cb7c1e 100755 --- a/src/geovista/examples/scalar_data/earthquakes_wink1.py +++ b/src/geovista/examples/scalar_data/earthquakes_wink1.py @@ -49,7 +49,7 @@ import geovista as gv from geovista.pantry.data import usgs_earthquakes -import geovista.theme +import geovista.themes def main() -> None: diff --git a/src/geovista/examples/spatial_index/uber_h3.py b/src/geovista/examples/spatial_index/uber_h3.py index 313601aa..e75d8179 100755 --- a/src/geovista/examples/spatial_index/uber_h3.py +++ b/src/geovista/examples/spatial_index/uber_h3.py @@ -88,7 +88,7 @@ import geovista from geovista.geodesic import line -import geovista.theme +import geovista.themes # %% # As a convenience, we create some **type aliases** and **data containers** diff --git a/src/geovista/examples/unstructured/dynamico.py b/src/geovista/examples/unstructured/dynamico.py index 3d9684de..0b07389c 100755 --- a/src/geovista/examples/unstructured/dynamico.py +++ b/src/geovista/examples/unstructured/dynamico.py @@ -32,7 +32,7 @@ import geovista as gv from geovista.pantry.data import dynamico -import geovista.theme +import geovista.themes def main() -> None: diff --git a/src/geovista/examples/unstructured/dynamico_poly.py b/src/geovista/examples/unstructured/dynamico_poly.py index 0614591d..5660184c 100755 --- a/src/geovista/examples/unstructured/dynamico_poly.py +++ b/src/geovista/examples/unstructured/dynamico_poly.py @@ -33,7 +33,7 @@ import geovista as gv from geovista.pantry.data import dynamico -import geovista.theme +import geovista.themes def main() -> None: diff --git a/src/geovista/examples/unstructured/fesom.py b/src/geovista/examples/unstructured/fesom.py index e97766a0..e0e1c6dd 100755 --- a/src/geovista/examples/unstructured/fesom.py +++ b/src/geovista/examples/unstructured/fesom.py @@ -32,7 +32,7 @@ import geovista as gv from geovista.pantry.data import fesom -import geovista.theme +import geovista.themes def main() -> None: diff --git a/src/geovista/examples/unstructured/fesom_fouc.py b/src/geovista/examples/unstructured/fesom_fouc.py index 646ae755..cfe8b5ce 100755 --- a/src/geovista/examples/unstructured/fesom_fouc.py +++ b/src/geovista/examples/unstructured/fesom_fouc.py @@ -33,7 +33,7 @@ import geovista as gv from geovista.pantry.data import fesom -import geovista.theme +import geovista.themes def main() -> None: diff --git a/src/geovista/examples/unstructured/icon.py b/src/geovista/examples/unstructured/icon.py index 208d80a3..4f80c9d5 100755 --- a/src/geovista/examples/unstructured/icon.py +++ b/src/geovista/examples/unstructured/icon.py @@ -33,7 +33,7 @@ import geovista as gv from geovista.pantry.data import icon_soil -import geovista.theme +import geovista.themes def main() -> None: diff --git a/src/geovista/examples/unstructured/icon_eqc.py b/src/geovista/examples/unstructured/icon_eqc.py index b77b9075..cbb19eef 100755 --- a/src/geovista/examples/unstructured/icon_eqc.py +++ b/src/geovista/examples/unstructured/icon_eqc.py @@ -34,7 +34,7 @@ import geovista as gv from geovista.pantry.data import icon_soil -import geovista.theme +import geovista.themes def main() -> None: diff --git a/src/geovista/examples/unstructured/lam_pacific.py b/src/geovista/examples/unstructured/lam_pacific.py index c3615ccd..f3cb7b39 100755 --- a/src/geovista/examples/unstructured/lam_pacific.py +++ b/src/geovista/examples/unstructured/lam_pacific.py @@ -31,7 +31,7 @@ import geovista as gv from geovista.pantry.data import lam_pacific -import geovista.theme +import geovista.themes def main() -> None: diff --git a/src/geovista/examples/unstructured/lam_pacific_moll.py b/src/geovista/examples/unstructured/lam_pacific_moll.py index cb89ec95..5e35097c 100755 --- a/src/geovista/examples/unstructured/lam_pacific_moll.py +++ b/src/geovista/examples/unstructured/lam_pacific_moll.py @@ -32,7 +32,7 @@ import geovista as gv from geovista.pantry.data import lam_pacific -import geovista.theme +import geovista.themes def main() -> None: diff --git a/src/geovista/examples/unstructured/lfric_sst.py b/src/geovista/examples/unstructured/lfric_sst.py index 8955af9e..6e4d177e 100755 --- a/src/geovista/examples/unstructured/lfric_sst.py +++ b/src/geovista/examples/unstructured/lfric_sst.py @@ -31,7 +31,7 @@ import geovista as gv from geovista.pantry.data import lfric_sst -import geovista.theme +import geovista.themes def main() -> None: diff --git a/src/geovista/examples/unstructured/lfric_sst_bonne.py b/src/geovista/examples/unstructured/lfric_sst_bonne.py index 15c769a2..09bd6bbd 100755 --- a/src/geovista/examples/unstructured/lfric_sst_bonne.py +++ b/src/geovista/examples/unstructured/lfric_sst_bonne.py @@ -32,7 +32,7 @@ import geovista as gv from geovista.pantry.data import lfric_sst -import geovista.theme +import geovista.themes def main() -> None: diff --git a/src/geovista/examples/unstructured/smc.py b/src/geovista/examples/unstructured/smc.py index 481dcbd9..45ea73b7 100755 --- a/src/geovista/examples/unstructured/smc.py +++ b/src/geovista/examples/unstructured/smc.py @@ -30,7 +30,7 @@ import geovista as gv from geovista.pantry.data import ww3_global_smc -import geovista.theme +import geovista.themes def main() -> None: diff --git a/src/geovista/examples/unstructured/smc_sinu.py b/src/geovista/examples/unstructured/smc_sinu.py index b0654d55..6d4b103b 100755 --- a/src/geovista/examples/unstructured/smc_sinu.py +++ b/src/geovista/examples/unstructured/smc_sinu.py @@ -32,7 +32,7 @@ import geovista as gv from geovista.pantry.data import ww3_global_smc -import geovista.theme +import geovista.themes def main() -> None: diff --git a/src/geovista/examples/unstructured/tri.py b/src/geovista/examples/unstructured/tri.py index 9b6e9e8c..2055753a 100755 --- a/src/geovista/examples/unstructured/tri.py +++ b/src/geovista/examples/unstructured/tri.py @@ -33,7 +33,7 @@ import geovista as gv from geovista.pantry.data import ww3_global_tri -import geovista.theme +import geovista.themes def main() -> None: diff --git a/src/geovista/examples/unstructured/tri_hammer.py b/src/geovista/examples/unstructured/tri_hammer.py index b0ea236d..0056905b 100755 --- a/src/geovista/examples/unstructured/tri_hammer.py +++ b/src/geovista/examples/unstructured/tri_hammer.py @@ -34,7 +34,7 @@ import geovista as gv from geovista.pantry.data import ww3_global_tri -import geovista.theme +import geovista.themes def main() -> None: diff --git a/src/geovista/examples/vector_data/vectors.py b/src/geovista/examples/vector_data/vectors.py index 5337b576..4cde80bc 100755 --- a/src/geovista/examples/vector_data/vectors.py +++ b/src/geovista/examples/vector_data/vectors.py @@ -27,7 +27,7 @@ import geovista as gv from geovista.pantry.meshes import regular_grid -import geovista.theme +import geovista.themes def main() -> None: diff --git a/src/geovista/examples/warp/from_unstructured__fvcom.py b/src/geovista/examples/warp/from_unstructured__fvcom.py index f043fecb..63daaa56 100755 --- a/src/geovista/examples/warp/from_unstructured__fvcom.py +++ b/src/geovista/examples/warp/from_unstructured__fvcom.py @@ -32,7 +32,7 @@ import geovista as gv from geovista.pantry.data import fvcom_tamar -import geovista.theme +import geovista.themes def main() -> None: diff --git a/src/geovista/examples/warp/from_unstructured__lfric_orog.py b/src/geovista/examples/warp/from_unstructured__lfric_orog.py index 6fcccc05..c75316da 100755 --- a/src/geovista/examples/warp/from_unstructured__lfric_orog.py +++ b/src/geovista/examples/warp/from_unstructured__lfric_orog.py @@ -33,7 +33,7 @@ import geovista as gv from geovista.pantry.data import lfric_orog -import geovista.theme +import geovista.themes def main() -> None: diff --git a/src/geovista/examples/warp/from_unstructured__lfric_orog_eqc.py b/src/geovista/examples/warp/from_unstructured__lfric_orog_eqc.py index a702118c..83a15929 100755 --- a/src/geovista/examples/warp/from_unstructured__lfric_orog_eqc.py +++ b/src/geovista/examples/warp/from_unstructured__lfric_orog_eqc.py @@ -35,7 +35,7 @@ import geovista as gv from geovista.pantry.data import lfric_orog -import geovista.theme +import geovista.themes from geovista.transform import transform_mesh diff --git a/src/geovista/theme.py b/src/geovista/theme.py deleted file mode 100644 index 6e3c82a5..00000000 --- a/src/geovista/theme.py +++ /dev/null @@ -1,32 +0,0 @@ -# Copyright (c) 2021, GeoVista Contributors. -# -# This file is part of GeoVista and is distributed under the 3-Clause BSD license. -# See the LICENSE file in the package root directory for licensing details. - -"""Configures a custom pyvista theme for geovista. - -Notes ------ -.. versionadded:: 0.1.0 - -""" -from __future__ import annotations - -import pyvista as pv - -from . import GEOVISTA_IMAGE_TESTING - -theme = pv.themes.Theme() -theme.name = "geovista" -theme.background = (1.0, 1.0, 1.0) -theme.color = "lightgray" -theme.cmap = "balance" -theme.edge_color = "gray" -theme.font.color = (0.0, 0.0, 0.0) -theme.outline_color = (0.0, 0.0, 0.0) -theme.title = "GeoVista" - -if not GEOVISTA_IMAGE_TESTING: - # only load the geovista theme if we're not performing image testing, - # as the default pyvista testing theme is adopted instead - pv.global_theme.load_theme(theme) diff --git a/src/geovista/themes.py b/src/geovista/themes.py new file mode 100644 index 00000000..b312b232 --- /dev/null +++ b/src/geovista/themes.py @@ -0,0 +1,141 @@ +# Copyright (c) 2021, GeoVista Contributors. +# +# This file is part of GeoVista and is distributed under the 3-Clause BSD license. +# See the LICENSE file in the package root directory for licensing details. + +""":mod:`geovista` specialisation of PyVista :external+pyvista:doc:`api/plotting/theme`. + +To set a theme: either use :func:`set_plot_theme` or set the +``$GEOVISTA_THEME`` environment variable. + +Notes +----- +.. versionadded:: 0.1.0 + +""" +from __future__ import annotations + +import contextlib +from enum import Enum +from os import environ +from warnings import warn + +from pyvista.plotting import themes as pv_themes + + +class GeoVistaTheme(pv_themes.Theme): + """A PyVista theme optimised for typical GeoVista operations. + + Notes + ----- + .. versionadded:: 0.5.0 + + """ + + def __init__(self) -> None: + super().__init__() + self.name = "geovista" + self.background = (1.0, 1.0, 1.0) + self.color = "lightgray" + self.cmap = "balance" + self.edge_color = "gray" + self.font.color = (0.0, 0.0, 0.0) + self.outline_color = (0.0, 0.0, 0.0) + self.title = "GeoVista" + + +class NATIVE_THEMES(Enum): # noqa: N801 (Python recommends UPPER_CASE for Enums) + """Global built-in themes available to GeoVista. + + Notes + ----- + .. versionadded:: 0.5.0 + + """ + + # This class is public, unlike the PyVista equivalent, to improve + # the documentation of valid themes. + geovista = GeoVistaTheme + """:class:`GeoVistaTheme`""" + + +def set_plot_theme(theme: str | pv_themes.Theme) -> None: + """Set the plotting parameters to a predefined theme. + + Calls :func:`pyvista.set_plot_theme`, with a widened set of options + to include themes defined in :mod:`geovista.themes`. + + Parameters + ---------- + theme : str or pyvista.themes.Theme + The theme to apply. All inputs documented in + :func:`pyvista.set_plot_theme` are accepted, as well as those + documented in :data:`NATIVE_THEMES` (e.g. ``NATIVE_THEMES.foo.value()`` + OR ``"foo"`` work the same). + + Warnings + -------- + To use a theme from :func:`pyvista.set_plot_theme` that has a name clash + with a theme from :data:`NATIVE_THEMES`: either use a + :class:`pyvista.plotting.themes.Theme` instance (see PyVista's + :external+pyvista:doc:`api/plotting/theme`), or use + :func:`pyvista.set_plot_theme` directly. + + Notes + ----- + .. versionadded:: 0.5.0 + + Examples + -------- + >>> from geovista import themes + + The following are all equivalent: + + >>> themes.set_plot_theme("geovista") + >>> themes.set_plot_theme(themes.GeoVistaTheme()) + >>> themes.set_plot_theme(themes.NATIVE_THEMES.geovista.value()) + + References to PyVista themes are also accepted: + + >>> themes.set_plot_theme("document") + + """ + if isinstance(theme, str): + theme = theme.lower() + with contextlib.suppress(KeyError): + # Lookup a Theme matching the string reference if possible. + # String may still be a valid reference to a PyVista theme so + # keep going regardless of KeyError. + theme = NATIVE_THEMES[theme].value + + try: + pv_themes.set_plot_theme(theme) + except ValueError as err: + if "not found" in str(err) and isinstance(theme, str): + # Neither GeoVista nor PyVista could find a theme matching the + # string reference. + msg = f"Theme {theme} not found in GeoVista's native themes. {err}" + else: + # Don't modify any other ValueErrors. + msg = str(err) + raise ValueError(msg) from err + + +def _find_and_set_plot_theme() -> None: + """:func:`set_plot_theme` from env var or default :class:`GeoVistaTheme`.""" + default_theme = NATIVE_THEMES.geovista + theme = environ.get("GEOVISTA_THEME", None) + if theme is not None: + try: + set_plot_theme(theme) + except ValueError: + message = ( + "Invalid GeoVista/PyVista theme set in $GEOVISTA_THEME: " + f"'{theme}'. Defaulting to {default_theme}. See the " + f"geovista.themes docs for other valid themes." + ) + warn(message, stacklevel=2) + else: + return + + set_plot_theme(default_theme.value())