### 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