You can run this notebook in a live session or view it on Github.
GRIB Data Example¶
GRIB format is commonly used to disseminate atmospheric model data. With xarray and the cfgrib engine, GRIB data can easily be analyzed and visualized.
[1]:
import xarray as xr
import matplotlib.pyplot as plt
Fontconfig error: No writable cache directories
To read GRIB data, you can use xarray.load_dataset
. The only extra code you need is to specify the engine as cfgrib
.
[2]:
ds = xr.tutorial.load_dataset("era5-2mt-2019-03-uk.grib", engine="cfgrib")
---------------------------------------------------------------------------
PermissionError Traceback (most recent call last)
File /usr/lib/python3/dist-packages/pooch/utils.py:262, in make_local_storage(path, env)
258 if action == "create":
259 # When running in parallel, it's possible that multiple jobs will
260 # try to create the path at the same time. Use exist_ok to avoid
261 # raising an error.
--> 262 os.makedirs(path, exist_ok=True)
263 else:
File /usr/lib/python3.12/os.py:215, in makedirs(name, mode, exist_ok)
214 try:
--> 215 makedirs(head, exist_ok=exist_ok)
216 except FileExistsError:
217 # Defeats race condition when another thread created the path
File /usr/lib/python3.12/os.py:215, in makedirs(name, mode, exist_ok)
214 try:
--> 215 makedirs(head, exist_ok=exist_ok)
216 except FileExistsError:
217 # Defeats race condition when another thread created the path
File /usr/lib/python3.12/os.py:225, in makedirs(name, mode, exist_ok)
224 try:
--> 225 mkdir(name, mode)
226 except OSError:
227 # Cannot rely on checking for EEXIST, since the operating system
228 # could give priority to other errors like EACCES or EROFS
PermissionError: [Errno 13] Permission denied: '/sbuild-nonexistent'
The above exception was the direct cause of the following exception:
PermissionError Traceback (most recent call last)
Cell In[2], line 1
----> 1 ds = xr.tutorial.load_dataset("era5-2mt-2019-03-uk.grib", engine="cfgrib")
File /usr/lib/python3/dist-packages/xarray/tutorial.py:207, in load_dataset(*args, **kwargs)
170 def load_dataset(*args, **kwargs) -> Dataset:
171 """
172 Open, load into memory, and close a dataset from the online repository
173 (requires internet).
(...)
205 load_dataset
206 """
--> 207 with open_dataset(*args, **kwargs) as ds:
208 return ds.load()
File /usr/lib/python3/dist-packages/xarray/tutorial.py:161, in open_dataset(name, cache, cache_dir, engine, **kws)
158 url = f"{base_url}/raw/{version}/{path.name}"
160 # retrieve the file
--> 161 filepath = pooch.retrieve(url=url, known_hash=None, path=cache_dir)
162 ds = _open_dataset(filepath, engine=engine, **kws)
163 if not cache:
File /usr/lib/python3/dist-packages/pooch/core.py:227, in retrieve(url, known_hash, fname, path, processor, downloader, progressbar)
222 action, verb = download_action(full_path, known_hash)
224 if action in ("download", "update"):
225 # We need to write data, so create the local data directory if it
226 # doesn't already exist.
--> 227 make_local_storage(path)
229 get_logger().info(
230 "%s data from '%s' to file '%s'.",
231 verb,
232 url,
233 str(full_path),
234 )
236 if downloader is None:
File /usr/lib/python3/dist-packages/pooch/utils.py:276, in make_local_storage(path, env)
272 if env is not None:
273 message.append(
274 f"Use environment variable '{env}' to specify a different location."
275 )
--> 276 raise PermissionError(" ".join(message)) from error
PermissionError: [Errno 13] Permission denied: '/sbuild-nonexistent' | Pooch could not create data cache folder '/sbuild-nonexistent/.cache/xarray_tutorial_data'. Will not be able to download data files.
Let’s create a simple plot of 2-m air temperature in degrees Celsius:
[3]:
ds = ds - 273.15
ds.t2m[0].plot(cmap=plt.cm.coolwarm)
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Cell In[3], line 1
----> 1 ds = ds - 273.15
2 ds.t2m[0].plot(cmap=plt.cm.coolwarm)
NameError: name 'ds' is not defined
With CartoPy, we can create a more detailed plot, using built-in shapefiles to help provide geographic context:
[4]:
import cartopy.crs as ccrs
import cartopy
fig = plt.figure(figsize=(10, 10))
ax = plt.axes(projection=ccrs.Robinson())
ax.coastlines(resolution="10m")
plot = ds.t2m[0].plot(
cmap=plt.cm.coolwarm, transform=ccrs.PlateCarree(), cbar_kwargs={"shrink": 0.6}
)
plt.title("ERA5 - 2m temperature British Isles March 2019")
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Cell In[4], line 7
5 ax = plt.axes(projection=ccrs.Robinson())
6 ax.coastlines(resolution="10m")
----> 7 plot = ds.t2m[0].plot(
8 cmap=plt.cm.coolwarm, transform=ccrs.PlateCarree(), cbar_kwargs={"shrink": 0.6}
9 )
10 plt.title("ERA5 - 2m temperature British Isles March 2019")
NameError: name 'ds' is not defined
Error in callback <function _draw_all_if_interactive at 0x7fcc8bcc2520> (for post_execute), with arguments args (),kwargs {}:
---------------------------------------------------------------------------
FileNotFoundError Traceback (most recent call last)
File /usr/lib/python3.12/pathlib.py:1313, in Path.mkdir(self, mode, parents, exist_ok)
1312 try:
-> 1313 os.mkdir(self, mode)
1314 except FileNotFoundError:
FileNotFoundError: [Errno 2] No such file or directory: '/sbuild-nonexistent/.local/share/cartopy/shapefiles/natural_earth/physical'
During handling of the above exception, another exception occurred:
FileNotFoundError Traceback (most recent call last)
File /usr/lib/python3.12/pathlib.py:1313, in Path.mkdir(self, mode, parents, exist_ok)
1312 try:
-> 1313 os.mkdir(self, mode)
1314 except FileNotFoundError:
FileNotFoundError: [Errno 2] No such file or directory: '/sbuild-nonexistent/.local/share/cartopy/shapefiles/natural_earth'
During handling of the above exception, another exception occurred:
FileNotFoundError Traceback (most recent call last)
File /usr/lib/python3.12/pathlib.py:1313, in Path.mkdir(self, mode, parents, exist_ok)
1312 try:
-> 1313 os.mkdir(self, mode)
1314 except FileNotFoundError:
FileNotFoundError: [Errno 2] No such file or directory: '/sbuild-nonexistent/.local/share/cartopy/shapefiles'
During handling of the above exception, another exception occurred:
FileNotFoundError Traceback (most recent call last)
File /usr/lib/python3.12/pathlib.py:1313, in Path.mkdir(self, mode, parents, exist_ok)
1312 try:
-> 1313 os.mkdir(self, mode)
1314 except FileNotFoundError:
FileNotFoundError: [Errno 2] No such file or directory: '/sbuild-nonexistent/.local/share/cartopy'
During handling of the above exception, another exception occurred:
FileNotFoundError Traceback (most recent call last)
File /usr/lib/python3.12/pathlib.py:1313, in Path.mkdir(self, mode, parents, exist_ok)
1312 try:
-> 1313 os.mkdir(self, mode)
1314 except FileNotFoundError:
FileNotFoundError: [Errno 2] No such file or directory: '/sbuild-nonexistent/.local/share'
During handling of the above exception, another exception occurred:
FileNotFoundError Traceback (most recent call last)
File /usr/lib/python3.12/pathlib.py:1313, in Path.mkdir(self, mode, parents, exist_ok)
1312 try:
-> 1313 os.mkdir(self, mode)
1314 except FileNotFoundError:
FileNotFoundError: [Errno 2] No such file or directory: '/sbuild-nonexistent/.local'
During handling of the above exception, another exception occurred:
PermissionError Traceback (most recent call last)
File /usr/lib/python3/dist-packages/matplotlib/pyplot.py:197, in _draw_all_if_interactive()
195 def _draw_all_if_interactive() -> None:
196 if matplotlib.is_interactive():
--> 197 draw_all()
File /usr/lib/python3/dist-packages/matplotlib/_pylab_helpers.py:132, in Gcf.draw_all(cls, force)
130 for manager in cls.get_all_fig_managers():
131 if force or manager.canvas.figure.stale:
--> 132 manager.canvas.draw_idle()
File /usr/lib/python3/dist-packages/matplotlib/backend_bases.py:1893, in FigureCanvasBase.draw_idle(self, *args, **kwargs)
1891 if not self._is_idle_drawing:
1892 with self._idle_draw_cntx():
-> 1893 self.draw(*args, **kwargs)
File /usr/lib/python3/dist-packages/matplotlib/backends/backend_agg.py:388, in FigureCanvasAgg.draw(self)
385 # Acquire a lock on the shared font cache.
386 with (self.toolbar._wait_cursor_for_draw_cm() if self.toolbar
387 else nullcontext()):
--> 388 self.figure.draw(self.renderer)
389 # A GUI class may be need to update a window using this draw, so
390 # don't forget to call the superclass.
391 super().draw()
File /usr/lib/python3/dist-packages/matplotlib/artist.py:95, in _finalize_rasterization.<locals>.draw_wrapper(artist, renderer, *args, **kwargs)
93 @wraps(draw)
94 def draw_wrapper(artist, renderer, *args, **kwargs):
---> 95 result = draw(artist, renderer, *args, **kwargs)
96 if renderer._rasterizing:
97 renderer.stop_rasterizing()
File /usr/lib/python3/dist-packages/matplotlib/artist.py:72, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
69 if artist.get_agg_filter() is not None:
70 renderer.start_filter()
---> 72 return draw(artist, renderer)
73 finally:
74 if artist.get_agg_filter() is not None:
File /usr/lib/python3/dist-packages/matplotlib/figure.py:3154, in Figure.draw(self, renderer)
3151 # ValueError can occur when resizing a window.
3153 self.patch.draw(renderer)
-> 3154 mimage._draw_list_compositing_images(
3155 renderer, self, artists, self.suppressComposite)
3157 for sfig in self.subfigs:
3158 sfig.draw(renderer)
File /usr/lib/python3/dist-packages/matplotlib/image.py:132, in _draw_list_compositing_images(renderer, parent, artists, suppress_composite)
130 if not_composite or not has_images:
131 for a in artists:
--> 132 a.draw(renderer)
133 else:
134 # Composite any adjacent images together
135 image_group = []
File /usr/lib/python3/dist-packages/matplotlib/artist.py:72, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
69 if artist.get_agg_filter() is not None:
70 renderer.start_filter()
---> 72 return draw(artist, renderer)
73 finally:
74 if artist.get_agg_filter() is not None:
File /usr/lib/python3/dist-packages/cartopy/mpl/geoaxes.py:525, in GeoAxes.draw(self, renderer, **kwargs)
520 self.imshow(img, extent=extent, origin=origin,
521 transform=factory.crs, *factory_args[1:],
522 **factory_kwargs)
523 self._done_img_factory = True
--> 525 return super().draw(renderer=renderer, **kwargs)
File /usr/lib/python3/dist-packages/matplotlib/artist.py:72, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
69 if artist.get_agg_filter() is not None:
70 renderer.start_filter()
---> 72 return draw(artist, renderer)
73 finally:
74 if artist.get_agg_filter() is not None:
File /usr/lib/python3/dist-packages/matplotlib/axes/_base.py:3070, in _AxesBase.draw(self, renderer)
3067 if artists_rasterized:
3068 _draw_rasterized(self.figure, artists_rasterized, renderer)
-> 3070 mimage._draw_list_compositing_images(
3071 renderer, self, artists, self.figure.suppressComposite)
3073 renderer.close_group('axes')
3074 self.stale = False
File /usr/lib/python3/dist-packages/matplotlib/image.py:132, in _draw_list_compositing_images(renderer, parent, artists, suppress_composite)
130 if not_composite or not has_images:
131 for a in artists:
--> 132 a.draw(renderer)
133 else:
134 # Composite any adjacent images together
135 image_group = []
File /usr/lib/python3/dist-packages/matplotlib/artist.py:72, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
69 if artist.get_agg_filter() is not None:
70 renderer.start_filter()
---> 72 return draw(artist, renderer)
73 finally:
74 if artist.get_agg_filter() is not None:
File /usr/lib/python3/dist-packages/cartopy/mpl/feature_artist.py:185, in FeatureArtist.draw(self, renderer)
180 geoms = self._feature.geometries()
181 else:
182 # For efficiency on local maps with high resolution features (e.g
183 # from Natural Earth), only create paths for geometries that are
184 # in view.
--> 185 geoms = self._feature.intersecting_geometries(extent)
187 stylised_paths = {}
188 # Make an empty placeholder style dictionary for when styler is not
189 # used. Freeze it so that we can use it as a dict key. We will need
190 # to unfreeze all style dicts with dict(frozen) before passing to mpl.
File /usr/lib/python3/dist-packages/cartopy/feature/__init__.py:309, in NaturalEarthFeature.intersecting_geometries(self, extent)
302 """
303 Returns an iterator of shapely geometries that intersect with
304 the given extent.
305 The extent is assumed to be in the CRS of the feature.
306 If extent is None, the method returns all geometries for this dataset.
307 """
308 self.scaler.scale_from_extent(extent)
--> 309 return super().intersecting_geometries(extent)
File /usr/lib/python3/dist-packages/cartopy/feature/__init__.py:112, in Feature.intersecting_geometries(self, extent)
109 if extent is not None and not np.isnan(extent[0]):
110 extent_geom = sgeom.box(extent[0], extent[2],
111 extent[1], extent[3])
--> 112 return (geom for geom in self.geometries() if
113 geom is not None and extent_geom.intersects(geom))
114 else:
115 return self.geometries()
File /usr/lib/python3/dist-packages/cartopy/feature/__init__.py:291, in NaturalEarthFeature.geometries(self)
289 key = (self.name, self.category, self.scale)
290 if key not in _NATURAL_EARTH_GEOM_CACHE:
--> 291 path = shapereader.natural_earth(resolution=self.scale,
292 category=self.category,
293 name=self.name)
294 geometries = tuple(shapereader.Reader(path).geometries())
295 _NATURAL_EARTH_GEOM_CACHE[key] = geometries
File /usr/lib/python3/dist-packages/cartopy/io/shapereader.py:306, in natural_earth(resolution, category, name)
302 ne_downloader = Downloader.from_config(('shapefiles', 'natural_earth',
303 resolution, category, name))
304 format_dict = {'config': config, 'category': category,
305 'name': name, 'resolution': resolution}
--> 306 return ne_downloader.path(format_dict)
File /usr/lib/python3/dist-packages/cartopy/io/__init__.py:203, in Downloader.path(self, format_dict)
200 result_path = target_path
201 else:
202 # we need to download the file
--> 203 result_path = self.acquire_resource(target_path, format_dict)
205 return result_path
File /usr/lib/python3/dist-packages/cartopy/io/shapereader.py:355, in NEShpDownloader.acquire_resource(self, target_path, format_dict)
352 from zipfile import ZipFile
354 target_dir = Path(target_path).parent
--> 355 target_dir.mkdir(parents=True, exist_ok=True)
357 url = self.url(format_dict)
359 shapefile_online = self._urlopen(url)
File /usr/lib/python3.12/pathlib.py:1317, in Path.mkdir(self, mode, parents, exist_ok)
1315 if not parents or self.parent == self:
1316 raise
-> 1317 self.parent.mkdir(parents=True, exist_ok=True)
1318 self.mkdir(mode, parents=False, exist_ok=exist_ok)
1319 except OSError:
1320 # Cannot rely on checking for EEXIST, since the operating system
1321 # could give priority to other errors like EACCES or EROFS
File /usr/lib/python3.12/pathlib.py:1317, in Path.mkdir(self, mode, parents, exist_ok)
1315 if not parents or self.parent == self:
1316 raise
-> 1317 self.parent.mkdir(parents=True, exist_ok=True)
1318 self.mkdir(mode, parents=False, exist_ok=exist_ok)
1319 except OSError:
1320 # Cannot rely on checking for EEXIST, since the operating system
1321 # could give priority to other errors like EACCES or EROFS
[... skipping similar frames: Path.mkdir at line 1317 (3 times)]
File /usr/lib/python3.12/pathlib.py:1317, in Path.mkdir(self, mode, parents, exist_ok)
1315 if not parents or self.parent == self:
1316 raise
-> 1317 self.parent.mkdir(parents=True, exist_ok=True)
1318 self.mkdir(mode, parents=False, exist_ok=exist_ok)
1319 except OSError:
1320 # Cannot rely on checking for EEXIST, since the operating system
1321 # could give priority to other errors like EACCES or EROFS
File /usr/lib/python3.12/pathlib.py:1313, in Path.mkdir(self, mode, parents, exist_ok)
1309 """
1310 Create a new directory at this given path.
1311 """
1312 try:
-> 1313 os.mkdir(self, mode)
1314 except FileNotFoundError:
1315 if not parents or self.parent == self:
PermissionError: [Errno 13] Permission denied: '/sbuild-nonexistent'
---------------------------------------------------------------------------
FileNotFoundError Traceback (most recent call last)
File /usr/lib/python3.12/pathlib.py:1313, in Path.mkdir(self, mode, parents, exist_ok)
1312 try:
-> 1313 os.mkdir(self, mode)
1314 except FileNotFoundError:
FileNotFoundError: [Errno 2] No such file or directory: '/sbuild-nonexistent/.local/share/cartopy/shapefiles/natural_earth/physical'
During handling of the above exception, another exception occurred:
FileNotFoundError Traceback (most recent call last)
File /usr/lib/python3.12/pathlib.py:1313, in Path.mkdir(self, mode, parents, exist_ok)
1312 try:
-> 1313 os.mkdir(self, mode)
1314 except FileNotFoundError:
FileNotFoundError: [Errno 2] No such file or directory: '/sbuild-nonexistent/.local/share/cartopy/shapefiles/natural_earth'
During handling of the above exception, another exception occurred:
FileNotFoundError Traceback (most recent call last)
File /usr/lib/python3.12/pathlib.py:1313, in Path.mkdir(self, mode, parents, exist_ok)
1312 try:
-> 1313 os.mkdir(self, mode)
1314 except FileNotFoundError:
FileNotFoundError: [Errno 2] No such file or directory: '/sbuild-nonexistent/.local/share/cartopy/shapefiles'
During handling of the above exception, another exception occurred:
FileNotFoundError Traceback (most recent call last)
File /usr/lib/python3.12/pathlib.py:1313, in Path.mkdir(self, mode, parents, exist_ok)
1312 try:
-> 1313 os.mkdir(self, mode)
1314 except FileNotFoundError:
FileNotFoundError: [Errno 2] No such file or directory: '/sbuild-nonexistent/.local/share/cartopy'
During handling of the above exception, another exception occurred:
FileNotFoundError Traceback (most recent call last)
File /usr/lib/python3.12/pathlib.py:1313, in Path.mkdir(self, mode, parents, exist_ok)
1312 try:
-> 1313 os.mkdir(self, mode)
1314 except FileNotFoundError:
FileNotFoundError: [Errno 2] No such file or directory: '/sbuild-nonexistent/.local/share'
During handling of the above exception, another exception occurred:
FileNotFoundError Traceback (most recent call last)
File /usr/lib/python3.12/pathlib.py:1313, in Path.mkdir(self, mode, parents, exist_ok)
1312 try:
-> 1313 os.mkdir(self, mode)
1314 except FileNotFoundError:
FileNotFoundError: [Errno 2] No such file or directory: '/sbuild-nonexistent/.local'
During handling of the above exception, another exception occurred:
PermissionError Traceback (most recent call last)
File /usr/lib/python3/dist-packages/IPython/core/formatters.py:340, in BaseFormatter.__call__(self, obj)
338 pass
339 else:
--> 340 return printer(obj)
341 # Finally look for special method names
342 method = get_real_method(obj, self.print_method)
File /usr/lib/python3/dist-packages/IPython/core/pylabtools.py:152, in print_figure(fig, fmt, bbox_inches, base64, **kwargs)
149 from matplotlib.backend_bases import FigureCanvasBase
150 FigureCanvasBase(fig)
--> 152 fig.canvas.print_figure(bytes_io, **kw)
153 data = bytes_io.getvalue()
154 if fmt == 'svg':
File /usr/lib/python3/dist-packages/matplotlib/backend_bases.py:2164, in FigureCanvasBase.print_figure(self, filename, dpi, facecolor, edgecolor, orientation, format, bbox_inches, pad_inches, bbox_extra_artists, backend, **kwargs)
2161 # we do this instead of `self.figure.draw_without_rendering`
2162 # so that we can inject the orientation
2163 with getattr(renderer, "_draw_disabled", nullcontext)():
-> 2164 self.figure.draw(renderer)
2165 if bbox_inches:
2166 if bbox_inches == "tight":
File /usr/lib/python3/dist-packages/matplotlib/artist.py:95, in _finalize_rasterization.<locals>.draw_wrapper(artist, renderer, *args, **kwargs)
93 @wraps(draw)
94 def draw_wrapper(artist, renderer, *args, **kwargs):
---> 95 result = draw(artist, renderer, *args, **kwargs)
96 if renderer._rasterizing:
97 renderer.stop_rasterizing()
File /usr/lib/python3/dist-packages/matplotlib/artist.py:72, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
69 if artist.get_agg_filter() is not None:
70 renderer.start_filter()
---> 72 return draw(artist, renderer)
73 finally:
74 if artist.get_agg_filter() is not None:
File /usr/lib/python3/dist-packages/matplotlib/figure.py:3154, in Figure.draw(self, renderer)
3151 # ValueError can occur when resizing a window.
3153 self.patch.draw(renderer)
-> 3154 mimage._draw_list_compositing_images(
3155 renderer, self, artists, self.suppressComposite)
3157 for sfig in self.subfigs:
3158 sfig.draw(renderer)
File /usr/lib/python3/dist-packages/matplotlib/image.py:132, in _draw_list_compositing_images(renderer, parent, artists, suppress_composite)
130 if not_composite or not has_images:
131 for a in artists:
--> 132 a.draw(renderer)
133 else:
134 # Composite any adjacent images together
135 image_group = []
File /usr/lib/python3/dist-packages/matplotlib/artist.py:72, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
69 if artist.get_agg_filter() is not None:
70 renderer.start_filter()
---> 72 return draw(artist, renderer)
73 finally:
74 if artist.get_agg_filter() is not None:
File /usr/lib/python3/dist-packages/cartopy/mpl/geoaxes.py:525, in GeoAxes.draw(self, renderer, **kwargs)
520 self.imshow(img, extent=extent, origin=origin,
521 transform=factory.crs, *factory_args[1:],
522 **factory_kwargs)
523 self._done_img_factory = True
--> 525 return super().draw(renderer=renderer, **kwargs)
File /usr/lib/python3/dist-packages/matplotlib/artist.py:72, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
69 if artist.get_agg_filter() is not None:
70 renderer.start_filter()
---> 72 return draw(artist, renderer)
73 finally:
74 if artist.get_agg_filter() is not None:
File /usr/lib/python3/dist-packages/matplotlib/axes/_base.py:3070, in _AxesBase.draw(self, renderer)
3067 if artists_rasterized:
3068 _draw_rasterized(self.figure, artists_rasterized, renderer)
-> 3070 mimage._draw_list_compositing_images(
3071 renderer, self, artists, self.figure.suppressComposite)
3073 renderer.close_group('axes')
3074 self.stale = False
File /usr/lib/python3/dist-packages/matplotlib/image.py:132, in _draw_list_compositing_images(renderer, parent, artists, suppress_composite)
130 if not_composite or not has_images:
131 for a in artists:
--> 132 a.draw(renderer)
133 else:
134 # Composite any adjacent images together
135 image_group = []
File /usr/lib/python3/dist-packages/matplotlib/artist.py:72, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
69 if artist.get_agg_filter() is not None:
70 renderer.start_filter()
---> 72 return draw(artist, renderer)
73 finally:
74 if artist.get_agg_filter() is not None:
File /usr/lib/python3/dist-packages/cartopy/mpl/feature_artist.py:185, in FeatureArtist.draw(self, renderer)
180 geoms = self._feature.geometries()
181 else:
182 # For efficiency on local maps with high resolution features (e.g
183 # from Natural Earth), only create paths for geometries that are
184 # in view.
--> 185 geoms = self._feature.intersecting_geometries(extent)
187 stylised_paths = {}
188 # Make an empty placeholder style dictionary for when styler is not
189 # used. Freeze it so that we can use it as a dict key. We will need
190 # to unfreeze all style dicts with dict(frozen) before passing to mpl.
File /usr/lib/python3/dist-packages/cartopy/feature/__init__.py:309, in NaturalEarthFeature.intersecting_geometries(self, extent)
302 """
303 Returns an iterator of shapely geometries that intersect with
304 the given extent.
305 The extent is assumed to be in the CRS of the feature.
306 If extent is None, the method returns all geometries for this dataset.
307 """
308 self.scaler.scale_from_extent(extent)
--> 309 return super().intersecting_geometries(extent)
File /usr/lib/python3/dist-packages/cartopy/feature/__init__.py:112, in Feature.intersecting_geometries(self, extent)
109 if extent is not None and not np.isnan(extent[0]):
110 extent_geom = sgeom.box(extent[0], extent[2],
111 extent[1], extent[3])
--> 112 return (geom for geom in self.geometries() if
113 geom is not None and extent_geom.intersects(geom))
114 else:
115 return self.geometries()
File /usr/lib/python3/dist-packages/cartopy/feature/__init__.py:291, in NaturalEarthFeature.geometries(self)
289 key = (self.name, self.category, self.scale)
290 if key not in _NATURAL_EARTH_GEOM_CACHE:
--> 291 path = shapereader.natural_earth(resolution=self.scale,
292 category=self.category,
293 name=self.name)
294 geometries = tuple(shapereader.Reader(path).geometries())
295 _NATURAL_EARTH_GEOM_CACHE[key] = geometries
File /usr/lib/python3/dist-packages/cartopy/io/shapereader.py:306, in natural_earth(resolution, category, name)
302 ne_downloader = Downloader.from_config(('shapefiles', 'natural_earth',
303 resolution, category, name))
304 format_dict = {'config': config, 'category': category,
305 'name': name, 'resolution': resolution}
--> 306 return ne_downloader.path(format_dict)
File /usr/lib/python3/dist-packages/cartopy/io/__init__.py:203, in Downloader.path(self, format_dict)
200 result_path = target_path
201 else:
202 # we need to download the file
--> 203 result_path = self.acquire_resource(target_path, format_dict)
205 return result_path
File /usr/lib/python3/dist-packages/cartopy/io/shapereader.py:355, in NEShpDownloader.acquire_resource(self, target_path, format_dict)
352 from zipfile import ZipFile
354 target_dir = Path(target_path).parent
--> 355 target_dir.mkdir(parents=True, exist_ok=True)
357 url = self.url(format_dict)
359 shapefile_online = self._urlopen(url)
File /usr/lib/python3.12/pathlib.py:1317, in Path.mkdir(self, mode, parents, exist_ok)
1315 if not parents or self.parent == self:
1316 raise
-> 1317 self.parent.mkdir(parents=True, exist_ok=True)
1318 self.mkdir(mode, parents=False, exist_ok=exist_ok)
1319 except OSError:
1320 # Cannot rely on checking for EEXIST, since the operating system
1321 # could give priority to other errors like EACCES or EROFS
File /usr/lib/python3.12/pathlib.py:1317, in Path.mkdir(self, mode, parents, exist_ok)
1315 if not parents or self.parent == self:
1316 raise
-> 1317 self.parent.mkdir(parents=True, exist_ok=True)
1318 self.mkdir(mode, parents=False, exist_ok=exist_ok)
1319 except OSError:
1320 # Cannot rely on checking for EEXIST, since the operating system
1321 # could give priority to other errors like EACCES or EROFS
[... skipping similar frames: Path.mkdir at line 1317 (3 times)]
File /usr/lib/python3.12/pathlib.py:1317, in Path.mkdir(self, mode, parents, exist_ok)
1315 if not parents or self.parent == self:
1316 raise
-> 1317 self.parent.mkdir(parents=True, exist_ok=True)
1318 self.mkdir(mode, parents=False, exist_ok=exist_ok)
1319 except OSError:
1320 # Cannot rely on checking for EEXIST, since the operating system
1321 # could give priority to other errors like EACCES or EROFS
File /usr/lib/python3.12/pathlib.py:1313, in Path.mkdir(self, mode, parents, exist_ok)
1309 """
1310 Create a new directory at this given path.
1311 """
1312 try:
-> 1313 os.mkdir(self, mode)
1314 except FileNotFoundError:
1315 if not parents or self.parent == self:
PermissionError: [Errno 13] Permission denied: '/sbuild-nonexistent'
<Figure size 1000x1000 with 1 Axes>
Finally, we can also pull out a time series for a given location easily:
[5]:
ds.t2m.sel(longitude=0, latitude=51.5).plot()
plt.title("ERA5 - London 2m temperature March 2019")
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Cell In[5], line 1
----> 1 ds.t2m.sel(longitude=0, latitude=51.5).plot()
2 plt.title("ERA5 - London 2m temperature March 2019")
NameError: name 'ds' is not defined