### Build documentation
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/development.rst
Install documentation dependencies and generate the HTML documentation locally.
```shell
cd docs
pip install -r requirements.txt
make html
```
--------------------------------
### Install dependencies and pre-commit hooks
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/development.rst
Install the package in editable mode and initialize pre-commit hooks for quality control.
```shell
pip install -e .
pre-commit install
```
--------------------------------
### Initialize environment and imports
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/examples/grid-types/_thumbnails.ipynb
Setup necessary imports and define the directory for saving thumbnail images.
```python
from pathlib import Path
import cartopy.crs as ccrs
import earthkit.data as ekd
from earthkit.geo import regrid
import earthkit.plots as ekp
THUMBNAILS_DIR = Path("../../../_static/thumbnails/")
```
--------------------------------
### Initialize Data and Environment
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/examples/introduction/_thumbnails.ipynb
Sets up the environment and loads sample GRIB data for use in subsequent plotting examples.
```python
from pathlib import Path
import earthkit.data as ekd
import earthkit.plots as ekp
THUMBNAILS_DIR = Path("../../../_static/thumbnails/")
data = ekd.from_source("sample", "era5-2t-msl-1985122512.grib").to_fieldlist()
pressure = data.sel({"parameter.variable": "msl"})
temperature = data.sel({"parameter.variable": "2t"})
```
--------------------------------
### Load sample datasets
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/examples/introduction/03-api-layers.ipynb
Initializes sample data from GRIB and NetCDF sources for use in plotting examples.
```python
import earthkit.data as ekd
import earthkit.plots as ekp
# ERA5 monthly averaged 2-metre temperature for December 1993
era5_2t = ekd.from_source("sample", "era5-monthly-mean-2t-199312.grib")
# An ECMWF HRES forecast containing mean sea-level pressure and wind gusts
joachim = ekd.from_source(
"url",
"https://get.ecmwf.int/repository/test-data/metview/gallery/fc_msl_wg_joachim.grib",
).to_fieldlist()
# An ERA5 hourly 2m-temperature time series at a point location
era5_reading_timeseries = ekd.from_source("sample", "era5-reading-timeseries.nc").to_xarray()
```
--------------------------------
### Initialize Data and Environment
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/examples/resampling/_thumbnails.ipynb
Setup imports, define the output directory, and load sample ERA5 GRIB data for resampling tasks.
```python
from pathlib import Path
import earthkit.data as ekd
import numpy as np
from earthkit.geo import regrid
from earthkit.plots.resample import Bilinear, NearestNeighbour, Regrid
THUMBNAILS_DIR = Path("../../../_static/thumbnails/")
data = ekd.from_source("sample", "era5-2t-msl-1985122512.grib").to_fieldlist()
pressure = data.sel({"parameter.variable": "msl"})
temperature = data.sel({"parameter.variable": "2t"})
```
--------------------------------
### Create a complete plot
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/examples/introduction/01-introduction.ipynb
A full example demonstrating map initialization, data plotting, decorations, and display.
```python
chart = ekp.Map(domain="Europe")
chart.contourf(era5_2t, units="celsius", style="auto")
chart.title("ERA5 monthly averaged {variable_name} over {domain} - {time:%B %Y}")
chart.coastlines()
chart.borders()
chart.gridlines()
chart.legend(label="{variable_name} ({units})")
chart.show()
```
--------------------------------
### Load sample data
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/examples/grid-types/_thumbnails.ipynb
Load a sample GRIB2 file to be used for regridding examples.
```python
source = hp = ekd.from_source("sample", "H8_nested_t2.grib2")
```
--------------------------------
### Importing earthkit-plots
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/gallery/gridded-data/unstructured-grids.ipynb
Initial setup for the earthkit-plots library.
```python
import numpy as np
import earthkit.plots as ekp
```
--------------------------------
### Importing earthkit libraries
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/examples/introduction/02-input-output-formats.ipynb
Initial setup required to access data loading and plotting functionality.
```python
import earthkit.data as ekd
import earthkit.plots as ekp
```
--------------------------------
### Install earthkit-plots via pip
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/README.md
Use this command to install the library from the Python Package Index.
```bash
pip install earthkit-plots
```
--------------------------------
### Mixing Functional and OO APIs
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/examples/introduction/03-api-layers.ipynb
Combine functional shortcuts for quick setup with the OO API for detailed refinement.
```python
# Start with the functional API — one line, sensible defaults
chart = ekp.geo.contourf(era5_2t, domain="Europe", units="celsius", title=False, coastlines=False)
# Refine with the OO API — plain statements, full control
chart.coastlines(color="grey", linewidth=0.5)
chart.title("ERA5 temperature — December 1993", fontsize=14)
chart.show()
```
--------------------------------
### Initialize data for plotting
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/examples/introduction/07-domains.ipynb
Load sample ERA5 data using earthkit-data to be used in subsequent plotting examples.
```python
import earthkit.data as ekd
import earthkit.plots as ekp
data = ekd.from_source("sample", "era5-monthly-mean-2t-199312.grib")
```
--------------------------------
### Comparing data source formats
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/examples/source-types/source-numpy.ipynb
Demonstrates the consistency of plotting calls across different data sources, noting the extra setup required for numpy arrays.
```python
# numpy (extra setup required)
lats, lons = fl.geography.latlons()
data = nc.to_numpy().squeeze()
metadata = {"units": "K", "long_name": "2 metre temperature", ...}
# GRIB, netCDF, xarray — no extra setup
data = ekd.from_source("sample", "era5-monthly-mean-2t-199312.grib")
# In every case, the plot call is the same:
chart = ekp.Map(domain="Europe")
chart.plot(data, units="celsius") # (pass x=, y=, metadata= for numpy)
```
--------------------------------
### Check earthkit-plots installation path
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/examples/test-unstructured.ipynb
Verifies the location of the installed earthkit-plots package.
```python
earthkit.plots.__file__
```
--------------------------------
### Initialize Data Sources
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/examples/introduction/04-layouts.ipynb
Load sample GRIB data for temperature, pressure, and wind fields using earthkit-data.
```python
import earthkit.data as ekd
import earthkit.plots as ekp
# ERA5 monthly averaged 2-metre temperature for December 1993
era5_2t = ekd.from_source("sample", "era5-monthly-mean-2t-199312.grib")
# An ECMWF HRES forecast containing mean sea-level pressure and wind gusts
joachim = ekd.from_source(
"url",
"https://get.ecmwf.int/repository/test-data/metview/gallery/fc_msl_wg_joachim.grib",
).to_fieldlist()
# Storm Ophelia 850 hPa wind U and V components
wind = ekd.from_source("sample", "storm_ophelia_wind_850.grib").to_fieldlist()
wind.ls()
```
--------------------------------
### Initialize Data and Environment
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/examples/contourf/_thumbnails.ipynb
Sets up the environment and loads sample ERA5 data for plotting.
```python
from pathlib import Path
import earthkit.data as ekd
import earthkit.plots as ekp
THUMBNAILS_DIR = Path("../../../_static/thumbnails/")
data = ekd.from_source("sample", "era5-2t-msl-1985122512.grib").to_fieldlist()
pressure = data.sel({"parameter.variable": "msl"})
```
--------------------------------
### Load sample data
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/examples/resampling/resampling-bilinear.ipynb
Initialize the earthkit data source and inspect the available fields.
```python
import earthkit.data as ekd
import earthkit.plots as ekp
data = ekd.from_source("sample", "test.grib").to_fieldlist()
data.ls()
```
--------------------------------
### Generate Introduction Thumbnail
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/examples/introduction/_thumbnails.ipynb
Creates a map visualization with contour and contourf layers, then saves it as a thumbnail.
```python
chart = ekp.Map(domain=["France", "Spain"], figsize=(2, 2))
chart.contourf(temperature, units="celsius", style="auto")
chart.contour(pressure, units="hPa", style="auto", linewidths=[0.4, 0.8])
chart.coastlines()
cbar = chart.legend(label="")
chart.title(fontsize=8, color="grey")
for t in cbar[0].ax.get_xticklabels():
t.set_fontsize(8)
t.set_color("grey")
chart.save(THUMBNAILS_DIR / "01-introduction.png", transparent=True)
```
--------------------------------
### Loading a GRIB file
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/examples/source-types/source-grib.ipynb
Fetch a GRIB sample and convert it to a fieldlist for processing.
```python
grib = ekd.from_source("sample", "era5-monthly-mean-2t-199312.grib").to_fieldlist()
grib
```
--------------------------------
### Define date range for forecast
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/examples/interactive-bar-plot.ipynb
Sets the start and end dates for the weather data request relative to the current time.
```python
from datetime import datetime, timedelta
today = datetime.now() + timedelta(days=-3)
tomorrow = today + timedelta(days=5)
today_str = today.strftime("%Y-%m-%d")
tomorrow_str = tomorrow.strftime("%Y-%m-%d")
```
--------------------------------
### Load sample data
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/examples/string-formatting-units.ipynb
Initialize the earthkit environment and load sample GRIB data for plotting.
```python
import earthkit.plots as ekp
import earthkit.data as ekd
data = ekd.from_source("sample", "storm_ophelia_wind_850.grib")
data.ls()
```
--------------------------------
### Import earthkit libraries
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/gallery/time-series/timeseries.ipynb
Initialize the environment by importing the necessary earthkit modules.
```python
import earthkit.plots as ekp
import earthkit.data as ekd
```
--------------------------------
### Apply unit formatting styles
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/examples/string-formatting-units.ipynb
Demonstrate various unit formatting options including default, exponential, fractional, stacked, and raw formats.
```python
plot_with_legend_label()
```
```python
plot_with_legend_label("{variable_name} ({units:~E})")
```
```python
plot_with_legend_label("{variable_name} ({units:~F})")
```
```python
plot_with_legend_label("{variable_name} ({units:~L})")
```
```python
plot_with_legend_label("{variable_name} ({units:L})")
```
```python
plot_with_legend_label("{variable_name} ({units:R})")
```
```python
plot_with_legend_label("{variable_name} ({units:L})", units="km h-1")
```
--------------------------------
### Create a complete map visualization
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/examples/introduction/01-introduction.ipynb
Demonstrates the full workflow from data loading to rendering a map with contours, decorations, and legends.
```python
# Import earthkit-data for accessing sample datasets
import earthkit.data as ekd
# Import earthkit-plots to visualise them
import earthkit.plots as ekp
# Download some sample data - ERA5 monthly averaged temperature
era5_2t = ekd.from_source("sample", "era5-monthly-mean-2t-199312.grib")
# Create a map showing a sub-domain over Europe
chart = ekp.Map(domain="Europe")
# Do a filled contour plot, with units converted to celsius and an automatic style
chart.contourf(era5_2t, units="celsius", style="auto")
# Add a title with metadata formatting
chart.title("ERA5 monthly averaged {variable_name} over {domain} - {time:%B %Y}")
# Add map decorations
chart.coastlines()
chart.borders()
chart.gridlines()
# Add a legend
chart.legend(label="{variable_name} ({units})")
chart.show()
```
--------------------------------
### Importing required libraries
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/examples/time-series/timeseries-climate-stripes.ipynb
Initializes the environment with earthkit packages and configures xarray to preserve CF metadata.
```python
import earthkit.data as ekd
import earthkit.plots as ekp
import earthkit.transforms as ekt
import xarray as xr
xr.set_options(keep_attrs=True)
```
--------------------------------
### Initialize data for contour plotting
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/examples/contour/contour-linestyles.ipynb
Load sample GRIB data and filter for pressure and temperature fields.
```python
import earthkit.data as ekd
import earthkit.plots as ekp
data = ekd.from_source("sample", "era5-2t-msl-1985122512.grib").to_fieldlist()
pressure = data.sel({"parameter.variable": "msl"})
temperature = data.sel({"parameter.variable": "2t"})
```
--------------------------------
### Load sample data
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/examples/introduction/01-introduction.ipynb
Accessing a remote GRIB file using earthkit-data.
```python
# Download some sample data - ERA5 monthly averaged temperature
era5_2t = ekd.from_source("sample", "era5-monthly-mean-2t-199312.grib")
```
--------------------------------
### Initialize earthkit environment and styles
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/examples/unstructured-data.ipynb
Imports necessary packages and defines a global style configuration for consistent plotting.
```python
import earthkit.data
import earthkit.plots
LEVELS = [i for i in range(390, 431, 4)]
STYLE = earthkit.plots.styles.Style(
levels=LEVELS,
extend="both",
colors="Spectral_r",
)
```
```python
earthkit.plots.__file__
```
--------------------------------
### Load GRIB data with earthkit-data
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/gallery/gridded-data/true-color-satellite.ipynb
Initializes the data source and lists the available fields in the GRIB file.
```python
import earthkit.data as ekd
data = ekd.from_source("sample", "rgb-sample.grib").to_fieldlist()
data.ls()
```
--------------------------------
### Initialize map canvas
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/examples/introduction/01-introduction.ipynb
Creating a map object with a predefined domain.
```python
# Create a map showing a sub-domain over Europe
chart = ekp.Map(domain="Europe")
```
--------------------------------
### Initialize plotting environment
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/examples/test-unstructured.ipynb
Imports necessary packages and defines a reusable Style object for consistent visualization.
```python
import earthkit.data
import earthkit.plots
LEVELS = [i for i in range(390, 431, 4)]
STYLE = earthkit.plots.styles.Style(
levels=LEVELS,
extend="both",
colors="Spectral_r",
)
```
--------------------------------
### Loading data as a fieldlist
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/examples/Untitled.ipynb
Load a GRIB file as a fieldlist and display its contents.
```python
test = ekd.from_source("sample", "extreme_2t_fc.grib").to_fieldlist()
```
```python
test.ls()
```
--------------------------------
### Load ERA5 temperature data
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/examples/introduction/05-styles.ipynb
Initialise the environment and load sample GRIB data for plotting.
```python
import earthkit.data as ekd
import earthkit.plots as ekp
temperature, pressure = ekd.from_source("sample", "era5-2t-msl-1985122512.grib").to_fieldlist()
```
--------------------------------
### Create and activate conda environment
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/development.rst
Optional steps for setting up a dedicated conda environment for development.
```shell
conda create -n earthkit-plots python=3.12
conda activate earthkit-plots
```
--------------------------------
### Load sample data
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/examples/plotting-and-styling-isolines.ipynb
Imports necessary modules and loads ERA5 mean sea level pressure data.
```python
import earthkit.plots as ekp
import earthkit.data as ekd
temperature, pressure = ekd.from_source("sample", "era5-2t-msl-1985122512.grib")
pressure.ls()
```
--------------------------------
### Load sample forecast data
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/examples/string-formatting-time.ipynb
Retrieves sample GRIB data from a URL to demonstrate time-based plotting.
```python
import earthkit.plots as ekp
import earthkit.data as ekd
data = ekd.from_source(
"url",
"https://get.ecmwf.int/repository/test-data/metview/gallery/fc_msl_wg_joachim.grib",
)
data.ls()
```
--------------------------------
### Inspecting GRIB contents
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/examples/source-types/source-grib.ipynb
Use the ls() method to display a summary of fields within the GRIB file.
```python
grib.ls()
```
--------------------------------
### Load sample data
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/examples/introduction/08-unit-conversion.ipynb
Load ERA5 monthly mean temperature data from the sample source.
```python
era5_2t = ekd.from_source("sample", "era5-monthly-mean-2t-199312.grib")
```
--------------------------------
### Demonstrating format agnosticism
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/examples/source-types/source-grib.ipynb
Compare how different data sources are loaded while maintaining identical plotting syntax.
```python
# GRIB
data = ekd.from_source("sample", "era5-monthly-mean-2t-199312.grib")
# netCDF
data = ekd.from_source("sample", "era5-monthly-mean-2t-199312.nc")
# xarray
data = ekd.from_source("sample", "era5-monthly-mean-2t-199312.nc").to_xarray()
# In every case, the plot call is identical:
chart = ekp.Map(domain="Europe")
chart.plot(data, units="celsius")
```
--------------------------------
### Domain Selection and Preview Logic
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/domains-gallery.rst
Functions to populate domain dropdowns, swap map images based on selection, and copy generated Python code to the clipboard.
```javascript
{name: "Africa", slug: "africa"},
{name: "Antarctic", slug: "antarctic"},
{name: "Arctic", slug: "arctic"},
{name: "Asia", slug: "asia"},
{name: "Central Europe", slug: "central_europe"},
{name: "Contiguous United States", slug: "contiguous_united_states"},
{name: "Europe", slug: "europe"},
{name: "Global", slug: "global"},
{name: "Mediterranean", slug: "mediterranean"},
{name: "North America", slug: "north_america"},
{name: "North Atlantic", slug: "north_atlantic"},
{name: "Northeast Europe", slug: "northeast_europe"},
{name: "Northwest Europe", slug: "northwest_europe"},
{name: "Oceania", slug: "oceania"},
{name: "South America", slug: "south_america"},
{name: "Southeast Europe", slug: "southeast_europe"},
{name: "Southwest Europe", slug: "southwest_europe"},
{name: "Svalbard", slug: "svalbard"}
]
};
function ekPopulate(category) {
var sel = document.getElementById('ek-domain-select');
sel.innerHTML = '';
EK_LISTS[category].forEach(function(item) {
var opt = document.createElement('option');
opt.value = item.name;
opt.dataset.slug = item.slug;
opt.textContent = item.name;
sel.appendChild(opt);
});
}
function ekDomainSwap(sel) {
if (!sel || !sel.options.length) return;
var slug = sel.options[sel.selectedIndex].dataset.slug;
var name = sel.value;
var img = document.getElementById('ek-domain-img');
var err = document.getElementById('ek-domain-error');
var code = document.getElementById('ek-domain-code');
img.src = EK_DOMAIN_BASE + slug + '.png';
img.alt = name;
err.style.display = 'none';
img.onerror = function() {
err.textContent = 'Map preview unavailable for: ' + name;
err.style.display = '';
};
var s = '';
var e = '';
var q = '=';
var esc = name.replace(/&/g,'&').replace(//g,'>').replace(/"/g,'"');
code.innerHTML = 'import earthkit.plots as ekp\n\nchart ' + q + ' ekp.Map(domain' + q + s + '"' + esc + '"' + e + ')\nchart.standard_layers()\nchart.title(' + s + '"{domain} | {crs}"' + e + ')\nchart.show()';
}
function ekCopyCode() {
var text = document.getElementById('ek-domain-code').textContent;
navigator.clipboard.writeText(text).then(function() {
var btn = document.getElementById('ek-domain-copy');
btn.src = '_static/check.svg';
btn.alt = 'Copied';
setTimeout(function() { btn.src = '_static/copy.svg'; btn.alt = 'Copy'; }, 1500);
});
}
function ekCatSwap(catSel) {
ekPopulate(catSel.value);
ekDomainSwap(document.getElementById('ek-domain-select'));
}
// Initialise on page load.
(function() {
ekPopulate('countries');
ekDomainSwap(document.getElementById('ek-domain-select'));
})();
```
--------------------------------
### Fetching satellite data
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/examples/misc/rgb-composite.ipynb
Retrieving a fieldlist from a sample GRIB file.
```python
data = ekd.from_source("sample", "rgb-sample.grib").to_fieldlist()
```
--------------------------------
### Load and Inspect Weather Data
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/gallery/gridded-data/weather-forecast-steps.ipynb
Initializes the data source from a URL and displays the fieldlist structure.
```python
import earthkit.data as ekd
import earthkit.plots as ekp
import matplotlib.pyplot as plt
data = ekd.from_source(
"url",
"https://get.ecmwf.int/repository/test-data/metview/gallery/fc_msl_wg_joachim.grib",
).to_fieldlist()
data.ls()
```
--------------------------------
### Load sample wind data
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/examples/plotting-and-styling-vector-data.ipynb
Initializes the earthkit-plots and data modules to load GRIB data for Storm Ophelia.
```python
import earthkit.plots as ekp
import earthkit.data as ekd
data = ekd.from_source("sample", "storm_ophelia_wind_850.grib")
data.ls()
```
```python
data.sel(short_name="v").ls()
```
--------------------------------
### Download Blue Marble Image
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/gallery/ancillary/blue-marble.ipynb
Uses wget to fetch the source image file from NASA's Earth Observatory.
```bash
!wget -O blue-marble.jpg https://eoimages.gsfc.nasa.gov/images/imagerecords/74000/74167/world.200410.3x5400x2700.jpg
```
--------------------------------
### Load GRIB dataset
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/examples/introduction/03-formats.ipynb
Load a sample ERA5 GRIB file using earthkit-data.
```python
import earthkit.data as ekd
era5_2t_grib = ekd.from_source("sample", "era5-monthly-mean-2t-199312.grib")
```
--------------------------------
### Loading data as a fieldlist
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/gallery/domains/domain-and-crs-from-data.ipynb
Load a sample NetCDF file and display its contents as a fieldlist.
```python
data = ekd.from_source("sample", "efas.nc").to_fieldlist()
data.ls()
```
--------------------------------
### Load GRIB forecast data
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/examples/contour/contour-spaghetti.ipynb
Initializes the data sources for high-resolution and ensemble forecasts from the earthkit sample archive.
```python
import earthkit.data as ekd
import earthkit.plots as ekp
ds_fc = ekd.from_source("sample", "fc_storm_st_jude.grib") # hi-res forecast
ds_en = ekd.from_source("sample", "ens_storm_st_jude.grib") # ensemble forecast
```
--------------------------------
### Run unit and image tests
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/development.rst
Commands to execute the core test suite, image-based regression tests, or generate new baseline images.
```shell
make unit-tests
```
```shell
make image-tests
```
```shell
make generate-test-images
```
--------------------------------
### Create a basic quiver plot
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/gallery/vector-data/basic-quiver.ipynb
Initializes a map domain and overlays wind data from a GRIB file using the quiver method.
```python
import earthkit.data as ekd
import earthkit.plots as ekp
data = ekd.from_source("sample", "storm_ophelia_wind_850.grib")
chart = ekp.Map(domain=[-20, 5, 40, 60])
chart.quiver(data)
chart.coastlines()
chart.land()
chart.gridlines()
chart.show()
```
--------------------------------
### Importing required libraries
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/examples/time-series/timeseries-global-temperature.ipynb
Initial imports for data handling and plotting.
```python
import earthkit.data as ekd
import pandas as pd
import earthkit.plots as ekp
```
--------------------------------
### Load ERA5 data
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/examples/grid-types/grid-types-regular-ll.ipynb
Initializes the data source and extracts the temperature field from a GRIB file.
```python
import earthkit.data as ekd
import earthkit.plots as ekp
data = ekd.from_source("sample", "era5-2t-msl-1985122512.grib").to_fieldlist()
temperature = data[0]
```
--------------------------------
### Handling missing metadata for regridding
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/examples/resampling/regridding.ipynb
Demonstrates how to manually define grid information for regridding when the dataset metadata is incomplete.
```python
data = ekd.from_source("sample", "healpix-h128-ring-2t.grib")
ds = data.to_xarray()
ds.t.attrs.pop("_earthkit")
ds
```
```python
from earthkit.plots.resample import Regrid
chart = ekp.Map(domain=["France", "Spain"])
chart.contourf(ds, resample=Regrid(in_grid={"grid": "H128", "order": "ring"}))
chart.legend()
chart.coastlines()
chart.borders()
chart.show()
```
--------------------------------
### Render the chart
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/examples/interactive-windrose-plot.ipynb
Displays the final configured chart as a PNG image.
```python
chart.show(renderer="png", width=2000, height=400)
```
--------------------------------
### Plotting xarray dataset with earthkit-plots
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/examples/Untitled.ipynb
Load a GRIB file as an xarray dataset and visualize a specific member using quickplot.
```python
import earthkit.data as ekd
import earthkit.plots as ekp
ds_fc = ekd.from_source("sample", "extreme_2t_fc.grib").to_xarray()
ekp.quickplot(ds_fc["2t"].isel(member=1))
```
--------------------------------
### Plotting temperature and pressure fields
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/gallery/gridded-data/temperature-and-pressure.ipynb
Unpacks a GRIB file into temperature and pressure fields and plots them on a map with automatic styling.
```python
import earthkit.data as ekd
import earthkit.plots as ekp
temperature, pressure = ekd.from_source("sample", "era5-2t-msl-1985122512.grib").to_fieldlist()
chart = ekp.Map(domain="Europe")
chart.plot(temperature, units="celsius")
chart.plot(pressure, units="hPa")
chart.legend(location="right")
chart.coastlines()
chart.title()
chart.gridlines()
chart.show()
```
--------------------------------
### Loading data as an xarray dataset
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/gallery/domains/domain-and-crs-from-data.ipynb
Load a sample NetCDF file and convert it into an xarray Dataset.
```python
ds = ekd.from_source("sample", "efas.nc").to_xarray()
ds
```
--------------------------------
### Generate Point Cloud Thumbnail
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/examples/points-and-cells/_thumbnails.ipynb
Renders a point cloud visualization and saves it as a transparent PNG.
```python
chart = ekp.Map(domain="Spain", figsize=(2, 2))
chart.point_cloud(data, s=10, style=style)
chart.ax.set_frame_on(False)
chart.save(THUMBNAILS_DIR / "point-cloud.png", transparent=True)
```
--------------------------------
### Overlaying pressure isobars on filled temperature
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/examples/contourf/contourf-contour-overlay.ipynb
Creates a synoptic chart by layering filled temperature contours with black pressure isobars.
```python
t2m_style = ekp.styles.Style(
units="celsius",
colors="RdYlBu_r",
levels={"step": 4, "reference": 0},
)
msl_style = ekp.styles.Contour(
units="hPa",
levels={"step": 4, "reference": 1000},
colors="black",
linewidths=[0.6, 0.6, 0.6, 0.6, 1.2],
labels=True,
)
chart = ekp.Map(domain="Europe")
chart.contourf(temperature, style=t2m_style)
chart.contour(pressure, style=msl_style)
chart.legend()
chart.land()
chart.borders()
chart.coastlines()
chart.title()
chart.show()
```
--------------------------------
### Generate Unstructured Sample Data
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/examples/resampling/_thumbnails.ipynb
Create random point cloud data for testing resampling visualizations.
```python
import earthkit.plots
# Example data (unstructured points)
points = np.random.rand(60, 2) * 10 # 500 random points
values = np.sin(points[:, 0]) + np.cos(points[:, 1]) # Some sample data
x = points[:, 0]
y = points[:, 1]
```
--------------------------------
### Applying reusable styles and metadata
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/examples/misc/choropleth.ipynb
Control color levels, colormaps, and metadata for units and labels using Style objects and dictionaries.
```python
style = ekp.styles.Style(
levels=range(-10, 11),
cmap="RdBu_r",
units="celsius",
)
ekp.geo.choropleth(
nuts_mean_2t,
domain="Europe",
z="2t",
labels="{2t:.1f}{units}",
metadata={"units": "K", "long_name": "2m temperature"},
style=style,
).show()
```
--------------------------------
### Comparing point_cloud and grid_cells
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/examples/points-and-cells/point-cloud.ipynb
Demonstrates the visual difference between rendering cell centroids as points versus shading the full area of grid cells.
```python
figure = ekp.Figure(rows=1, columns=2, domain=["France", "Spain"])
ax = figure.add_map()
ax.point_cloud(data, style=style, s=10)
ax.title("point_cloud")
ax = figure.add_map()
ax.grid_cells(data, style=style)
ax.title("grid_cells")
figure.coastlines()
figure.borders()
figure.legend(location="right")
figure.show()
```
--------------------------------
### Prepare Numpy Data
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/gallery/gridded-data/numpy-arrays.ipynb
Initialize random data and coordinate arrays for plotting.
```python
import numpy as np
import earthkit.plots
data = np.random.rand(15, 30)
y = np.linspace(-90, 90, 15)
x = np.linspace(-180, 180, 30)
```
--------------------------------
### Load ORCA grid data
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/examples/grid-types/grid-types-orca.ipynb
Initializes the data source for the ORCA grid sea surface temperature field.
```python
import earthkit.data as ekd
import earthkit.plots as ekp
data = ekd.from_source("sample", "orca.grib")
```
--------------------------------
### Visualizing individual channels and composite
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/examples/misc/rgb-composite.ipynb
Creating a multi-panel figure to display individual color channels alongside the final RGB composite.
```python
import cartopy.crs as ccrs
COLORS = {
"red": (1, 0, 0),
"green": (0, 1, 0),
"blue": (0, 0, 1),
}
figure = ekp.Figure(crs=ccrs.NearsidePerspective(), rows=2, columns=2)
for i, color in enumerate(COLORS):
channel_plot = figure.add_map()
channel_plot.grid_cells(data[i], colors=["black", COLORS[color]])
channel_plot.title(f"{color} channel")
composite = figure.add_map()
composite.rgb_composite(data)
composite.title("RGB composite")
figure.title("RGB composite image at {time:%H:%M on %-d %B %Y}")
figure.show()
```
--------------------------------
### Generating sample unstructured data
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/gallery/gridded-data/unstructured-grids.ipynb
Creates random points and associated values for demonstration.
```python
# Example data (unstructured points)
points = np.random.rand(500, 2) * 10 # 500 random points
values = np.sin(points[:, 0]) + np.cos(points[:, 1]) # Some sample data
x = points[:, 0]
y = points[:, 1]
```
--------------------------------
### Generate Input/Output Formats Thumbnail
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/examples/introduction/_thumbnails.ipynb
Creates a multi-panel figure demonstrating support for various data formats.
```python
fig = ekp.Figure(rows=2, columns=2, figsize=(2, 2), domain=["France", "Spain"])
for i, fmt in enumerate(["GRIB", "netCDF", "xarray", "NumPy"]):
fig.add_map().contourf(temperature, units="celsius", style="auto").title(
fmt, fontsize=10, fontweight="bold", color="grey"
)
fig.coastlines()
# fig.show()
fig.save(THUMBNAILS_DIR / "02-input-output-formats.png", transparent=True)
```
--------------------------------
### Compare output resolutions
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/examples/resampling/resampling-regrid.ipynb
Shows how the resolution parameter affects the output grid spacing, with finer resolutions providing more detail at the cost of computation time.
```python
style = ekp.styles.Style(
levels=range(240, 310, 5),
colors="Spectral_r",
)
figure = ekp.Figure(rows=1, columns=2, domain="Europe")
ax = figure.add_map()
ax.pcolormesh(data, resample=Regrid(resolution=2.0), style=style)
ax.title("resolution=2.0°")
ax = figure.add_map()
ax.pcolormesh(data, resample=Regrid(resolution=0.25), style=style)
ax.title("resolution=0.25°")
figure.coastlines()
figure.legend()
figure.show()
```
--------------------------------
### Loading and plotting GRIB data
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/examples/introduction/02-input-output-formats.ipynb
Load GRIB data using earthkit-data and visualize it with a map chart.
```python
grib = ekd.from_source("sample", "era5-monthly-mean-2t-199312.grib")
grib
```
```python
chart = ekp.Map(domain="Europe")
chart.contourf(grib, units="celsius", style="auto")
chart.coastlines()
chart.legend(label="{variable_name} ({units})")
chart.title("{variable_name} – {time:%B %Y}")
chart.show()
```
--------------------------------
### Generate RGB Composite Thumbnail
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/examples/misc/_thumbnails.ipynb
Creates a map visualization using an RGB composite and saves it as a transparent PNG.
```python
chart = ekp.Map(
crs=ccrs.NearsidePerspective(central_longitude=10, central_latitude=10),
figsize=(2, 2),
)
chart.rgb_composite(data)
chart.save(THUMBNAILS_DIR / "rgb-composite.png", transparent=True)
```
--------------------------------
### Visualize Gridded Data with earthkit-plots
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/gallery/point-data/non-contiguous-gridded-data.ipynb
This snippet initializes a map, adds contour layers for temperature and pressure, and displays the final plot with standard map features.
```python
chart = ekp.Map(domain=countries)
chart.contourf(ds["2t"], units="celsius")
chart.contour(ds["msl"], units="hPa", style="auto")
chart.coastlines()
chart.borders()
chart.gridlines()
chart.legend()
chart.title()
chart.show()
```
--------------------------------
### Generate Domain Thumbnail
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/examples/introduction/_thumbnails.ipynb
Configures a map with a NearsidePerspective projection and custom gridlines for a specific domain view.
```python
import cartopy.crs as ccrs
chart = ekp.Map(
crs=ccrs.NearsidePerspective(central_latitude=52, central_longitude=10),
figsize=(2, 2),
)
chart.ocean(color="white")
chart.land(transform_first=False)
chart.coastlines(color="lightgrey")
chart.borders(linewidth=0.2, color="lightgrey")
chart.gridlines(draw_labels=False, ylim=70, xstep=10, ystep=10)
chart.gridlines(draw_labels=False, ylim=80, xstep=30, ystep=10)
chart.save(THUMBNAILS_DIR / "06-domains.png", transparent=True)
```
--------------------------------
### Load reduced Gaussian grid data
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/examples/grid-types/grid-types-reduced-gg.ipynb
Load an O32 reduced Gaussian grid GRIB file from a remote source.
```python
import earthkit.data as ekd
import earthkit.plots as ekp
data = ekd.from_source(
"url",
"https://get.ecmwf.int/repository/test-data/earthkit-regrid/test-data/global_0_360/O32.grib",
)
```
--------------------------------
### Visualize Resampling Methods
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/examples/resampling/_thumbnails.ipynb
Generate map visualizations comparing Bilinear and NearestNeighbour resampling for point cloud data.
```python
chart = earthkit.plots.Map(figsize=(2, 2))
chart.point_cloud(x=x, y=y, z=values)
chart.pcolormesh(x=x, y=y, z=values, style=style, resample=Bilinear())
chart.scatter(x=x, marker="X", y=y, edgecolors="black", z=values, c=values, style=style)
chart.ax.set_frame_on(False)
chart.ax.set_extent([2, 8, 2, 8])
chart.save(THUMBNAILS_DIR / "resampling-bilinear.png", transparent=True)
```
```python
chart = earthkit.plots.Map(figsize=(2, 2))
chart.point_cloud(x=x, y=y, z=values)
chart.pcolormesh(x=x, y=y, z=values, style=style, resample=NearestNeighbour())
chart.scatter(x=x, marker="X", y=y, edgecolors="black", z=values, c=values, style=style)
chart.ax.set_frame_on(False)
chart.ax.set_extent([2, 8, 2, 8])
chart.save(THUMBNAILS_DIR / "resampling-nearest-neighbour.png", transparent=True)
```
--------------------------------
### Loading and preparing CSV data
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/examples/time-series/timeseries-global-temperature.ipynb
Downloads the global temperature CSV from the C3S portal and loads it into a pandas DataFrame.
```python
C3S_RED = "#941333"
csv_file = "era5_daily_series_2t_global.csv"
data = ekd.from_source(
"url",
"https://sites.ecmwf.int/data/climatepulse/data/series/era5_daily_series_2t_global.csv",
)
data.to_target("file", csv_file)
df = pd.read_csv(csv_file, comment="#", index_col="date", parse_dates=True).round(2)
df.head()
```
--------------------------------
### Visualize El Niño data with subplots
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/gallery/gridded-data/el-nino.ipynb
Uses earthkit-data to load GRIB files and earthkit-plots to create a multi-row map visualization with custom styles and legends.
```python
import earthkit.data as ekd
import earthkit.plots as ekp
YEARS = {
1993: "Normal conditions",
1997: "El Niño",
1998: "La Niña",
}
DOMAIN = [100, 300, -20, 20]
# data = ekd.from_source(
# "cds",
# "reanalysis-era5-single-levels-monthly-means",
# {
# "product_type": "monthly_averaged_reanalysis",
# "variable": "sea_surface_temperature",
# "year": list(YEARS),
# "month": "12",
# "time": "00:00",
# "area": [20, 100, -20, -60],
# "grid": [0.25, 0.25],
# },
# ).to_fieldlist()
data = ekd.from_source("sample", "era5-el-nino.grib").to_fieldlist()
style = ekp.styles.Style(
colors="Spectral_r",
levels=range(15, 33),
units="celsius",
ticks=range(15, 33),
)
figure = ekp.Figure(rows=3, columns=1, figsize=(8, 7.5))
for i, year in enumerate(YEARS):
subplot = figure.add_map(domain=DOMAIN)
subplot.contourf(data[i], style=style)
subplot.title(f"{YEARS[year]} - ERA5 {short_name!u} monthly mean: {time:%B %Y}")
figure.land(color="#555", zorder=2)
figure.gridlines(xstep=20, ystep=10, sharex=True)
figure.title("{variable_name} in {time:%B} of {time:%Y}", fontsize=14)
figure.legend(label="{variable_name!l} ({units})")
figure.show()
```
--------------------------------
### Create and visualize a union of EU countries
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/gallery/domains/domain-union.ipynb
Uses a list of country names to define a union domain and applies it to an earthkit-plots Map object.
```python
import earthkit.plots as ekp
from earthkit.plots.geography import domains
EU_COUNTRIES = [
"Austria",
"Belgium",
"Bulgaria",
"Croatia",
"Cyprus",
"Czech Republic",
"Denmark",
"Estonia",
"Finland",
"France",
"Germany",
"Greece",
"Hungary",
"Ireland",
"Italy",
"Latvia",
"Lithuania",
"Luxembourg",
"Netherlands",
"Poland",
"Portugal",
"Romania",
"Slovakia",
"Slovenia",
"Spain",
"Sweden",
]
EU = domains.union(EU_COUNTRIES, name="European Union")
# domain=EU_COUNTRIES is also valid but would lose the name metadata
eu_map = ekp.Map(domain=EU)
eu_map.countries(edgecolor="white")
# We can reuse the same list of EU countries to show a subset of country polygons
eu_map.countries(include=EU_COUNTRIES, facecolor="cornflowerblue", edgecolor="white", labels=True)
eu_map.gridlines()
eu_map.title("{domain}")
# You can pass an earthkit-plots Style directly to the legend method
eu_map.legend(
ekp.styles.Categorical(
categories=["Non-EU countries", "EU countries"],
colors=["lightgrey", "cornflowerblue"],
)
)
eu_map.show()
```
--------------------------------
### Loading and plotting NetCDF data
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/examples/introduction/02-input-output-formats.ipynb
Load NetCDF data and visualize it using the same plotting interface as GRIB.
```python
nc = ekd.from_source("sample", "era5-monthly-mean-2t-199312.nc")
nc
```
```python
chart = ekp.Map(domain="Europe")
chart.contourf(nc, units="celsius", style="auto")
chart.coastlines()
chart.legend(label="{variable_name} ({units})")
chart.title("{variable_name} – {time:%B %Y}")
chart.show()
```
--------------------------------
### Configuring categorical style
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/examples/lccs.ipynb
Define levels and colors for the land cover classification categories.
```python
levels, colors = zip(*[
[0, "#000000"],
[10, "#ffff64"],
[20, "#aaf0f0"],
[30, "#dcf064"],
[40, "#c8c864"],
[50, "#006400"],
[60, "#00a000"],
[70, "#003c00"],
[80, "#285000"],
[90, "#788200"],
[100, "#8ca000"],
[110, "#be9600"],
[120, "#966400"],
[130, "#ffb432"],
[140, "#ffdcd2"],
[150, "#ffebaf"],
[160, "#00785a"],
[170, "#009678"],
[180, "#00dc82"],
[190, "#c31400"],
[200, "#fff5d7"],
[210, "#0046c8"],
[220, "#ffffff"],
])
style = ekp.styles.Categorical(
levels=levels,
colors=colors,
legend_style=None,
)
```
--------------------------------
### Create Basic Contourf Map
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/examples/contourf/_thumbnails.ipynb
Generates a basic contourf map with custom colors and saves it as a thumbnail.
```python
chart = ekp.Map(domain=[-18, -10.1, 45, 50], figsize=(2, 2))
chart.contourf(pressure, units="hPa", levels={"step": 4}, colors=colors)
chart.ax.set_frame_on(False)
chart.save(THUMBNAILS_DIR / "contourf-introduction.png", transparent=True)
```
--------------------------------
### Subsample Visualization
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/examples/resampling/_thumbnails.ipynb
Visualize subsampled data using pcolormesh and scatter plots.
```python
chart = earthkit.plots.Map(domain=[-18, -10.1, 45, 50], figsize=(2, 2))
chart.pcolormesh(t4, units="celsius", levels=np.arange(8.4, 12.4, 0.2), cmap="Reds")
chart.scatter(
t2,
marker="X",
edgecolors="black",
cmap="Reds",
units="celsius",
levels=np.arange(8.4, 12.4, 0.2),
)
# chart.legend()
chart.ax.set_frame_on(False)
chart.save(THUMBNAILS_DIR / "resampling-subsample.png", transparent=True)
```
--------------------------------
### Chaining map plotting methods
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/examples/introduction/01-introduction.ipynb
Demonstrates chaining multiple plotting methods to customize a map with specific domains, units, and overlays.
```python
(
ekp.geo
.plot(era5_2t, units="celsius", domain="Australia")
.administrative_areas(color="brown")
.gridlines(xstep=10, ystep=10)
.cities(adjust_labels=True)
)
```
--------------------------------
### Inspecting Functional API Results
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/examples/introduction/03-api-layers.ipynb
Demonstrates that functional shortcuts return the same underlying Map and Figure objects as the OO API.
```python
result = ekp.geo.plot(era5_2t, domain="Europe", units="celsius")
print(type(result)) # Map — single panels are unwrapped from the Figure automatically
print(type(result.figure)) # Figure
print(result.layers) # the Layer objects produced by the contourf call
```
--------------------------------
### Load NetCDF dataset
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/examples/introduction/03-formats.ipynb
Load a sample ERA5 NetCDF file using earthkit-data.
```python
era5_2t_nc = ekd.from_source("sample", "era5-monthly-mean-2t-199312.nc")
```
--------------------------------
### HEALPix data download progress
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/gallery/grid-types/healpix-point-cloud.ipynb
Displays the download progress output for the sample GRIB file.
```text
healpix-h128-nested-2t.grib: 0%| | 0.00/385k [00:00, ?B/s]
```
--------------------------------
### Plotting vector data with custom styles
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/gallery/vector-data/vector-styles.ipynb
Uses earthkit.data to load GRIB files and earthkit.plots to define map domains, vector styles, and annotations.
```python
import earthkit.data as ekd
import earthkit.plots as ekp
data = ekd.from_source("sample", "storm_ophelia_wind_850.grib")
chart = ekp.Map(domain=[-20, 5, 40, 60])
style = ekp.styles.Style(
colors="plasma_r",
levels=range(0, 22, 2),
units="m s-1",
)
chart.quiver(data, style=style)
chart.legend(label="wind speed ({units})", location="right")
chart.land()
chart.coastlines()
chart.gridlines()
chart.title("Storm Ophelia - {level} hPa wind speed and direction\n{time:%H:%M UTC on %-d %B %Y}")
chart.show()
```
--------------------------------
### GRIB file download progress
Source: https://github.com/ecmwf/earthkit-plots/blob/develop/docs/source/examples/gallery/gridded-data/temperature-and-pressure.ipynb
Displays the progress of the GRIB file download.
```text
Result:
era5-2t-msl-1985122512.grib: 0%| | 0.00/3.96M [00:00, ?B/s]
```