Project Pythia Logo ECMWF logo Google logo

02_InteractiveVisualization Part 1: Geoviews


Overview

A team at Google Research & Cloud are making parts of the ECMWF Reanalysis version 5 (aka ERA-5) accessible in a Analysis Ready, Cloud Optimized (aka ARCO) format.

In this notebook, we will do the following:

  1. Access the ERA-5 ARCO catalog

  2. Select a particular dataset and variable from the catalog

  3. Convert the data from Gaussian to Cartesian coordinates

  4. Plot a map of sea-level pressure contours and 2-meter temperature mesh using Geoviews.

Prerequisites

Concepts

Importance

Notes

Cartopy

Necessary

Xarray

Necessary

[Geoviews]

Necessary

  • Time to learn: 30 minutes


Imports

import fsspec
import xarray as xr
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.feature as cfeature
from metpy import calc as mpcalc
from metpy.units import units
import metpy
import scipy.spatial
import numpy as np
/knight/mamba_aug23/envs/sep23_env/lib/python3.11/site-packages/dask/config.py:742: FutureWarning: Dask configuration key 'ucx.cuda-copy' has been deprecated; please use 'distributed.ucx.cuda_copy' instead
  warnings.warn(
/knight/mamba_aug23/envs/sep23_env/lib/python3.11/site-packages/dask/config.py:742: FutureWarning: Dask configuration key 'ucx.tcp' has been deprecated; please use 'distributed.ucx.tcp' instead
  warnings.warn(
/knight/mamba_aug23/envs/sep23_env/lib/python3.11/site-packages/dask/config.py:742: FutureWarning: Dask configuration key 'ucx.nvlink' has been deprecated; please use 'distributed.ucx.nvlink' instead
  warnings.warn(
/knight/mamba_aug23/envs/sep23_env/lib/python3.11/site-packages/dask/config.py:742: FutureWarning: Dask configuration key 'ucx.infiniband' has been deprecated; please use 'distributed.ucx.infiniband' instead
  warnings.warn(
/knight/mamba_aug23/envs/sep23_env/lib/python3.11/site-packages/dask/config.py:742: FutureWarning: Dask configuration key 'ucx.rdmacm' has been deprecated; please use 'distributed.ucx.rdmacm' instead
  warnings.warn(
/knight/mamba_aug23/envs/sep23_env/lib/python3.11/site-packages/dask/config.py:742: FutureWarning: Dask configuration key 'ucx.net-devices' has been deprecated; please use 'distributed.ucx.net-devices' instead
  warnings.warn(
/knight/mamba_aug23/envs/sep23_env/lib/python3.11/site-packages/dask/config.py:742: FutureWarning: Dask configuration key 'ucx.reuse-endpoints' has been deprecated; please use 'distributed.ucx.reuse-endpoints' instead
  warnings.warn(
/knight/mamba_aug23/envs/sep23_env/lib/python3.11/site-packages/dask/config.py:742: FutureWarning: Dask configuration key 'rmm.pool-size' has been deprecated; please use 'distributed.rmm.pool-size' instead
  warnings.warn(

Access the ARCO ERA-5 catalog on Google Cloud

Let’s open the 37-level isobaric surfaces reanalysis Zarr file

reanalysis = xr.open_zarr(
    'gs://gcp-public-data-arco-era5/ar/1959-2022-full_37-1h-0p25deg-chunk-1.zarr-v2', 
    chunks={'time': 48},
    consolidated=True,
)
reanalysis
<xarray.Dataset>
Dimensions:                                           (time: 552264,
                                                       latitude: 721,
                                                       longitude: 1440,
                                                       level: 37)
Coordinates:
  * latitude                                          (latitude) float32 90.0...
  * level                                             (level) int64 1 2 ... 1000
  * longitude                                         (longitude) float32 0.0...
  * time                                              (time) datetime64[ns] 1...
Data variables: (12/31)
    10m_u_component_of_wind                           (time, latitude, longitude) float32 dask.array<chunksize=(48, 721, 1440), meta=np.ndarray>
    10m_v_component_of_wind                           (time, latitude, longitude) float32 dask.array<chunksize=(48, 721, 1440), meta=np.ndarray>
    2m_temperature                                    (time, latitude, longitude) float32 dask.array<chunksize=(48, 721, 1440), meta=np.ndarray>
    angle_of_sub_gridscale_orography                  (latitude, longitude) float32 dask.array<chunksize=(721, 1440), meta=np.ndarray>
    anisotropy_of_sub_gridscale_orography             (latitude, longitude) float32 dask.array<chunksize=(721, 1440), meta=np.ndarray>
    geopotential                                      (time, level, latitude, longitude) float32 dask.array<chunksize=(48, 37, 721, 1440), meta=np.ndarray>
    ...                                                ...
    total_precipitation                               (time, latitude, longitude) float32 dask.array<chunksize=(48, 721, 1440), meta=np.ndarray>
    type_of_high_vegetation                           (latitude, longitude) float32 dask.array<chunksize=(721, 1440), meta=np.ndarray>
    type_of_low_vegetation                            (latitude, longitude) float32 dask.array<chunksize=(721, 1440), meta=np.ndarray>
    u_component_of_wind                               (time, level, latitude, longitude) float32 dask.array<chunksize=(48, 37, 721, 1440), meta=np.ndarray>
    v_component_of_wind                               (time, level, latitude, longitude) float32 dask.array<chunksize=(48, 37, 721, 1440), meta=np.ndarray>
    vertical_velocity                                 (time, level, latitude, longitude) float32 dask.array<chunksize=(48, 37, 721, 1440), meta=np.ndarray>
geop = reanalysis.geopotential
temp = reanalysis.temperature
geop
<xarray.DataArray 'geopotential' (time: 552264, level: 37, latitude: 721,
                                  longitude: 1440)>
dask.array<open_dataset-geopotential, shape=(552264, 37, 721, 1440), dtype=float32, chunksize=(48, 37, 721, 1440), chunktype=numpy.ndarray>
Coordinates:
  * latitude   (latitude) float32 90.0 89.75 89.5 89.25 ... -89.5 -89.75 -90.0
  * level      (level) int64 1 2 3 5 7 10 20 30 ... 850 875 900 925 950 975 1000
  * longitude  (longitude) float32 0.0 0.25 0.5 0.75 ... 359.0 359.2 359.5 359.8
  * time       (time) datetime64[ns] 1959-01-01 ... 2021-12-31T23:00:00
Attributes:
    long_name:      Geopotential
    short_name:     z
    standard_name:  geopotential
    units:          m**2 s**-2

Select time and level ranges from the dataset.

geopSub1 = geop.sel(time=slice('1993-03-13T18:00:00','1993-03-14T00:00:00'), level=500).compute()
tempSub1 = temp.sel(time=slice('1993-03-13T18:00:00','1993-03-14T00:00:00'), level=850).compute()
/knight/mamba_aug23/envs/sep23_env/lib/python3.11/site-packages/dask/config.py:742: FutureWarning: Dask configuration key 'ucx' has been deprecated; please use 'distributed.comm.ucx' instead
  warnings.warn(
/knight/mamba_aug23/envs/sep23_env/lib/python3.11/site-packages/dask/config.py:742: FutureWarning: Dask configuration key 'rmm' has been deprecated; please use 'distributed.rmm' instead
  warnings.warn(

Convert to dam and deg C.

Z = mpcalc.geopotential_to_height(geopSub1).metpy.convert_units('dam')
T = tempSub1.metpy.convert_units('degC')
Z
<xarray.DataArray (time: 7, latitude: 721, longitude: 1440)>
<Quantity([[[496.11923 496.11923 496.11923 ... 496.11923 496.11923 496.11923]
  [495.4044  495.40805 495.40988 ... 495.39526 495.4008  495.4026 ]
  [494.79037 494.7941  494.79956 ... 494.77393 494.77945 494.78488]
  ...
  [491.92023 491.91656 491.91656 ... 491.92023 491.92023 491.92023]
  [491.47482 491.47482 491.47482 ... 491.47482 491.47482 491.47482]
  [491.01846 491.01846 491.01846 ... 491.01846 491.01846 491.01846]]

 [[496.9404  496.9404  496.9404  ... 496.9404  496.9404  496.9404 ]
  [496.1687  496.17236 496.17422 ... 496.15958 496.16138 496.16684]
  [495.5034  495.51074 495.51627 ... 495.48688 495.4924  495.49786]
  ...
  [492.12735 492.12735 492.12735 ... 492.12915 492.12915 492.12915]
  [491.70944 491.70578 491.70578 ... 491.70944 491.70944 491.70944]
  [491.2622  491.2622  491.2622  ... 491.2622  491.2622  491.2622 ]]

 [[497.71384 497.71384 497.71384 ... 497.71384 497.71384 497.71384]
  [496.88535 496.88718 496.89084 ... 496.87436 496.878   496.87985]
  [496.17422 496.18335 496.187   ... 496.1577  496.16504 496.17056]
  ...
...
  ...
  [492.77792 492.77792 492.77792 ... 492.7798  492.7798  492.7798 ]
  [492.3491  492.34543 492.34543 ... 492.3491  492.3491  492.3491 ]
  [491.8854  491.8854  491.8854  ... 491.8854  491.8854  491.8854 ]]

 [[500.47592 500.47592 500.47592 ... 500.47592 500.47592 500.47592]
  [499.58884 499.5925  499.5962  ... 499.57593 499.5796  499.58517]
  [498.8355  498.84283 498.85016 ... 498.81174 498.819   498.8264 ]
  ...
  [492.83292 492.83292 492.83292 ... 492.83478 492.83292 492.83292]
  [492.38574 492.38574 492.38574 ... 492.38574 492.38574 492.38574]
  [491.92023 491.92023 491.92023 ... 491.92023 491.92023 491.92023]]

 [[501.2972  501.2972  501.2972  ... 501.2972  501.2972  501.2972 ]
  [500.40225 500.4078  500.40973 ... 500.39102 500.39478 500.40036]
  [499.6473  499.65485 499.66232 ... 499.6268  499.63428 499.64175]
  ...
  [492.91885 492.91885 492.91885 ... 492.9226  492.9226  492.9226 ]
  [492.4518  492.4518  492.4518  ... 492.4518  492.4518  492.4518 ]
  [491.97714 491.97714 491.97714 ... 491.97714 491.97714 491.97714]]], 'decameter')>
Coordinates:
  * latitude   (latitude) float32 90.0 89.75 89.5 89.25 ... -89.5 -89.75 -90.0
    level      int64 500
  * longitude  (longitude) float32 0.0 0.25 0.5 0.75 ... 359.0 359.2 359.5 359.8
  * time       (time) datetime64[ns] 1993-03-13T18:00:00 ... 1993-03-14
T
<xarray.DataArray 'temperature' (time: 7, latitude: 721, longitude: 1440)>
<Quantity([[[-27.231277 -27.231277 -27.231277 ... -27.231277 -27.231277 -27.231277]
  [-27.653152 -27.650772 -27.650772 ... -27.656723 -27.654343 -27.653152]
  [-28.072647 -28.070251 -28.069061 ... -28.080978 -28.076218 -28.075027]
  ...
  [-29.216705 -29.2191   -29.2191   ... -29.215515 -29.216705 -29.216705]
  [-29.601654 -29.601654 -29.601654 ... -29.601654 -29.601654 -29.601654]
  [-30.096222 -30.096222 -30.096222 ... -30.096222 -30.096222 -30.096222]]

 [[-27.255112 -27.255112 -27.255112 ... -27.255112 -27.255112 -27.255112]
  [-27.598328 -27.595947 -27.594757 ... -27.601898 -27.600708 -27.598328]
  [-27.967773 -27.964188 -27.961807 ... -27.973724 -27.971344 -27.970154]
  ...
  [-29.051056 -29.051056 -29.053452 ... -29.047485 -29.047485 -29.049866]
  [-29.444336 -29.444336 -29.444336 ... -29.444336 -29.444336 -29.444336]
  [-29.961548 -29.961548 -29.961548 ... -29.961548 -29.961548 -29.961548]]

 [[-27.234848 -27.234848 -27.234848 ... -27.234848 -27.234848 -27.234848]
  [-27.538742 -27.537552 -27.535172 ... -27.543518 -27.541122 -27.538742]
  [-27.901031 -27.898651 -27.89627  ... -27.908188 -27.906982 -27.904602]
  ...
...
  ...
  [-28.604156 -28.607727 -28.610123 ... -28.59462  -28.598206 -28.600586]
  [-28.928314 -28.930695 -28.931885 ... -28.924744 -28.925934 -28.925934]
  [-29.38713  -29.38713  -29.38713  ... -29.38713  -29.38713  -29.38713 ]]

 [[-26.82727  -26.82727  -26.82727  ... -26.82727  -26.82727  -26.82727 ]
  [-27.004837 -27.002457 -27.001266 ... -27.008423 -27.007233 -27.007233]
  [-27.172882 -27.169312 -27.166916 ... -27.182419 -27.178833 -27.175262]
  ...
  [-28.549347 -28.554108 -28.555298 ... -28.54219  -28.54457  -28.548141]
  [-28.811523 -28.813904 -28.813904 ... -28.807953 -28.809143 -28.809143]
  [-29.171432 -29.171432 -29.171432 ... -29.171432 -29.171432 -29.171432]]

 [[-26.590942 -26.590942 -26.590942 ... -26.590942 -26.590942 -26.590942]
  [-26.659225 -26.658035 -26.658035 ... -26.664032 -26.664032 -26.661621]
  [-26.710754 -26.708359 -26.704758 ... -26.717941 -26.716736 -26.714355]
  ...
  [-28.46251  -28.46611  -28.470901 ... -28.450531 -28.454132 -28.458923]
  [-28.663803 -28.666199 -28.667404 ... -28.660217 -28.661407 -28.661407]
  [-28.958557 -28.958557 -28.958557 ... -28.958557 -28.958557 -28.958557]]], 'degree_Celsius')>
Coordinates:
  * latitude   (latitude) float32 90.0 89.75 89.5 89.25 ... -89.5 -89.75 -90.0
    level      int64 850
  * longitude  (longitude) float32 0.0 0.25 0.5 0.75 ... 359.0 359.2 359.5 359.8
  * time       (time) datetime64[ns] 1993-03-13T18:00:00 ... 1993-03-14
Attributes:
    long_name:      Temperature
    short_name:     t
    standard_name:  air_temperature

Plot the data using Matplotlib

projData = ccrs.PlateCarree()
lons, lats = Z.longitude, Z.latitude
tLevels = np.arange(-45,39,3)
zLevels = np.arange(468, 606, 6)
res = '110m'
dpi = 100
fig = plt.figure(figsize=(2048/dpi, 1024/dpi))
ax = plt.subplot(1,1,1,projection=projData, frameon=False)

ax.add_feature(cfeature.COASTLINE.with_scale(res), edgecolor='brown', linewidth=2.5)
ax.add_feature(cfeature.BORDERS.with_scale(res), edgecolor='brown', linewidth=2.5)
ax.add_feature(cfeature.STATES.with_scale(res), edgecolor='brown')

# Temperature (T) contour fills

# Note we don't need the transform argument since the map/data projections are the same, but we'll leave it in
CF = ax.contourf(lons,lats,T,levels=tLevels,cmap=plt.get_cmap('coolwarm'), extend='both', transform=projData) 

# Height (Z) contour lines
CL = ax.contour(lons,lats,Z,zLevels,linewidths=1.25,colors='yellow', transform=projData)
ax.clabel(CL, inline_spacing=0.2, fontsize=8, fmt='%.0f')
fig.tight_layout(pad=.01)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[14], line 13
      8 ax.add_feature(cfeature.STATES.with_scale(res), edgecolor='brown')
     10 # Temperature (T) contour fills
     11 
     12 # Note we don't need the transform argument since the map/data projections are the same, but we'll leave it in
---> 13 CF = ax.contourf(lons,lats,T,levels=tLevels,cmap=plt.get_cmap('coolwarm'), extend='both', transform=projData) 
     15 # Height (Z) contour lines
     16 CL = ax.contour(lons,lats,Z,zLevels,linewidths=1.25,colors='yellow', transform=projData)

File /knight/mamba_aug23/envs/sep23_env/lib/python3.11/site-packages/cartopy/mpl/geoaxes.py:315, in _add_transform.<locals>.wrapper(self, *args, **kwargs)
    310     raise ValueError(f'Invalid transform: Spherical {func.__name__} '
    311                      'is not supported - consider using '
    312                      'PlateCarree/RotatedPole.')
    314 kwargs['transform'] = transform
--> 315 return func(self, *args, **kwargs)

File /knight/mamba_aug23/envs/sep23_env/lib/python3.11/site-packages/cartopy/mpl/geoaxes.py:359, in _add_transform_first.<locals>.wrapper(self, *args, **kwargs)
    357     # Use the new points as the input arguments
    358     args = (x, y, z) + args[3:]
--> 359 return func(self, *args, **kwargs)

File /knight/mamba_aug23/envs/sep23_env/lib/python3.11/site-packages/cartopy/mpl/geoaxes.py:1655, in GeoAxes.contourf(self, *args, **kwargs)
   1652             if not hasattr(sub_trans, 'force_path_ccw'):
   1653                 sub_trans.force_path_ccw = True
-> 1655 result = super().contourf(*args, **kwargs)
   1657 # We need to compute the dataLim correctly for contours.
   1658 if _MPL_VERSION.release[:2] < (3, 8):

File /knight/mamba_aug23/envs/sep23_env/lib/python3.11/site-packages/matplotlib/__init__.py:1446, in _preprocess_data.<locals>.inner(ax, data, *args, **kwargs)
   1443 @functools.wraps(func)
   1444 def inner(ax, *args, data=None, **kwargs):
   1445     if data is None:
-> 1446         return func(ax, *map(sanitize_sequence, args), **kwargs)
   1448     bound = new_sig.bind(ax, *args, **kwargs)
   1449     auto_label = (bound.arguments.get(label_namer)
   1450                   or bound.kwargs.get(label_namer))

File /knight/mamba_aug23/envs/sep23_env/lib/python3.11/site-packages/matplotlib/axes/_axes.py:6465, in Axes.contourf(self, *args, **kwargs)
   6456 """
   6457 Plot filled contours.
   6458 
   (...)
   6462 %(contour_doc)s
   6463 """
   6464 kwargs['filled'] = True
-> 6465 contours = mcontour.QuadContourSet(self, *args, **kwargs)
   6466 self._request_autoscale_view()
   6467 return contours

File /knight/mamba_aug23/envs/sep23_env/lib/python3.11/site-packages/matplotlib/contour.py:769, in ContourSet.__init__(self, ax, levels, filled, linewidths, linestyles, hatches, alpha, origin, extent, cmap, colors, norm, vmin, vmax, extend, antialiased, nchunk, locator, transform, negative_linestyles, *args, **kwargs)
    765 if self.negative_linestyles is None:
    766     self.negative_linestyles = \
    767         mpl.rcParams['contour.negative_linestyle']
--> 769 kwargs = self._process_args(*args, **kwargs)
    770 self._process_levels()
    772 self._extend_min = self.extend in ['min', 'both']

File /knight/mamba_aug23/envs/sep23_env/lib/python3.11/site-packages/matplotlib/contour.py:1411, in QuadContourSet._process_args(self, corner_mask, algorithm, *args, **kwargs)
   1408         corner_mask = mpl.rcParams['contour.corner_mask']
   1409 self._corner_mask = corner_mask
-> 1411 x, y, z = self._contour_args(args, kwargs)
   1413 contour_generator = contourpy.contour_generator(
   1414     x, y, z, name=self._algorithm, corner_mask=self._corner_mask,
   1415     line_type=contourpy.LineType.SeparateCode,
   1416     fill_type=contourpy.FillType.OuterCode,
   1417     chunk_size=self.nchunk)
   1419 t = self.get_transform()

File /knight/mamba_aug23/envs/sep23_env/lib/python3.11/site-packages/matplotlib/contour.py:1450, in QuadContourSet._contour_args(self, args, kwargs)
   1448 elif nargs <= 4:
   1449     x, y, z_orig, *args = args
-> 1450     x, y, z = self._check_xyz(x, y, z_orig, kwargs)
   1451 else:
   1452     raise _api.nargs_error(fn, takes="from 1 to 4", given=nargs)

File /knight/mamba_aug23/envs/sep23_env/lib/python3.11/site-packages/matplotlib/contour.py:1475, in QuadContourSet._check_xyz(self, x, y, z, kwargs)
   1472 z = ma.asarray(z)
   1474 if z.ndim != 2:
-> 1475     raise TypeError(f"Input z must be 2D, not {z.ndim}D")
   1476 if z.shape[0] < 2 or z.shape[1] < 2:
   1477     raise TypeError(f"Input z must be at least a (2, 2) shaped array, "
   1478                     f"but has shape {z.shape}")

TypeError: Input z must be 2D, not 3D
../../_images/2dad7fa22268000deaf26fbcc306c2122b2dd9098e9bda741e7f3c3eb9976354.png
res = '110m'
dpi = 100
fig = plt.figure(figsize=(2048/dpi, 1024/dpi))
ax = plt.subplot(1,1,1,projection=projData, frameon=False)

ax.add_feature(cfeature.COASTLINE.with_scale(res), edgecolor='brown', linewidth=2.5)
ax.add_feature(cfeature.BORDERS.with_scale(res), edgecolor='brown', linewidth=2.5)
ax.add_feature(cfeature.STATES.with_scale(res), edgecolor='brown')

# Temperature (T) contour fills

# Note we don't need the transform argument since the map/data projections are the same, but we'll leave it in
CF = ax.contourf(lons,lats,T.isel(time=0),levels=tLevels,cmap=plt.get_cmap('coolwarm'), extend='both', transform=projData) 

# Height (Z) contour lines
CL = ax.contour(lons,lats,Z.isel(time=0),zLevels,linewidths=1.25,colors='yellow', transform=projData)
ax.clabel(CL, inline_spacing=0.2, fontsize=8, fmt='%.0f')
fig.tight_layout(pad=.01)
../../_images/09cfbf4e319680659234fe6beb2083895d673389931492675407fd602352ba68.png
lonW, lonE, latS, latN = -130, -60, 20, 55 
lonRange = np.arange(lonW, lonE + 0.1, 0.25)
latRange = np.arange(latS, latN + 0.1, 0.25)
ZSub2 = Z.sel(latitude = latRange, longitude = lonRange)
TSub2 = T.sel(latitude = latRange, longitude = lonRange)
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
Cell In[18], line 1
----> 1 ZSub2 = Z.sel(latitude = latRange, longitude = lonRange)
      2 TSub2 = T.sel(latitude = latRange, longitude = lonRange)

File /knight/mamba_aug23/envs/sep23_env/lib/python3.11/site-packages/xarray/core/dataarray.py:1582, in DataArray.sel(self, indexers, method, tolerance, drop, **indexers_kwargs)
   1472 def sel(
   1473     self: T_DataArray,
   1474     indexers: Mapping[Any, Any] | None = None,
   (...)
   1478     **indexers_kwargs: Any,
   1479 ) -> T_DataArray:
   1480     """Return a new DataArray whose data is given by selecting index
   1481     labels along the specified dimension(s).
   1482 
   (...)
   1580     Dimensions without coordinates: points
   1581     """
-> 1582     ds = self._to_temp_dataset().sel(
   1583         indexers=indexers,
   1584         drop=drop,
   1585         method=method,
   1586         tolerance=tolerance,
   1587         **indexers_kwargs,
   1588     )
   1589     return self._from_temp_dataset(ds)

File /knight/mamba_aug23/envs/sep23_env/lib/python3.11/site-packages/xarray/core/dataset.py:3020, in Dataset.sel(self, indexers, method, tolerance, drop, **indexers_kwargs)
   2959 """Returns a new dataset with each array indexed by tick labels
   2960 along the specified dimension(s).
   2961 
   (...)
   3017 DataArray.sel
   3018 """
   3019 indexers = either_dict_or_kwargs(indexers, indexers_kwargs, "sel")
-> 3020 query_results = map_index_queries(
   3021     self, indexers=indexers, method=method, tolerance=tolerance
   3022 )
   3024 if drop:
   3025     no_scalar_variables = {}

File /knight/mamba_aug23/envs/sep23_env/lib/python3.11/site-packages/xarray/core/indexing.py:190, in map_index_queries(obj, indexers, method, tolerance, **indexers_kwargs)
    188         results.append(IndexSelResult(labels))
    189     else:
--> 190         results.append(index.sel(labels, **options))
    192 merged = merge_sel_results(results)
    194 # drop dimension coordinates found in dimension indexers
    195 # (also drop multi-index if any)
    196 # (.sel() already ensures alignment)

File /knight/mamba_aug23/envs/sep23_env/lib/python3.11/site-packages/xarray/core/indexes.py:781, in PandasIndex.sel(self, labels, method, tolerance)
    779     indexer = get_indexer_nd(self.index, label_array, method, tolerance)
    780     if np.any(indexer < 0):
--> 781         raise KeyError(f"not all values found in index {coord_name!r}")
    783 # attach dimension names and/or coordinates to positional indexer
    784 if isinstance(label, Variable):

KeyError: "not all values found in index 'longitude'"
projMap = ccrs.
  Cell In[19], line 1
    projMap = ccrs.
                   ^
SyntaxError: invalid syntax
res = '50m'
dpi = 100
fig = plt.figure(figsize=(2048/dpi, 1024/dpi))
ax = plt.subplot(1,1,1,projection=, frameon=False)

ax.add_feature(cfeature.COASTLINE.with_scale(res), edgecolor='brown', linewidth=2.5)
ax.add_feature(cfeature.BORDERS.with_scale(res), edgecolor='brown', linewidth=2.5)
ax.add_feature(cfeature.STATES.with_scale(res), edgecolor='brown')

# Temperature (T) contour fills

# Note we don't need the transform argument since the map/data projections are the same, but we'll leave it in
CF = ax.contourf(lons,lats,T.isel(time=0),levels=tLevels,cmap=plt.get_cmap('coolwarm'), extend='both', transform=projData) 

# Height (Z) contour lines
CL = ax.contour(lons,lats,Z.isel(time=0),zLevels,linewidths=1.25,colors='yellow', transform=projData)
ax.clabel(CL, inline_spacing=0.2, fontsize=8, fmt='%.0f')
fig.tight_layout(pad=.01)
  Cell In[20], line 4
    ax = plt.subplot(1,1,1,projection=, frameon=False)
                                      ^
SyntaxError: invalid syntax