### Install and Install Pre-commit Hooks Source: https://github.com/ecmwf/earthkit/blob/develop/docs/development/setup.md Install the pre-commit package and then install the git hooks. These hooks run automated checks on commits to ensure code quality. ```shell pip install pre-commit pre-commit install ``` -------------------------------- ### Install Documentation Dependencies Source: https://github.com/ecmwf/earthkit/blob/develop/docs/development/docs.md Installs the necessary Python dependencies for building the documentation. Navigate to the 'docs' directory before running this command. ```shell cd docs pip install -r requirements.txt ``` -------------------------------- ### Install earthkit from PyPI Source: https://github.com/ecmwf/earthkit/blob/develop/README.md Use this command to install the earthkit library using pip. Ensure you have Python and pip installed. ```bash pip install earthkit ``` -------------------------------- ### Install earthkit Source: https://context7.com/ecmwf/earthkit/llms.txt Install the full earthkit suite from PyPI. Ensure you have earthkit version 1.0.0rc0 or later. ```bash pip install earthkit>=1.0.0rc0 ``` -------------------------------- ### Install earthkit with pip Source: https://github.com/ecmwf/earthkit/blob/develop/docs/getting-started.md Install earthkit using pip. This command installs version 1.0.0rc0 or later. ```bash python3 -m pip install earthkit>=1.0.0rc0 ``` -------------------------------- ### Build HTML Documentation Source: https://github.com/ecmwf/earthkit/blob/develop/docs/development/docs.md Builds the HTML version of the documentation. After installation, run this command from the 'docs' folder. The output can be found in 'docs/_build/html/index.html'. ```shell make html ``` -------------------------------- ### Install reverse-geocode Source: https://github.com/ecmwf/earthkit/blob/develop/docs/tutorials/time-series-solutions.ipynb Install the optional reverse-geocode package for location lookup functionality. ```python #!pip install reverse-geocode ``` -------------------------------- ### Install Earthkit in Editable Mode Source: https://github.com/ecmwf/earthkit/blob/develop/docs/development/setup.md Install the Earthkit package in editable mode from the root of the repository. This allows changes in the source code to be reflected immediately without reinstallation. ```shell pip install -e . ``` -------------------------------- ### Check EarthKit Package Versions Source: https://context7.com/ecmwf/earthkit/llms.txt Prints the installed version of various earthkit sub-packages. Useful for verifying installations and compatibility. ```python print(ekd.__version__) ``` ```python print(ekg.__version__) ``` ```python print(ekp.__version__) ``` ```python print(ekt.__version__) ``` ```python print(ekh.__version__) ``` ```python print(eku.__version__) ``` -------------------------------- ### Import earthkit Packages Source: https://github.com/ecmwf/earthkit/blob/develop/docs/tutorials/comparing-models-solutions.ipynb Import the necessary earthkit packages for data handling, transformations, and plotting. Ensure these packages are installed before running. ```python import earthkit.data as ekd import earthkit.transforms as ekt import earthkit.plots as ekp ``` -------------------------------- ### CuPy-based Upstream Summation (GPU) Source: https://github.com/ecmwf/earthkit/blob/develop/docs/tutorials/gpu_hydro.ipynb Perform the same upstream summation using cupy for GPU acceleration. Ensure cupy is installed and a CUDA-enabled GPU is available. ```python import cupy as cp net_gpu = ekh.river_network.load("efas", "5").to_device(device="cuda") array_cp = cp.array(da.values) %timeit ekh.upstream.array.sum(net_gpu, array_cp) ``` -------------------------------- ### Plotting Data as a Point Cloud with earthkit-plots Source: https://github.com/ecmwf/earthkit/blob/develop/docs/tutorials/polytope_polygon.ipynb Plots the retrieved xarray Dataset as a point cloud using earthkit-plots. This snippet requires the '2t' data variable from the dataset. Ensure earthkit-plots is installed. ```python import earthkit.plots as ekp chart = ekp.Map(domain="Portugal") chart.point_cloud(ds['2t']) chart.coastlines() chart.borders() chart.gridlines() chart.title("{variable_name} (number={number})") chart.legend() chart.show() ``` -------------------------------- ### Retrieve Country Polygon and Data with Polytope Source: https://github.com/ecmwf/earthkit/blob/develop/docs/tutorials/polytope_polygon.ipynb Generates a country polygon for Portugal using earthkit-geo, then retrieves data within that polygon using Polytope and converts it to an xarray Dataset. Ensure earthkit-data and earthkit-geo are installed. ```python import earthkit.data as ekd from earthkit.geo.cartography import country_polygons coords = country_polygons("Portugal") request = { "class": "od", "stream" : "enfo", "type" : "pf", "date" : -1, "time" : "1200", "levtype" : "sfc", "expver" : 1, "domain" : "g", "param" : "167/169", "number" : "1", "step": "0", "feature": { "type": "polygon", "shape": coords }, } ds = ekd.from_source("polytope", "ecmwf-mars", request, stream=False, address='polytope.ecmwf.int').to_xarray() ds ``` -------------------------------- ### Retrieve ERA5 Reference Data from CDS Source: https://github.com/ecmwf/earthkit/blob/develop/docs/tutorials/comparing-models-solutions.ipynb Fetch monthly averaged reanalysis data for 2m temperature from ERA5 for July between 1961 and 1991. This serves as the reference period for anomaly calculation. Requires a Copernicus Climate Data Store (CDS) account and API key setup. ```python era5_reference_data = ekd.from_source( "cds", "reanalysis-era5-single-levels-monthly-means", { "product_type": "monthly_averaged_reanalysis", "variable": "2m_temperature", "year": list(range(1961, 1991)), "month": "07", "time": "00:00", }, ) ``` -------------------------------- ### Import Earthkit Components and Verify Versions Source: https://context7.com/ecmwf/earthkit/llms.txt Demonstrates how to import individual earthkit components and access their version information via the `__version__` attribute. ```python import earthkit.data as ekd import earthkit.geo as ekg import earthkit.meteo as ekm import earthkit.plots as ekp import earthkit.transforms as ekt import earthkit.hydro as ekh import earthkit.utils as eku ``` -------------------------------- ### Load and List GRIB Data Source: https://github.com/ecmwf/earthkit/blob/develop/docs/tutorials/grid_solutions.ipynb Loads a GRIB file from a sample source and lists its contents to inspect available fields. ```python import earthkit.data as ekd ds = ekd.from_source("sample", "grids_3.grib").to_fieldlist() ds.ls() ``` -------------------------------- ### Run All Tests Source: https://github.com/ecmwf/earthkit/blob/develop/docs/development/tests.md Execute the entire test suite. This command is the default way to run tests. ```shell pytest ``` -------------------------------- ### Create and Activate Python Virtual Environment (venv) Source: https://github.com/ecmwf/earthkit/blob/develop/docs/development/setup.md Create a Python virtual environment named 'earthkit-dev' and activate it. This isolates project dependencies. ```shell cd YOUR_VENVS_DIR python -m venv earthkit-dev source earthkit-dev/bin/activate ``` -------------------------------- ### Load Sample ERA5 Data from URL Source: https://github.com/ecmwf/earthkit/blob/develop/docs/tutorials/time-series-solutions.ipynb Load a sample ERA5 dataset directly from a URL, useful for following along without a CDS account. ```python ``` -------------------------------- ### Access Field Values as 1D Array Source: https://github.com/ecmwf/earthkit/blob/develop/docs/tutorials/grid_solutions.ipynb Accesses the field's data as a 1D NumPy array using the `.values` property. This is a convenient way to get a flattened representation of the data. ```python f.values.shape ``` -------------------------------- ### Ingest data using earthkit.data.from_source Source: https://context7.com/ecmwf/earthkit/llms.txt The central entry point for data ingestion, supporting GRIB, NetCDF, Zarr, CDS, MARS, Polytope, URL, and sample datasets. Returns a format-agnostic data object. ```python import earthkit.data as ekd # --- GRIB from built-in sample --- ds = ekd.from_source("sample", "grids_3.grib").to_fieldlist() ds.ls() # parameter.variable geography.grid_type vertical.level ... # t regular_ll 1000 # t reduced_gg 1000 # t healpix 1000 ``` ```python # --- NetCDF from Copernicus Climate Data Store (CDS) --- ds_cds = ekd.from_source( "cds", "reanalysis-era5-single-levels-timeseries", { "variable": ["2m_temperature"], "location": {"longitude": -1, "latitude": 51.5}, "date": ["2025-06-01/2025-09-30"], "data_format": "netcdf", }, ) data = ds_cds.to_xarray() # xarray.Dataset with valid_time dimension ``` ```python # --- GRIB from CDS monthly means --- era5 = ekd.from_source( "cds", "reanalysis-era5-single-levels-monthly-means", { "product_type": "monthly_averaged_reanalysis", "variable": "2m_temperature", "year": 2024, "month": "07", "time": "00:00", }, ) ``` ```python # --- NetCDF from a direct URL --- HADCRUT5_URL = ( "https://www.metoffice.gov.uk/hadobs/hadcrut5/" "data/HadCRUT.5.0.2.0/analysis/HadCRUT.5.0.2.0.analysis.anomalies.ensemble_mean.nc" ) hadcrut5 = ekd.from_source("url", HADCRUT5_URL).to_xarray() ``` ```python # --- Ensemble forecast via Polytope --- request = { "class": "od", "stream": "enfo", "type": "pf", "date": -1, "time": "0000", "levtype": "sfc", "expver": 1, "domain": "g", "param": "164/167/169", "number": "1/to/50", "step": "0/to/360", "feature": {"type": "timeseries", "points": [[38.79, -9.11]], "axes": "step"}, } ds_poly = ekd.from_source( "polytope", "ecmwf-mars", request, stream=False, address="polytope.ecmwf.int" ).to_xarray() ``` -------------------------------- ### Convert Field to NumPy Array Source: https://github.com/ecmwf/earthkit/blob/develop/docs/tutorials/grid_solutions.ipynb Converts the field's data to a NumPy array. Use `flatten=True` to get a 1D array, otherwise, it respects the field's geographical shape. ```python f.to_numpy().shape, f.to_numpy(flatten=True).shape ``` -------------------------------- ### Get Field Geography Shape Source: https://github.com/ecmwf/earthkit/blob/develop/docs/tutorials/grid_solutions.ipynb Determines the shape of the field's geographical representation. This varies based on the grid type (e.g., 2D for regular lat/lon, 1D for reduced Gaussian grids). ```python f.geography.shape() ``` -------------------------------- ### Load GRIB data with earthkit.data Source: https://github.com/ecmwf/earthkit/blob/develop/docs/tutorials/meteo_solutions.ipynb Load GRIB data from a sample source and convert it into a fieldlist. This is the initial step for most meteorological data processing tasks. ```python import earthkit.data as ekd ds = ekd.from_source("sample", "tquv_pl_2x2.grib").to_fieldlist() ds.head(6) ``` -------------------------------- ### Access Field Data and Geography with earthkit.data Source: https://context7.com/ecmwf/earthkit/llms.txt Inspect metadata, access geographic information (shape, lat/lon), and retrieve numeric values as NumPy arrays. Values can be returned in their native 2D shape or flattened. Use `data()` to get flattened lat, lon, and values together. ```python import earthkit.data as ekd ds = ekd.from_source("sample", "grids_3.grib").to_fieldlist() f = ds.sel({"geography.grid_type": "regular_ll"})[0] # Metadata inspection f.get("parameter.variable") # 't' f.get("geography.grid_type") # 'regular_ll' # Geography: shape, lat/lon arrays f.geography.shape() # (37, 72) lat, lon = f.geography.latlons() lat.shape # (37, 72) lon.shape # (37, 72) # Values: shaped (respects 2D) or flat f.to_numpy().shape # (37, 72) f.to_numpy(flatten=True).shape # (2664,) f.values.shape # (2664,) — always 1D # Access lat, lon, values together lat_flat, lon_flat, vals = f.data(flatten=True) # Convert to Xarray (fieldlist-level) xr_ds = ds.to_xarray() xr_ds_with_dim = ds.to_xarray(ensure_dims="forecast_reference_time") ``` -------------------------------- ### Configure and Create a Plot with Earthkit-Plots Source: https://github.com/ecmwf/earthkit/blob/develop/docs/tutorials/gpu_hydro.ipynb Define plotting styles, create a map object, and add various map elements like data, legend, title, coastlines, and gridlines. Use `chart.show()` to display the plot. ```python style = ekp.styles.Style( colors="Blues", levels=[0, 0.5, 1, 2, 5, 10, 50, 100, 500, 1000, 2000, 3000, 4000], extend="max", ) chart = ekp.Map() chart.quickplot(upstream_sum, style=style) chart.legend(label="{variable_name}") chart.title("Upstream precipitation at {time:%H:%M on %-d %B %Y}") chart.coastlines() chart.gridlines() chart.show() ``` -------------------------------- ### Retrieve ERA5 2024 Data from CDS Source: https://github.com/ecmwf/earthkit/blob/develop/docs/tutorials/comparing-models-solutions.ipynb Fetch monthly averaged reanalysis data for 2m temperature from ERA5 for July 2024. This data will be used to calculate the anomaly against the reference period. Requires a Copernicus Climate Data Store (CDS) account and API key setup. ```python era5_2024_data = ekd.from_source( "cds", "reanalysis-era5-single-levels-monthly-means", { "product_type": "monthly_averaged_reanalysis", "variable": "2m_temperature", "year": 2024, "month": "07", "time": "00:00", }, ) ``` -------------------------------- ### Create and Activate Python Virtual Environment (conda) Source: https://github.com/ecmwf/earthkit/blob/develop/docs/development/setup.md Create a conda environment named 'earthkit-dev' with Python 3.12 and activate it. This is an alternative to venv for managing environments. ```shell conda create -n earthkit-dev python=3.12 conda activate earthkit-dev ``` -------------------------------- ### Import Earthkit Libraries Source: https://github.com/ecmwf/earthkit/blob/develop/docs/tutorials/gpu_hydro.ipynb Import the necessary libraries from earthkit for data handling, hydro computations, and plotting. ```python import earthkit.data as ekd import earthkit.hydro as ekh import earthkit.plots as ekp ``` -------------------------------- ### Create an ensemble plot Source: https://github.com/ecmwf/earthkit/blob/develop/docs/tutorials/ensemble.ipynb Generates a 2x2 plot displaying deterministic forecast, control forecast, ensemble mean, and ensemble spread for windgust at a specific timestep. Imports necessary libraries like earthkit.plots and cartopy. ```python import earthkit.plots as ekp ``` ```python import cartopy.crs as ccrs import datetime # define step step_hours = 78 step = datetime.timedelta(hours=step_hours) figure = ekp.Figure(crs=ccrs.PlateCarree(), domain=[-15,15,65,45], size=(7, 6), rows=2, columns=2) gust_style = ekp.styles.Style( colors=["#85AAEE", "#208EFC", "#6CA632", "#FFB000", "#FF0000", "#7A11B1"], levels=[12, 15, 20, 25, 30, 35, 50], units="m s-1", ) spread_style = ekp.styles.Style(colors="plasma") # the hres forecast, GRIB subplot = figure.add_map(0, 0) subplot.contourf(fl_fc.sel({"parameter.variable": "10fg3", "time.step": step}), style=gust_style) subplot.title("HRES {base_time:%Y-%m-%d %H} UTC (+{lead_time}h)") subplot.legend(label="") # the control forecast, GRIB subplot = figure.add_map(0, 1) subplot.contourf(fl_fg.sel({"metadata.marsType": "cf", "time.step": step}), style=gust_style) subplot.title("CF {base_time:%Y-%m-%d %H} UTC (+{lead_time}h)") subplot.legend(label="") # the ensemble mean, Xarray subplot = figure.add_map(1, 0) subplot.contourf(fg_mean.sel(step=step), style=gust_style) subplot.title("MEAN") subplot.legend(label="") # the ensemble spread, Xarray subplot = figure.add_map(1, 1) subplot.contourf(fg_spread.sel(step=step), style=spread_style) subplot.title("SPREAD") subplot.legend(label="") figure.land() figure.coastlines() figure.borders() figure.show() ``` -------------------------------- ### Load Sample Wind Data Source: https://github.com/ecmwf/earthkit/blob/develop/docs/tutorials/meteo_solutions.ipynb Loads sample GRIB data containing U and V wind components from the earthkit sample dataset. This data is used for wind speed computation. ```python import earthkit.datasets as ekd ds = ekd.from_source("sample", "tquv_pl_2x2.grib").to_fieldlist() ``` -------------------------------- ### Load Forecast Data with earthkit.data Source: https://github.com/ecmwf/earthkit/blob/develop/docs/tutorials/ensemble.ipynb Loads control and ensemble forecast data from sample GRIB files into earthkit.data objects. Ensure the sample files are available in your earthkit-data path. ```python import earthkit.data as ekd 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 ``` -------------------------------- ### Xarray Computation with CuPy Backend Source: https://github.com/ecmwf/earthkit/blob/develop/docs/tutorials/gpu_hydro.ipynb Achieve speedups by using CuPy for xarray computations on a GPU. Ensure your data is copied to the GPU using `cp.asarray` before computation. ```python small_da_gpu = small_da.copy(data=cp.asarray(small_da.data)) %timeit ekh.upstream.sum(net_gpu, small_da_gpu) ``` -------------------------------- ### Create Figure with Specific Domain and Size Source: https://github.com/ecmwf/earthkit/blob/develop/docs/tutorials/comparing-models-solutions.ipynb Initializes an earthkit Figure object. Use 'figsize' for size. Deprecation warning for 'size' argument. ```python figure = ekp.Figure(domain="Europe", rows=1, columns=2, size=(8, 5.5)) ``` -------------------------------- ### Read and Display GRIB Data Source: https://github.com/ecmwf/earthkit/blob/develop/docs/tutorials/meteo_solutions.ipynb Reads GRIB data from a file and displays the first two fields. Ensure the '_pt_res.grib' file exists in the current directory. ```python import earthkit.datasets as ekd # read back saved data and check first 2 fields ds_pt = ekd.from_source("file", "_pt_res.grib").to_fieldlist() ds_pt.head(2) ``` -------------------------------- ### Compute Daily Temporal Statistics Source: https://context7.com/ecmwf/earthkit/llms.txt Calculates daily maximum, minimum, and mean temperature from Xarray time-series data. Requires importing earthkit.data and earthkit.transforms. ```python import earthkit.data as ekd import earthkit.transforms as ekt ds = ekd.from_source( "cds", "reanalysis-era5-single-levels-timeseries", { "variable": ["2m_temperature"], "location": {"longitude": -1, "latitude": 51.5}, "date": ["2025-06-01/2025-09-30"], "data_format": "netcdf", }, ) data = ds.to_xarray() # Daily statistics daily_max = ekt.temporal.daily_max(data).rename({"t2m": "daily max"}) daily_min = ekt.temporal.daily_min(data).rename({"t2m": "daily min"}) daily_mean = ekt.temporal.daily_mean(data).rename({"t2m": "daily mean"}) ``` -------------------------------- ### Import Earthkit Libraries Source: https://github.com/ecmwf/earthkit/blob/develop/docs/tutorials/time-series-solutions.ipynb Import the necessary libraries from the earthkit package for data handling, plotting, and transformations. ```python import earthkit.data as ekd import earthkit.plots as ekp import earthkit.transforms as ekt ``` -------------------------------- ### Clone Earthkit Repository Source: https://github.com/ecmwf/earthkit/blob/develop/docs/development/setup.md Clone the Earthkit repository from GitHub, specifically checking out the 'develop' branch for development. ```shell git clone --branch develop git@github.com:ecmwf/earthkit.git ``` -------------------------------- ### Load Precipitation Dataset Source: https://github.com/ecmwf/earthkit/blob/develop/docs/tutorials/gpu_hydro.ipynb Load a precipitation dataset from a sample source and convert it to an xarray Dataset for further processing. ```python ds = ekd.from_source("sample", "R06a.nc").to_xarray() ds ``` -------------------------------- ### Display Figure Source: https://github.com/ecmwf/earthkit/blob/develop/docs/tutorials/comparing-models-solutions.ipynb Renders the created figure. This command is used to show the plot. ```python figure.show() ``` -------------------------------- ### Run Notebook Tests Source: https://github.com/ecmwf/earthkit/blob/develop/docs/development/tests.md Execute only the notebook tests within the test suite. The -m flag filters tests by the 'notebook' marker. ```shell pytest -v -m notebook ``` -------------------------------- ### Import earthkit.geo Source: https://github.com/ecmwf/earthkit/blob/develop/docs/tutorials/ensemble.ipynb Import the necessary earthkit.geo module for geospatial operations. ```python import earthkit.geo as ekg ``` -------------------------------- ### Select windgust fields and convert to Xarray Source: https://github.com/ecmwf/earthkit/blob/develop/docs/tutorials/ensemble.ipynb Selects '10fg3' parameter fields from an ensemble FieldList and converts them into an Xarray Dataset, ensuring 'forecast_reference_time' is a dimension. ```python # select windgust fields and convert them to Xarray fl_fg = fl_en.sel({"parameter.variable": "10fg3"}) g = fl_fg.to_xarray(ensure_dims="forecast_reference_time") fg ``` -------------------------------- ### Save potential temperature data to a GRIB file Source: https://github.com/ecmwf/earthkit/blob/develop/docs/tutorials/meteo_solutions.ipynb Save the computed potential temperature fieldlist to a GRIB file. This is useful for storing the results for later use or sharing. ```python ds_pt.to_target("file", "_pt_res.grib") ``` -------------------------------- ### Prepare Data for Plotting Source: https://github.com/ecmwf/earthkit/blob/develop/docs/tutorials/gpu_hydro.ipynb Select a single time step from the DataArray and compute the upstream sum using the specified backend (NumPy in this case). ```python step0 = small_da.isel(time=0) upscale_sum = ekh.upstream.sum(net, step0) ``` -------------------------------- ### Plot Temperature Anomalies (Europe Domain) Source: https://github.com/ecmwf/earthkit/blob/develop/docs/tutorials/comparing-models-solutions.ipynb Creates a map of Europe visualizing temperature anomalies from two datasets side-by-side. Initializes a Figure with a specified domain, plots the data using pcolormesh, adds coastlines and borders, and sets titles and legends. The 'size' argument is deprecated; use 'figsize' instead. ```python figure = ekp.Figure(domain="Europe", rows=1, columns=2, size=(8, 5.5)) # We can throw both datasets at the figure and it will iterate over subplots to plot them figure.pcolormesh([hadcrut5_jan_anomaly, era5_jan_anomaly], style=style) figure.coastlines(resolution="medium") figure.borders(resolution="medium") figure.legend(label="temperature anomaly ({units})") # Add titles figure[0].title("HADCRUT5") figure[1].title("ERA5") # We can use the "time" key once here as it should have the same value for ERA5 and HADCRUT5 figure.title("Global temperature anomaly during {time:%B %Y}", fontsize=15) # Add shading to emphasise the missing data in HADCRUT5 ``` -------------------------------- ### Earthkit Project Licence Source: https://github.com/ecmwf/earthkit/blob/develop/README.md This is the Apache License 2.0, which governs the use of the earthkit software. It allows for free use, modification, and distribution. ```text Copyright 2023, European Centre for Medium Range Weather Forecasts. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. In applying this licence, ECMWF does not waive the privileges and immunities granted to it by virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction. ``` -------------------------------- ### Create Stamp Plots for Ensemble Members Source: https://context7.com/ecmwf/earthkit/llms.txt Generates a grid of individual maps, each representing an ensemble member. Useful for visualizing the spread and variation within an ensemble. Requires GRIB data. ```python figure2 = ekp.Figure(domain=[-15, 15, 65, 45], figsize=(7, 7), rows=8, columns=8) fl_pf = fl_fg.sel({"metadata.marsType": "pf", "time.step": step}) for i, f in enumerate(fl_pf): subplot = figure2.add_map(1 + i // 8, i % 8) subplot.contourf(f, style=gust_style) subplot.title("PF {number}") figure2.show() ``` -------------------------------- ### Save and Read Back Wind Speed Data Source: https://github.com/ecmwf/earthkit/blob/develop/docs/tutorials/meteo_solutions.ipynb Saves the computed wind speed data to a GRIB file and then reads it back to verify the save/load process. Ensure write permissions for the current directory. ```python ds_ws.to_target("file", "_ws_res.grib") # read back saved data and check first 2 fields ds_ws = ekd.from_source("file", "_ws_res.grib").to_fieldlist() ds_ws.head(2) ``` -------------------------------- ### Autosummary Function Source: https://github.com/ecmwf/earthkit/blob/develop/docs/_templates/autosummary/function.rst This snippet shows how a function is documented using the autosummary directive, which typically includes its name, module, and a link to its full documentation. ```APIDOC ## {{ objname }} .. currentmodule:: {{ module }} .. autofunction:: {{ objname }} ``` -------------------------------- ### Plot Field with Grid Points Source: https://github.com/ecmwf/earthkit/blob/develop/docs/tutorials/grid_solutions.ipynb Visualizes the GRIB field on a map and overlays the original grid points. Requires earthkit-plots and cartopy. ```python import earthkit.plots as ekp chart = ekp.Map(size=(7,7)) chart.contourf(f, units="celsius", auto_style=True) # plot the original grid points chart.grid_points(f, c="black") #marker="+" chart.title(f"gridType={f.get('geography.grid_type')}") chart.coastlines() chart.gridlines() chart.legend() chart.show() ``` -------------------------------- ### Convert to FieldList and List Contents Source: https://github.com/ecmwf/earthkit/blob/develop/docs/tutorials/ensemble.ipynb Converts earthkit.data objects to FieldLists and displays their contents using ls(). The extra_keys argument allows inspection of specific metadata, such as 'metadata.marsType' to differentiate control ('fc') from perturbed ('pf') forecasts. ```python fl_fc = ds_fc.to_fieldlist() fl_en = ds_en.to_fieldlist() ``` ```python fl_fc.ls(extra_keys=["metadata.marsType"]) ``` ```python fl_en.ls(extra_keys=["metadata.marsType"]) ``` -------------------------------- ### Create a Basic Time Series Plot Source: https://github.com/ecmwf/earthkit/blob/develop/docs/tutorials/time-series-solutions.ipynb Instantiate a TimeSeries object from earthkit-plots and plot the xarray Dataset. The time dimension is automatically placed on the x-axis. ```python chart = ekp.TimeSeries() # Plot our hourly data as a line chart.line(data) chart.show() ``` -------------------------------- ### Plot Daily Min, Mean, and Max Temperatures Source: https://github.com/ecmwf/earthkit/blob/develop/docs/tutorials/time-series-solutions.ipynb Calculate and plot the daily mean temperature between the daily minimum and maximum temperatures. This provides a visual representation of the temperature range throughout the day. ```python daily_mean = ekt.temporal.daily_mean(data).rename({"t2m": "daily mean"}) chart = ekp.TimeSeries() chart.line(daily_max, units="celsius", label="{name}") chart.line(daily_mean, units="celsius", label="{name}") chart.line(daily_min, units="celsius", label="{name}") chart.title("ERA5 hourly {variable_name} at {latitude:%Lt} {longitude:%Ln} ({location:%c}, {location:%C})") chart.ylabel() chart.xticks( frequency="M", format="%B", period=True, ) chart.legend() chart.show() ``` -------------------------------- ### Convert GRIB to xarray Source: https://github.com/ecmwf/earthkit/blob/develop/docs/tutorials/comparing-models-solutions.ipynb Convert GRIB data retrieved from the CDS to xarray DataArrays for further processing. Ensure dimensions are correctly set if needed. ```python reference = era5_reference_data.to_xarray() july_2024 = era5_2024_data.to_xarray(ensure_dims="forecast_reference_time") ``` -------------------------------- ### Create Spaghetti Plot Source: https://github.com/ecmwf/earthkit/blob/develop/docs/tutorials/ensemble.ipynb Generates a spaghetti plot by overlaying isolines from perturbed members, control forecast, and high-resolution forecast onto the same map. Requires earthkit.plots and cartopy to be imported. ```python chart = ekp.Map(crs=ccrs.PlateCarree(), domain=[-15, 15, 65, 45], size=(7,7)) # the isoline value cont_level = [12500] # perturbed members for f in z_en.sel({"metadata.marsType": "pf"}): chart.contour(f, levels=cont_level, linewidths=[0.2, 0.2],colors="blue", labels=False) # control forecast chart.contour(z_en.sel({"metadata.marsType": "cf"}), levels=cont_level, linewidths=[3, 3],colors="red", labels=False) # hres forecasts chart.contour(z_fc, levels=cont_level, linewidths=[3, 3],colors="orange", labels=False) chart.land() chart.coastlines() chart.borders() chart.gridlines() chart.title( "ECMWF Run: {base_time:%Y-%m-%d %H} UTC (+{lead_time}h) {variable_name} {level} hPa", fontsize=9 ) chart.show() ``` -------------------------------- ### Retrieve HADCRUT5 Data from URL Source: https://github.com/ecmwf/earthkit/blob/develop/docs/tutorials/comparing-models-solutions.ipynb Access the gridded monthly surface temperature anomalies dataset (netCDF format) directly from the UK Met Office's website URL. This data is an anomaly against the 1961-1991 average. ```python HADCRUT5_URL = "https://www.metoffice.gov.uk/hadobs/hadcrut5/data/HadCRUT.5.0.2.0/analysis/HadCRUT.5.0.2.0.analysis.anomalies.ensemble_mean.nc" hadcrut5_data = ekd.from_source("url", HADCRUT5_URL) ``` -------------------------------- ### Run no_cache_init Tests Source: https://github.com/ecmwf/earthkit/blob/develop/docs/development/tests.md Execute tests marked with 'no_cache_init' using the pytest-forked plugin. These tests run in a separate process. ```shell pytest --forked -v -m no_cache_init ``` -------------------------------- ### Plot Temperature Anomalies (Global) Source: https://github.com/ecmwf/earthkit/blob/develop/docs/tutorials/comparing-models-solutions.ipynb Creates a global map visualizing temperature anomalies from two datasets side-by-side. Initializes a Figure with a Robinson projection, plots the data using pcolormesh, adds coastlines and borders, and sets titles and legends. The 'size' argument is deprecated; use 'figsize' instead. ```python figure = ekp.Figure(crs=ccrs.Robinson(), rows=1, columns=2, size=(8, 5.5)) # We can throw both datasets at the figure and it will iterate over subplots to plot them figure.pcolormesh([hadcrut5_jan_anomaly, era5_jan_anomaly], style=style) figure.coastlines(resolution="low") figure.borders(resolution="low") figure.legend(label="temperature anomaly ({units})") # Add titles figure[0].title("HADCRUT5") figure[1].title("ERA5") # We can use the "time" key once here as it should have the same value for ERA5 and HADCRUT5 figure.title("Global temperature anomaly during {time:%B %Y}", fontsize=15) # Add shading to emphasise the missing data in HADCRUT5 # We can directly access the underlying matplotlib objects to do this x = [-180, -180, 180, 180, -180] y = [-90, 90, 90, -90, -90] figure[0].ax.fill(x, y, transform=ccrs.PlateCarree(), hatch="///////", fill=False, zorder=0) figure.show() ``` -------------------------------- ### Draw Contours and Grid Points on a Map Source: https://context7.com/ecmwf/earthkit/llms.txt Draws isolines and scatters grid-point positions onto a map for GRIB fields. Requires earthkit.data, earthkit.plots, and earthkit.geo imports. ```python import earthkit.data as ekd import earthkit.plots as ekp import earthkit.geo as ekg ds = ekd.from_source("sample", "grids_3.grib").to_fieldlist() f = ds.sel({"geography.grid_type": "regular_ll"})[0] chart = ekp.Map(size=(7, 7)) chart.contourf(f, units="celsius", auto_style=True) chart.grid_points(f, c="black") # scatter the native gridpoints chart.title(f"gridType={f.get('geography.grid_type')}") chart.coastlines() chart.gridlines() chart.legend() chart.show() ``` ```python # Spaghetti plot — all ensemble isolines on one map import cartopy.crs as ccrs import datetime fl_en = ekd.from_source("sample", "ens_storm_st_jude.grib").to_fieldlist() step = datetime.timedelta(hours=78) z_en = fl_en.sel({"parameter.variable": "z", "vertical.level": 850, "time.step": step}) chart2 = ekp.Map(crs=ccrs.PlateCarree(), domain=[-15, 15, 65, 45], size=(7, 7)) for f in z_en.sel({"metadata.marsType": "pf"}): chart2.contour(f, levels=[12500], linewidths=[0.2], colors="blue", labels=False) chart2.contour(z_en.sel({"metadata.marsType": "cf"}), levels=[12500], linewidths=[3], colors="red", labels=False) chart2.coastlines() chart2.show() ``` -------------------------------- ### Access Results for a Specific Step Source: https://context7.com/ecmwf/earthkit/llms.txt Selects and retrieves ensemble statistics (mean and spread) for a particular forecast step. ```python step = datetime.timedelta(hours=78) mean_at_step = fg_mean.sel(step=step) spread_at_step = fg_spread.sel(step=step) ``` -------------------------------- ### Plot Wind Speed and Arrows Source: https://github.com/ecmwf/earthkit/blob/develop/docs/tutorials/meteo_solutions.ipynb Generates a map visualization showing wind speed contours and wind barbs over Europe for a specific level. Requires U and V wind components to be loaded. ```python level = 850 chart = ekp.Map(domain="Europe", size=(6,6)) chart.contourf(ds_ws.sel({"vertical.level": level}), units="m s-1", colors="Greens", levels=list(range(4,22,2)), alpha=1) chart.quiver(u=u.sel({"vertical.level": level}), v=v.sel({"vertical.level": level})) chart.coastlines() chart.gridlines() chart.legend() chart.title(("{time:%Y-%m-%d %H} UTC (+{lead_time}h) {level} hPa")) chart.show() ``` -------------------------------- ### List computed potential temperature fields Source: https://github.com/ecmwf/earthkit/blob/develop/docs/tutorials/meteo_solutions.ipynb Display the metadata of the computed potential temperature fields. This helps in verifying the results and understanding the structure of the output data. ```python ds_pt.ls() ``` -------------------------------- ### Fetch Data for Specific Location and Time Source: https://github.com/ecmwf/earthkit/blob/develop/docs/tutorials/time-series-solutions.ipynb Retrieve ERA5 hourly time series data for a specific location (Bologna, Italy) and time range (summer 2025) using the earthkit-data client. ```python dataset = "reanalysis-era5-single-levels-timeseries" request = { "variable": ["2m_temperature"], "location": {"longitude": 11.25, "latitude": 44.5}, "date": ["2025-06-01/2025-09-30"], "data_format": "netcdf" } ds = ekd.from_source("cds", dataset, request) data = ds.to_xarray() ``` -------------------------------- ### Create Smaller DataArray Source: https://github.com/ecmwf/earthkit/blob/develop/docs/tutorials/gpu_hydro.ipynb Create a smaller DataArray from the loaded Dataset for illustration purposes, selecting a subset of time steps. ```python # create a smaller dataarray for illustration purposes da = ds["R06a"].isel(time=slice(0,10)) da ``` -------------------------------- ### Generate Percentile Map Source: https://github.com/ecmwf/earthkit/blob/develop/docs/tutorials/ensemble.ipynb Plots a percentile map for wind gusts, showing the value below which a certain percentage of ensemble members fall. Requires earthkit.plots and cartopy. The 'gust_style' object should be pre-defined. ```python # define step step=78 chart = ekp.Map(crs=ccrs.PlateCarree(), domain=[-15, 15, 65, 45], size=(7,7)) chart.contourf(perc_xr.sel(step=datetime.timedelta(hours=step)), style=gust_style) chart.land() chart.coastlines() chart.borders() chart.gridlines() chart.legend() chart.title("{variable_name} (+" +str(step) + " h) percentile " + str(perc*100) + " %", fontsize=9) chart.show() ``` -------------------------------- ### Plotting Temperature and Potential Temperature Source: https://github.com/ecmwf/earthkit/blob/develop/docs/tutorials/meteo_solutions.ipynb Generates a figure with two subplots to visualize temperature and potential temperature fields. Requires earthkit.plots and specific data to be loaded. ```python import earthkit.plots as ekp figure = ekp.Figure(rows=1, columns=2) level = 850 t_style = ekp.styles.Style( units="K", levels=list(range(220,340,10)) ) subplot = figure.add_map(0, 0) subplot.contourf(t.sel({"vertical.level": level}), style=t_style) subplot.title("{shortName} {level} hPa") subplot.legend() subplot = figure.add_map(0, 1) subplot.contourf(ds_pt.sel({"vertical.level": level}), style=t_style) subplot.title("{shortName} {level} hPa") subplot.legend() figure.coastlines() figure.gridlines() figure.show() ``` -------------------------------- ### Compute Potential Temperature with earthkit.meteo.thermo.fieldlist.potential_temperature Source: https://context7.com/ecmwf/earthkit/llms.txt Calculate potential temperature from temperature fields on pressure levels. This function operates on GRIB FieldLists and returns a new FieldList with the parameter 'pt'. ```python import earthkit.data as ekd from earthkit.meteo.thermo.fieldlist import potential_temperature ds = ekd.from_source("sample", "tquv_pl_2x2.grib").to_fieldlist() t = ds.sel({"parameter.variable": "t"}) ds_pt = potential_temperature(t) ds_pt.ls() # parameter.variable vertical.level vertical.level_type # pt 1000 pressure # pt 850 pressure # pt 700 pressure # pt 500 pressure # pt 400 pressure # pt 300 pressure ``` -------------------------------- ### Run Long Tests Source: https://github.com/ecmwf/earthkit/blob/develop/docs/development/tests.md Enable and run tests that are marked as 'long', typically involving remote services. Use the -E flag to specify test markers. ```shell pytest -E long -v ``` -------------------------------- ### Plot Field on a Specific Domain with Grid Points Source: https://github.com/ecmwf/earthkit/blob/develop/docs/tutorials/grid_solutions.ipynb Plots a GRIB field over a specified geographical domain (e.g., 'Europe') and marks the grid points. Useful for regional analysis. ```python import cartopy.crs as ccrs chart = ekp.Map(domain="Europe") chart.contourf(f, units="celsius", auto_style=True) # plot the original grid points chart.grid_points(f, c="black") #marker="+" ``` -------------------------------- ### Plot Daily Precipitation as a Bar Chart Source: https://github.com/ecmwf/earthkit/blob/develop/docs/tutorials/time-series-solutions.ipynb Create and display a bar chart of the daily precipitation data. Customize the chart title, y-axis label, and x-axis ticks for better readability. This snippet visualizes the processed time series data. ```python chart = ekp.TimeSeries() chart.bar(daily_precip, units="mm") chart.title("ERA5 hourly {variable_name} at {latitude:%Lt} {longitude:%Ln} ({location:%c}, {location:%C})") chart.ylabel() chart.xticks( frequency="M", format="%B", period=True, ) chart.show() ``` -------------------------------- ### Create a Multi-Panel Geographical Figure Source: https://context7.com/ecmwf/earthkit/llms.txt Generates a multi-panel geographical plot using EarthKit's Figure class. Allows for custom layouts (rows, columns) and plotting different data on each map. Requires GRIB data and ensemble data. ```python import earthkit.transforms as ekt import datetime fl_en = ekd.from_source("sample", "ens_storm_st_jude.grib").to_fieldlist() fl_fg = fl_en.sel({"parameter.variable": "10fg3"}) fg_mean = ekt.ensemble.mean(fl_fg.to_xarray(ensure_dims="forecast_reference_time")) fg_spread = ekt.ensemble.std(fl_fg.to_xarray(ensure_dims="forecast_reference_time")) step = datetime.timedelta(hours=78) gust_style = ekp.styles.Style( colors=["#85AAEE", "#208EFC", "#6CA632", "#FFB000", "#FF0000", "#7A11B1"], levels=[12, 15, 20, 25, 30, 35, 50], units="m s-1", ) figure = ekp.Figure(domain=[-15, 15, 65, 45], size=(7, 6), rows=2, columns=2) figure.add_map(0, 0).contourf(fg_mean.sel(step=step), style=gust_style) figure.add_map(0, 1).contourf(fg_spread.sel(step=step), style=ekp.styles.Style(colors="plasma")) figure.coastlines() figure.land() figure.show() ``` -------------------------------- ### FieldList inspection and selection Source: https://context7.com/ecmwf/earthkit/llms.txt A FieldList is the primary in-memory container for GRIB data, offering pandas-style inspection and selection via metadata. Use `ls` for listing fields and `sel` for filtering. ```python import earthkit.data as ekd fl = ekd.from_source("sample", "tquv_pl_2x2.grib").to_fieldlist() # Inspect all fields fl.head(6) # parameter.variable time.valid_datetime vertical.level geography.grid_type # t 2018-08-01 12:00:00 1000 regular_ll # q 2018-08-01 12:00:00 1000 regular_ll # ... # Select fields by metadata predicates t = fl.sel({"parameter.variable": "t"}) t_850 = fl.sel({"parameter.variable": "t", "vertical.level": 850}) # List with extra metadata columns fl.ls(extra_keys=["metadata.marsType"]) # ... metadata.marsType # fc # Ensemble fieldlist — shows cf/pf members fl_en = ekd.from_source("sample", "ens_storm_st_jude.grib").to_fieldlist() fl_en.ls(extra_keys=["metadata.marsType"]) # ensemble.member metadata.marsType # 0 cf # 1 pf # ... (306 rows) ``` -------------------------------- ### Regridding Fields Source: https://context7.com/ecmwf/earthkit/llms.txt Interpolate GRIB data between grids using configurable interpolation methods (linear, nearest, bilinear, etc.), producing a new FieldList on the target grid. ```APIDOC ## earthkit.geo — `regrid` Interpolate GRIB data between grids using configurable interpolation methods (linear, nearest, bilinear, etc.), producing a new FieldList on the target grid. ```python import earthkit.data as ekd import earthkit.geo as ekg ds = ekd.from_source("sample", "grids_3.grib").to_fieldlist() f = ds.sel({"geography.grid_type": "regular_ll"})[0] # Regrid to a 10x10 degree global regular lat-lon grid target_grid = {"grid": [10, 10]} ds_regridded = ekg.regrid(f, grid=target_grid, interpolation="linear") print(ds_regridded[0].geography.shape()) # (19, 36) — coarser grid ``` ``` -------------------------------- ### NumPy-based Upstream Summation (Baseline) Source: https://github.com/ecmwf/earthkit/blob/develop/docs/tutorials/gpu_hydro.ipynb Perform an upstream summation using numpy as the array backend. This serves as a baseline for performance comparison. ```python array_np = da.values # convert to array (numpy) %timeit ekh.upstream.array.sum(net, array_np) ``` -------------------------------- ### Create Publication-Quality Time-Series Charts Source: https://context7.com/ecmwf/earthkit/llms.txt Generates time-series charts with automatic unit conversion, flexible axis orientation, and multi-layer composition. Supports line and bar charts, and direct plotting from Polytope Xarray datasets. ```python import earthkit.data as ekd import earthkit.plots as ekp import earthkit.transforms as ekt ds = ekd.from_source( "cds", "reanalysis-era5-single-levels-timeseries", {"variable": ["2m_temperature"], "location": {"longitude": -1, "latitude": 51.5}, "date": ["2025-06-01/2025-09-30"], "data_format": "netcdf"}, ) data = ds.to_xarray() daily_max = ekt.temporal.daily_max(data).rename({"t2m": "daily max"}) daily_min = ekt.temporal.daily_min(data).rename({"t2m": "daily min"}) daily_mean = ekt.temporal.daily_mean(data).rename({"t2m": "daily mean"}) # Line chart with unit conversion and monthly tick labels chart = ekp.TimeSeries() chart.line(daily_max, units="celsius", label="{name}") chart.line(daily_mean, units="celsius", label="{name}") chart.line(daily_min, units="celsius", label="{name}") chart.title("ERA5 {variable_name} at {latitude:%Lt} {longitude:%Ln}") chart.ylabel() chart.xticks(frequency="M", format="%B", period=True) chart.legend() chart.show() ``` ```python # Bar chart for precipitation ds_precip = ekd.from_source( "cds", "reanalysis-era5-single-levels-timeseries", {"variable": ["total_precipitation"], "location": {"longitude": -1, "latitude": 51.5}, "date": ["2025-06-01/2025-09-30"], "data_format": "netcdf"}, ) daily_precip = ekt.temporal.daily_mean(ds_precip) chart2 = ekp.TimeSeries() chart2.bar(daily_precip, units="mm") chart2.ylabel() chart2.show() ``` ```python # ENS meteogram directly from Polytope Xarray dataset TIME_FREQUENCY = "6h" QUANTILES = [0, 0.1, 0.25, 0.5, 0.75, 0.9, 1] ekp.timeseries.multiboxplot(ds_poly, resample=TIME_FREQUENCY, quantiles=QUANTILES).line( ds_poly.mean(dim="number") ) ```