Source code for salishsea_tools.places

# Copyright 2013 – present by the SalishSeaCast contributors
# and The University of British Columbia

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at

#    https://www.apache.org/licenses/LICENSE-2.0

# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Salish Sea NEMO model geographic places information.

It is recommended that library code that uses the :py:data:`PLACES` data
structure from this module should use :kbd:`try...except` to catch
:py:exc:`KeyError` exceptions and produce an error message that is more
informative than the default, for example:

.. code-block:: python

    try:
        max_tide_ssh = max(ttide.pred_all) + PLACES[site_name]['mean sea lvl']
        max_historic_ssh = PLACES[site_name]['hist max sea lvl']
    except KeyError as e:
        raise KeyError(
            'place name or info key not found in '
            'salishsea_tools.places.PLACES: {}'.format(e))
"""

#: Information about geographic places used in the analysis and
#: presentation of Salish Sea NEMO model results.
PLACES = {
    # Tide gauge stations
    "Campbell River": {
        # deg E, deg N
        "lon lat": (-125.24, 50.04),
        # Canadian Hydrographic Service (CHS) or NOAA
        "stn number": 8074,
        # m above chart datum
        "mean sea lvl": 2.916,
        # m above chart datum
        "hist max sea lvl": 5.35,
        # indices of nearest weather forcing grid point
        # j is the latitude (y) direction, i is the longitude (x) direction
        "wind grid ji": (190, 102),
        # indices of nearest NEMO model grid point
        # j is the latitude (y) direction, i is the longitude (x) direction
        "NEMO grid ji": (747, 125),
        # indices of nearest wave model grid point
        # j is the latitude (y) direction, i is the longitude (x) direction
        "ww3 grid ji": (453, 109),
    },
    "Cherry Point": {
        "lon lat": (-122.766667, 48.866667),
        "stn number": 9449424,
        "mean sea lvl": 3.543,
        "hist max sea lvl": 5.846,
        "wind grid ji": (122, 166),
        "NEMO grid ji": (343, 342),
        "ww3 grid ji": (193, 462),
    },
    "Friday Harbor": {
        "lon lat": (-123.016667, 48.55),
        "stn number": 9449880,
        "mean sea lvl": 2.561,
        "hist max sea lvl": 4.572,
        "wind grid ji": (108, 155),
        "NEMO grid ji": (300, 267),
        "ww3 grid ji": (124, 427),
    },
    "Halfmoon Bay": {
        "lon lat": (-123.912, 49.511),
        "stn number": None,
        "NEMO grid ji": (549, 254),
        "wind grid ji": (158, 136),
        "ww3 grid ji": (331, 297),
        "mean sea lvl": 3.14,
        "hist max sea lvl": 5.61,  # copied from Point Atkinson
    },
    "Nanaimo": {
        "lon lat": (-123.93, 49.16),
        "stn number": 7917,
        "mean sea lvl": 3.08,
        "hist max sea lvl": 5.47,
        "wind grid ji": (142, 133),
        "NEMO grid ji": (484, 208),  # current a little different
        "ww3 grid ji": (261, 298),
    },
    "Neah Bay": {
        "lon lat": (-124.6, 48.4),
        "stn number": 9443090,
        "mean sea lvl": 1.925,
        "hist max sea lvl": 4.359,
        "wind grid ji": (111, 105),
        "NEMO grid ji": (384, 15),
        "ww3 grid ji": (89, 200),
    },
    "New Westminster": {
        "lon lat": (-122.90535, 49.203683),
        "stn number": 7654,
        "mean sea lvl": 1.3,  # from Marlene Jefferies via 20mar18 email from Michael Dunphy
        "hist max sea lvl": 4.66,
        "NEMO grid ji": (423, 363),
        "wind grid ji": (138, 164),
        # no nearby waves
    },
    "Patricia Bay": {
        "lon lat": (-123.4515, 48.6536),
        "stn number": 7277,
        "mean sea lvl": 2.256,
        "hist max sea lvl": 4.38,
        "NEMO grid ji": (351, 214),
        "wind grid ji": (115, 143),
        "ww3 grid ji": (145, 363),
    },
    "Point Atkinson": {
        "lon lat": (-123.25, 49.33),
        "stn number": 7795,
        "mean sea lvl": 3.09,
        "hist max sea lvl": 5.61,
        "wind grid ji": (146, 155),
        "NEMO grid ji": (468, 329),
        "ww3 grid ji": (296, 393),
    },
    "Port Renfrew": {
        "lon lat": (-124.421, 48.555),
        "stn number": 8525,
        "mean sea lvl": 1.937,
        "hist max sea lvl": 4.359,  # from Neah Bay
        "NEMO grid ji": (401, 61),
        "wind grid ji": (117, 112),
        "ww3 grid ji": (123, 226),
    },
    "Sandy Cove": {
        "lon lat": (-123.23, 49.34),
        "stn number": 7786,
        "NEMO grid ji": (468, 333),
        "wind grid ji": (146, 155),
        "ww3 grid ji": (294, 396),
        "mean sea lvl": 3.1,  # from Marlene Jefferies via 20mar18 email from Michael Dunphy
        "hist max sea lvl": 5.61,  # from Pt. Atkinson
    },
    "Squamish": {
        "lon lat": (-123.155, 49.694),
        "stn number": None,
        "NEMO grid ji": (532, 389),
        "wind grid ji": (162, 160),
        "ww3 grid ji": (370, 404),
        "mean sea lvl": 3.14,
        "hist max sea lvl": 5.61,  # from Pt. Atkkinson
    },
    "Victoria": {
        "lon lat": (-123.3707, 48.424666),
        "stn number": 7120,
        "mean sea lvl": 1.8810,
        "hist max sea lvl": 3.76,
        "wind grid ji": (104, 144),
        "NEMO grid ji": (302, 196),
        "ww3 grid ji": (90, 374),
    },
    "Woodwards Landing": {
        "lon lat": (-123.0754, 49.1251),
        "stn number": 7610,
        "hist max sea lvl": 4.66,  # based on New West
        "mean sea lvl": 1.84,  # from Marlene Jefferies via 20mar18 email from Michael Dunphy
        "NEMO grid ji": (414, 329),
        "wind grid ji": (135, 138),
    },
    "Boundary Bay": {
        "lon lat": (-122.925, 49.0),
        "stn number": None,
        "hist max sea lvl": 5.61,  # based on Point Atk
        "mean sea lvl": 3.09,  # based on Point Atk
        "NEMO grid ji": (380, 335),
        "wind grid ji": (129, 162),
        "ww3 grid ji": (222, 439),
    },
    # VHFR FVCOM model tide guage stations
    "Calamity Point": {
        "lon lat": (-123.1276, 49.31262),
        "stn number": 7724,
        "mean sea lvl": 3.001,  # same as Vancouver Harbour; from Marlene Jefferies via 20mar18 email from Michael Dunphy
        "NEMO grid ji": None,
        "wind grid ji": (456, 344),
        "ww3 grid ji": None,
    },
    "Vancouver Harbour": {
        "lon lat": (-123.1069, 49.28937),
        "stn number": 7735,
        "mean sea lvl": 3.001,  # from Marlene Jefferies via 20mar18 email from Michael Dunphy
        "NEMO grid ji": None,
        "wind grid ji": (143, 159),
        "ww3 grid ji": None,
    },
    "Port Moody": {
        "lon lat": (-122.8658, 49.28814),
        "stn number": 7755,
        "mean sea lvl": 3.143,  # from Marlene Jefferies via 20mar18 email from Michael Dunphy
        "NEMO grid ji": None,
        "wind grid ji": (142, 166),
        "ww3 grid ji": None,
    },
    "Indian Arm Head": {
        "lon lat": (-122.8864, 49.4615),
        "stn number": 7774,
        "mean sea lvl": 3.052,  # from Marlene Jefferies via 20mar18 email from Michael Dunphy
        "NEMO grid ji": None,
        "wind grid ji": (150, 167),
        "ww3 grid ji": None,
    },
    # VHFR FVCOM model HADCP station
    "2nd Narrows Rail Bridge": {
        "lon lat": (-123.0247222, 49.2938889),
        "stn number": 3160171,  # AIS MMSI (Maritime Mobile Service Identity)
        "mean sea lvl": None,
        "NEMO grid ji": None,
        "wind grid ji": (143, 161),
        "ww3 grid ji": None,
    },
    # Ferry terminals
    "Tsawwassen": {
        "lon lat": (-123.132722, 49.006165),
        "stn number": None,
        "mean sea lvl": None,
        "NEMO grid ji": (396, 305),
        "wind grid ji": (130, 155),
        "ww3 grid ji": None,
        "in berth radius": 0.0015,
    },
    "Duke Pt.": {
        "lon lat": (-123.89095676900132, 49.16340592936349),
        "stn number": None,
        "mean sea lvl": None,
        "NEMO grid ji": (481, 213),
        "wind grid ji": (142, 134),
        "ww3 grid ji": None,
        "in berth radius": 0.002,
    },
    "Horseshoe Bay": {
        "lon lat": (-123.2728, 49.3742),
        "stn number": None,
        "mean sea lvl": None,
        "NEMO grid ji": (478, 331),
        "wind grid ji": (148, 154),
        "ww3 grid ji": None,
    },
    "Departure Bay": {
        "lon lat": (-123.8909, 49.1632),
        "stn number": None,
        "mean sea lvl": None,
        "NEMO grid ji": (481, 213),
        "wind grid ji": (142, 134),
        "ww3 grid ji": None,
    },
    "Swartz Bay": {
        "lon lat": (-123.4102, 48.6882),
        "stn number": None,
        "mean sea lvl": None,
        "NEMO grid ji": (354, 225),
        "wind grid ji": (117, 144),
        "ww3 grid ji": None,
    },
    # Cities
    "Vancouver": {
        "lon lat": (-123.1207, 49.2827),
    },
    "Hope": {
        "lon lat": (-121.4419, 49.3858),
    },
    # Provinces and states
    "British Columbia": {
        "lon lat": (-123.6, 49.9),
    },
    "Washington State": {
        "lon lat": (-123.8, 47.8),
    },
    # Bodies of water
    "Pacific Ocean": {
        "lon lat": (-125.6, 48.1),
    },
    "Juan de Fuca Strait": {
        "lon lat": (-124.7, 48.47),
    },
    "Puget Sound": {
        "lon lat": (-122.67, 48),
    },
    "Strait of Georgia": {
        "lon lat": (-123.8, 49.3),
    },
    "Central SJDF": {
        "lon lat": (-123.9534, 48.281677),
        "NEMO grid ji": (315, 95),
        "GEM2.5 grid ji": (101, 124),
    },
    # if you have a better location in mind for Baynes Sound, please update!
    # if not, I will after I hear from Debbie/Evie -EO
    "Baynes Sound": {
        "lon lat": (-124.86022, 49.60356),
        "NEMO grid ji": (635, 126),
    },
    # STRATOGEM STATION S3(lat,lon)=(49 7.5 N, 123 33.5 W)
    "S3": {
        "lon lat": (-123.558, 49.125),
        "NEMO grid ji": (450, 258),
        "GEM2.5 grid ji": (138, 144),
    },
    # Hakai STATION QU39 (lat,lon)=(50.0307 N, 125.0992 W)
    "QU39": {
        "lon lat": (-125.0992, 50.0307),
        "NEMO grid ji": (736, 144),
        "GEM2.5 grid ji": (189, 106),
    },
    # SJDF station for bloom timing
    "SJDF": {
        "lon lat": (-124.07, 48.31),
        "NEMO grid ji": (329, 81),
        "GEM2.5 grid ji": (103, 121),
    },
    # Tereza's cluster stations, aligned with Vector Stations where possible.
    "Cluster_1": {
        "NEMO grid ji": (241, 212),
        "lon lat": (48.215, -123.099),
        "Vector Stn": "64",
    },
    "Cluster_2": {
        "NEMO grid ji": (294, 127),
        "lon lat": (48.261, -123.717),
        "Vector Stn": "69",
    },
    "Cluster_3": {
        "NEMO grid ji": (376, 291),
        "lon lat": (48.899, -123.138),
        "Vector Stn": "45",
    },
    "Cluster_4": {
        "NEMO grid ji": (282, 305),
        "lon lat": (48.555, -122.750),
        "Vector Stn": "53",
    },
    "Cluster_5": {
        "NEMO grid ji": (344, 271),
        "lon lat": (48.735, -123.135),
        "Vector Stn": "57",
    },
    "Cluster_6": {
        "NEMO grid ji": (320, 68),
        "lon lat": (48.249, -124.110),
        "Vector Stn": "73",
    },
    "Cluster_7": {
        "NEMO grid ji": (504, 246),
        "lon lat": (49.317, -123.801),
        "Vector Stn": "27",
    },
    "Cluster_8": {
        "NEMO grid ji": (646, 168),
        "lon lat": (49.726, -124.679),
        "Vector Stn": "12",
    },
    "Cluster_9": {
        "NEMO grid ji": (423, 300),
        "lon lat": (49.101, -123.249),
    },
    # VENUS
    "Central node": {
        # location from Ocean Networks Canada (ONC) website
        "lon lat": (-123.425825, 49.040066666),
        # depth in metres from ONC website
        "depth": 294,
        # corresponding python vertical grid index
        "NEMO grid k": 34,
        # NEMO python grid indices: j in y direction, i in x direction
        "NEMO grid ji": (424, 266),
        # HRDPS python grid indices: j in y direction, i in x direction
        "wind grid ji": (133, 147),
        # ONC data web services API station code
        "ONC stationCode": "SCVIP",
    },
    "Delta BBL node": {
        # ONC's description is "Delta/Lower Slope/Bottom Boundary Layer"
        "lon lat": (-123.339633, 49.074766),
        "depth": 143,
        "NEMO grid k": 28,
        "NEMO grid ji": (424, 283),
        "wind grid ji": (134, 150),
        "ONC stationCode": "LSBBL",
    },
    "Delta DDL node": {
        # ONC's description is "Delta/Upper Slope/Delta Dynamics Laboratory"
        "lon lat": (-123.32972, 49.08495),
        "depth": 107,
        "NEMO grid k": 27,
        "NEMO grid ji": (426, 286),
        "wind grid ji": (135, 150),
        "ONC stationCode": "USDDL",
    },
    "East node": {
        "lon lat": (-123.316836666, 49.04316),
        "depth": 164,
        "NEMO grid k": 29,
        "NEMO grid ji": (417, 283),
        "wind grid ji": (133, 150),
        "ONC stationCode": "SEVIP",
    },
    # Lightstations
    "Ballenas Islands": {
        "lon lat": (-124.160, 49.350),
        "NEMO grid ji": (536, 197),
        "wind grid ji": (152, 127),
    },
    "Discovery Island": {
        "lon lat": (-123.226, 48.425),
        "NEMO grid ji": (291, 219),
        "wind grid ji": (104, 148),
    },
    "Entrance Island": {
        "lon lat": (-123.811, 49.209),
        "NEMO grid ji": (484, 231),
        "wind grid ji": (143, 137),
    },
    "Race Rocks": {
        "lon lat": (-123.531, 48.298),
        "NEMO grid ji": (288, 159),
        "wind grid ji": (99, 137),
    },
    "Sand Heads": {
        "lon lat": (-123.30, 49.10),
        "stn number": 7594,  # Marlene's coordinates for Tide Station are slightly different.  Leaving as is.
        "NEMO grid ji": (426, 293),  # match Domain file
        "mean sea lvl": 2.875,
        "hist max sea lvl": 5.61 - 3.09 + 2.875,  # based on Point Atk.
        "GEM2.5 grid ji": (135, 151),
        "wind grid ji": (135, 151),
        "ww3 grid ji": (246, 385),
    },
    "Saturna Island": {
        "lon lat": (-123.045, 48.784),
        "NEMO grid ji": (347, 290),
        "wind grid ji": (119, 156),
    },
    "Sisters Islet": {
        "lon lat": (-124.43, 49.49),
        "NEMO grid ji": (582, 175),
        "GEM2.5 grid ji": (160, 120),
        "wind grid ji": (160, 120),
    },
    # Wind stations
    "Esquimalt": {
        "lon lat": (-123.439, 48.432),
        "NEMO grid ji": (307, 189),
        "wind grid ji": (105, 141),
    },
    "Pam Rocks": {
        "lon lat": (-123.299, 49.488),
        "NEMO grid ji": (502, 341),
        "wind grid ji": (153, 154),
    },
    # Wave buoys
    "Halibut Bank": {
        "lon lat": (-123.72, 49.34),
        "NEMO grid ji": (503, 261),
        "GEM2.5 grid ji": (149, 141),
        "wind grid ji": (149, 141),
        "EC buoy number": 46146,
    },
    "Sentry Shoal": {
        "lon lat": (-125.0, 49.92),
        "NEMO grid ji": (707, 145),
        "GEM2.5 grid ji": (183, 107),
        "wind grid ji": (183, 107),
        "EC buoy number": 46131,
    },
    # Seasonal Chl sensor at town dock
    "Egmont": {
        "lon lat": (-123.93, 49.75),
        "NEMO grid ji": (598, 282),
    },
    # Airports
    "Comox Airport": {
        "lon lat": (-124.900, 49.717),
        "NEMO grid ji": (660, 134),
        "wind grid ji": (173, 108),
    },
    "Squamish Airport": {
        "lon lat": (-123.161, 49.783),
        "wind grid ji": (166, 161),
    },
    "YVR": {
        "lon lat": (-123.184, 49.195),
        "GEM2.5 grid ji": (139, 155),
        "wind grid ji": (139, 155),
    },
    # ORCA Buoys
    "Hoodsport": {
        "lon lat": (-123.1126, 47.4218),
        "NEMO grid ji": (89, 114),
    },
    "Twanoh": {
        "lon lat": (-123.0083, 47.3750),
        "NEMO grid ji": (72, 123),
    },
    "DabobBay": {
        "lon lat": (-122.8029, 47.8031),
        "NEMO grid ji": (141, 205),
    },
    "PointWells": {
        "lon lat": (-122.3972, 47.7612),
        "NEMO grid ji": (104, 259),
    },
    "CarrInlet": {
        "lon lat": (-122.7300, 47.2800),
        "NEMO grid ji": (34, 152),
    },
    "Hansville": {
        "lon lat": (-122.627, 47.90733),
        "NEMO grid ji": (148, 243),
    },
    "Dockton": {
        "lon lat": (-122.45722, 47.37611),
        "NEMO grid ji": (34, 204),
    },
    "PointWilliams": {
        "lon lat": (-122.40612, 47.53716),
        "NEMO grid ji": (62, 231),
    },
}
# Aliases:
PLACES["Sandheads"] = PLACES["Sand Heads"]


#: Names of tide gauge sites,
#: ordered from south and west to north and east.
#: These names are keys of the :py:data:`~salishsea_tools.places.PLACES` dict.
TIDE_GAUGE_SITES = (
    "Neah Bay",
    "Victoria",
    "Cherry Point",
    "Point Atkinson",
    "Nanaimo",
    "Campbell River",
)
#: Other tide sites, no wind data at these (just to keep the number of arrows under control)
SUPP_TIDE_SITES = (
    "Friday Harbor",
    "Halfmoon Bay",
    "Patricia Bay",
    "Port Renfrew",
    "Squamish",
    "Boundary Bay",
    "Sand Heads",
)


[docs] def DispGeoLocs(): """Display locations in map coordinates :returns: figure handle :rtype: :py:class:`matplotlib.figure.Figure` """ from mpl_toolkits.basemap import Basemap from matplotlib import pyplot as plt places2 = PLACES.copy() places2.pop("Sandheads") places2.pop("Departure Bay") width = 300000 lon_0 = -124.3 lat_0 = 49 fig = plt.figure(figsize=(20, 20)) m = Basemap( width=width, height=width, projection="aeqd", resolution="h", lat_0=lat_0, lon_0=lon_0, ) m.drawmapboundary() m.drawcoastlines(linewidth=0.5) m.drawrivers() m.drawparallels(range(40, 60, 2)) m.drawmeridians(range(-130, -110, 2)) # plt.title('EC River Stations') # map stations: for pl in places2.keys(): if "lon lat" in places2[pl].keys(): lon, lat = places2[pl]["lon lat"] if (47 < lat < 51) & (-128 < lon < -120): if pl in ( "Sandy Cove", "Calamity Point", "Port Moody", "Vancouver", "New Westminster", "Delta DDL node", "East node", "Boundary Bay", "Duke Pt.", ): xpt, ypt = m(lon, lat) xpt2, ypt2 = m(lon + 0.03, lat) m.plot(xpt, ypt, "ro") plt.text( xpt2, ypt2, pl, fontsize=10, fontweight="bold", ha="left", va="center", color="r", ) else: xpt, ypt = m(lon, lat) xpt2, ypt2 = m(lon - 0.03, lat) m.plot(xpt, ypt, "ro") plt.text( xpt2, ypt2, pl, fontsize=10, fontweight="bold", ha="right", va="center", color="r", ) return fig
[docs] def DispGridLocs( mesh_mask="/ocean/eolson/MEOPAR/NEMO-forcing/grid/mesh_mask201702_noLPE.nc", ): """Display locations in NEMO model grid coordinates :arg mesh_mask: string with path to the meshmask you would like to plot; 201702 default :type mesh_mask: str :returns: figure handle :rtype: :py:class:`matplotlib.figure.Figure` """ import numpy as np # only grid from mpl_toolkits.basemap import Basemap import netCDF4 as nc # only grid from matplotlib import pyplot as plt from salishsea_tools import viz_tools # only grid places2 = PLACES.copy() places2.pop("Sandheads") places2.pop("Departure Bay") with nc.Dataset(mesh_mask) as fm: tmask = np.copy(fm.variables["tmask"]) e3t_0 = np.copy(fm.variables["e3t_0"]) bathy = np.sum(e3t_0[0, :, :, :] * tmask[0, :, :, :], 0) cm = plt.cm.get_cmap("Blues") cm.set_bad("lightgray") fig, ax = plt.subplots(1, 2, figsize=(18, 18)) viz_tools.set_aspect(ax[0]) viz_tools.set_aspect(ax[1]) ax[0].pcolormesh( np.ma.masked_where(tmask[0, 0, :, :] == 0, bathy), cmap=plt.cm.get_cmap("Blues") ) # map stations: for pl in places2.keys(): if ( "NEMO grid ji" in places2[pl].keys() and places2[pl]["NEMO grid ji"] is not None ): j, i = places2[pl]["NEMO grid ji"] if pl in ( "Sandy Cove", "Calamity Point", "Port Moody", "Vancouver", "New Westminster", "East Node", "Duke Pt.", "Halibut Bank", "Cherry Point", "Central SJDF", "Friday Harbor", ): ax[0].plot(i, j, "ro") ax[0].text( i + 4, j, pl, fontsize=10, fontweight="bold", ha="left", va="center", color="r", ) elif pl in ( "Sand Heads", "Delta DDL node", "Central Node", "Delta BBL node", "Cluster_9", "East Node", "Woodwards Landing", ): ax[0].plot(i, j, "ro") else: ax[0].plot(i, j, "ro") ax[0].text( i - 4, j, pl, fontsize=10, fontweight="bold", ha="right", va="center", color="r", ) xl = (240, 340) yl = (400, 450) ax[1].pcolormesh( np.ma.masked_where(tmask[0, 0, :, :] == 0, bathy), cmap=plt.cm.get_cmap("Blues") ) # map stations: for pl in places2.keys(): if ( "NEMO grid ji" in places2[pl].keys() and places2[pl]["NEMO grid ji"] is not None ): j, i = places2[pl]["NEMO grid ji"] if (xl[0] < i < xl[1]) & (yl[0] < j < yl[1]): if pl in ( "Sandy Cove", "Calamity Point", "Port Moody", "Vancouver", "New Westminster", "Friday Harbor", "East Node", "Duke Point", "Halibut Bank", "Cherry Point", "Sand Heads", "Cluster_9", "Central SJDF", ): ax[1].plot(i, j, "ro") ax[1].text( i + 1, j, pl, fontsize=10, fontweight="bold", ha="left", va="center", color="r", ) elif pl in ("Delta BBL node"): ax[1].plot(i, j, "ro") ax[1].text( i, j - 2, pl, fontsize=10, fontweight="bold", ha="center", va="center", color="r", ) elif pl in ("Delta DDL node"): ax[1].plot(i, j, "ro") ax[1].text( i, j + 2, pl, fontsize=10, fontweight="bold", ha="right", va="center", color="r", ) else: ax[1].plot(i, j, "ro") ax[1].text( i - 1, j, pl, fontsize=10, fontweight="bold", ha="right", va="center", color="r", ) ax[1].set_xlim(xl[0], xl[1]) ax[1].set_ylim(yl[0], yl[1]) return fig