Repository: ARM-DOE/ACT

Issue:
Sunset Stamen maps in GeoDisplay and potentially replace
Stamen is transitioning their maps to stadia at the end of October 2023.  ACT will need to deprecate that feature in GeoDisplay and potentially look for replacements.

https://github.com/SciTools/cartopy/pull/2266 


Discussion:

Resolving patch:
diff --git a/act/plotting/geodisplay.py b/act/plotting/geodisplay.py
--- a/act/plotting/geodisplay.py
+++ b/act/plotting/geodisplay.py
@@ -3,6 +3,8 @@
 
 """
 
+import warnings
+
 import matplotlib
 import matplotlib.pyplot as plt
 import numpy as np
@@ -13,7 +15,7 @@
 try:
     import cartopy.crs as ccrs
     import cartopy.feature as cfeature
-    from cartopy.io.img_tiles import Stamen
+    from cartopy.io import img_tiles
 
     CARTOPY_AVAILABLE = True
 except ImportError:
@@ -56,8 +58,10 @@ def geoplot(
         title=None,
         projection=None,
         plot_buffer=0.08,
-        stamen='terrain-background',
+        img_tile=None,
+        img_tile_args={},
         tile=8,
+        stamen='terrain-background',
         cartopy_feature=None,
         cmap='rainbow',
         text=None,
@@ -91,11 +95,18 @@ def geoplot(
             https://scitools.org.uk/cartopy/docs/latest/reference/projections.html?highlight=projections
         plot_buffer : float
             Buffer to add around data on plot in lat and lon dimension.
-        stamen : str
-            Dataset to use for background image. Set to None to not use
-            background image.
+        img_tile : str
+            Image to use for the plot background. Set to None to not use
+            background image. For all image background types, see:
+            https://scitools.org.uk/cartopy/docs/v0.16/cartopy/io/img_tiles.html
+            Default is None.
+        img_tile_args : dict
+            Keyword arguments for the chosen img_tile. These arguments can be
+            found for the corresponding img_tile here:
+            https://scitools.org.uk/cartopy/docs/v0.16/cartopy/io/img_tiles.html
+            Default is an empty dictionary.
         tile : int
-            Tile zoom to use with background image. Higer number indicates
+            Tile zoom to use with background image. Higher number indicates
             more resolution. A value of 8 is typical for a normal sonde plot.
         cartopy_feature : list of str or str
             Cartopy feature to add to plot.
@@ -199,9 +210,16 @@ def geoplot(
         else:
             plt.title(title)
 
-        if stamen:
-            tiler = Stamen(stamen)
+        if stamen and img_tile is None:
+            tiler = img_tiles.Stamen(stamen)
             ax.add_image(tiler, tile)
+            warnings.warn(
+                "Stamen is deprecated in Cartopy and in future versions of ACT, "
+                "please use img_tile to specify the image background. ")
+        else:
+            if img_tile is not None:
+                tiler = getattr(img_tiles, img_tile)(**img_tile_args)
+                ax.add_image(tiler, tile)
 
         colorbar_map = None
         if cmap is not None:
diff --git a/examples/plotting/plot_aaf_track.py b/examples/plotting/plot_aaf_track.py
--- a/examples/plotting/plot_aaf_track.py
+++ b/examples/plotting/plot_aaf_track.py
@@ -22,7 +22,7 @@
 display = act.plotting.GeographicPlotDisplay(ds, figsize=(12, 10))
 
 # Plot the ARM AAF flight track with respect to Pressure Altitude
-display.geoplot('press_alt', lat_field='lat', lon_field='lon', stamen=None)
+display.geoplot('press_alt', lat_field='lat', lon_field='lon')
 
 # Display the plot
 plt.show()


Test patch:
diff --git a/act/tests/baseline/test_geoplot.png b/act/tests/baseline/test_geoplot.png
Binary files a/act/tests/baseline/test_geoplot.png and b/act/tests/baseline/test_geoplot.png differ
diff --git a/act/tests/baseline/test_geoplot_tile.png b/act/tests/baseline/test_geoplot_tile.png
new file mode 100644
Binary files /dev/null and b/act/tests/baseline/test_geoplot_tile.png differ
diff --git a/act/tests/test_plotting.py b/act/tests/test_plotting.py
--- a/act/tests/test_plotting.py
+++ b/act/tests/test_plotting.py
@@ -412,14 +412,13 @@ def test_xsection_plot_map():
 
 
 @pytest.mark.skipif(not CARTOPY_AVAILABLE, reason='Cartopy is not installed.')
-@pytest.mark.mpl_image_compare(tolerance=30)
+@pytest.mark.mpl_image_compare(style="default", tolerance=30)
 def test_geoplot():
     sonde_ds = arm.read_netcdf(sample_files.EXAMPLE_SONDE1)
     geodisplay = GeographicPlotDisplay({'sgpsondewnpnC1.b1': sonde_ds}, figsize=(15, 8))
     try:
         geodisplay.geoplot(
             'tdry',
-            marker='.',
             cartopy_feature=[
                 'STATES',
                 'LAND',
@@ -430,6 +429,7 @@ def test_geoplot():
                 'RIVERS',
             ],
             text={'Ponca City': [-97.0725, 36.7125]},
+            img_tile=None,
             stamen=None,
         )
         try:
@@ -441,6 +441,36 @@ def test_geoplot():
     sonde_ds.close()
 
 
+@pytest.mark.skipif(not CARTOPY_AVAILABLE, reason='Cartopy is not installed.')
+@pytest.mark.mpl_image_compare(style="default", tolerance=30)
+def test_geoplot_tile():
+    sonde_ds = arm.read_netcdf(sample_files.EXAMPLE_SONDE1)
+    geodisplay = GeographicPlotDisplay({'sgpsondewnpnC1.b1': sonde_ds}, figsize=(15, 8))
+    try:
+        geodisplay.geoplot(
+            'tdry',
+            cartopy_feature=[
+                'STATES',
+                'LAND',
+                'OCEAN',
+                'COASTLINE',
+                'BORDERS',
+                'LAKES',
+                'RIVERS',
+            ],
+            text={'Ponca City': [-97.0725, 36.7125]},
+            img_tile='GoogleTiles',
+            img_tile_args={'style': 'street'},
+        )
+        try:
+            return geodisplay.fig
+        finally:
+            matplotlib.pyplot.close(geodisplay.fig)
+    except Exception:
+        pass
+    sonde_ds.close()
+
+
 @pytest.mark.mpl_image_compare(tolerance=30)
 def test_stair_graph():
     sonde_ds = arm.read_netcdf(sample_files.EXAMPLE_SONDE1)