This notebook will provide you guidance how to explore and plot ECMWF open dataset to produce the map from the ECMWF open charts web product.
The original product can be found on this link: https://charts.ecmwf.int/products/medium-wind-10m
The full list of available Open data products can be found here, and more information can be found in the User documentation.
This product takes in input 3 parameters :
In this example, we will use:
First we need to install them in the current Jupyter kernel:
#!pip install ecmwf-opendata metview metview-python
import metview as mv
from ecmwf.opendata import Client
client = Client("ecmwf", beta=True)
parameters = ['msl', '10u', '10v']
filename = 'medium-wind-10m.grib'
filename
'medium-wind-10m.grib'
client.retrieve(
date=0,
time=0,
step=12,
stream="oper",
type="fc",
levtype="sfc",
param=parameters,
target=filename
)
20241224000000-12h-oper-fc.grib2: 0%| | 0.00/2.12M [00:00<?, ?B/s]
<ecmwf.opendata.client.Result at 0x10f2cfc10>
Now we can use ecmwf.data to read the files.
data = mv.read(filename)
The describe() function will give us the overview of the dataset.
data.describe()
parameter | typeOfLevel | level | date | time | step | number | paramId | class | stream | type | experimentVersionNumber |
---|---|---|---|---|---|---|---|---|---|---|---|
10u | heightAboveGround | 10 | 20241224 | 0 | 12 | None | 165 | od | oper | fc | 0001 |
10v | heightAboveGround | 10 | 20241224 | 0 | 12 | None | 166 | od | oper | fc | 0001 |
msl | meanSea | 0 | 20241224 | 0 | 12 | None | 151 | od | oper | fc | 0001 |
And an overview of one parameter, where we can see more information, such as units or type of level.
data.describe('msl')
shortName | msl |
---|---|
name | Mean sea level pressure |
paramId | 151 |
units | Pa |
typeOfLevel | meanSea |
level | 0 |
date | 20241224 |
time | 0 |
step | 12 |
number | None |
class | od |
stream | oper |
type | fc |
experimentVersionNumber | 0001 |
msl = data.select(shortName = 'msl')
msl.describe()
parameter | typeOfLevel | level | date | time | step | number | paramId | class | stream | type | experimentVersionNumber |
---|---|---|---|---|---|---|---|---|---|---|---|
msl | meanSea | 0 | 20241224 | 0 | 12 | None | 151 | od | oper | fc | 0001 |
Mean sea level pressure data has unites Pa, but we want to plot it in hPa, therefore we need to convert it.
msl /= 100
We can calculate wind speed using u and v component:
u = data.select(shortName='10u')
v = data.select(shortName='10v')
speed = mv.speed(u,v)
speed.describe()
parameter | typeOfLevel | level | date | time | step | number | paramId | class | stream | type | experimentVersionNumber |
---|---|---|---|---|---|---|---|---|---|---|---|
10si | heightAboveGround | 10 | 20241224 | 0 | 12 | None | 207 | od | oper | fc | 0001 |
We need to create a wind vector field for the visualisation, as well.
wind_vector = mv.grib_vectors(u_component = u, v_component = v)
And finally, we can plot the data on the map.
# define coastlines
coast = mv.mcoast(
map_coastline_colour="charcoal",
map_coastline_resolution="medium",
map_coastline_land_shade="on",
map_coastline_land_shade_colour="cream",
map_coastline_sea_shade="off",
map_boundaries="on",
map_boundaries_colour= "charcoal",
map_boundaries_thickness = 1,
map_disputed_boundaries = "off",
map_grid_colour="tan",
map_label_height=0.35,
)
# define view
view = mv.geoview(
area_mode = "name",
area_name = "europe",
subpage_clipping = "off",
coastlines = coast
)
#define styles
speed_shade = mv.mcont(legend= "on",
contour_automatics_settings = "style_name",
contour_style_name = "sh_grn_f10t100lst")
msl_shade = mv.mcont(legend= "off",
contour_automatics_settings = "style_name",
contour_style_name = "ct_blk_i5_t2")
wind_arrows = mv.mwind(
wind_thinning_factor=5, wind_arrow_colour="black"
)
title = mv.mtext(
text_lines=["10m wind and mean sea level pressure",
"START TIME: <grib_info key='base-date' format='%a %d %B %Y %H' where='shortName=msl'/>",
"VALID TIME: <grib_info key='valid-date' format='%a %d %B %Y %H' where='shortName=msl'/>, STEP: <grib_info key='step' where='shortName=msl'/>"],
text_font_size=0.4,
text_colour = 'charcoal')
ecmwf_text = mv.mtext(
text_lines = ["© European Centre for Medium-Range Weather Forecasts (ECMWF)",
"Source: www.ecmwf.int Licence: CC-BY-4.0 and ECMWF Terms of Use",
"https://apps.ecmwf.int/datasets/licences/general/"],
text_justification = 'center',
text_font_size = 0.3,
text_mode = "positional",
text_box_x_position = 6.,
text_box_y_position = -0.2,
text_box_x_length = 8,
text_box_y_length = 2,
text_colour = 'charcoal')
# generate plot
mv.setoutput('jupyter', plot_widget=False)
mv.plot(view, speed, speed_shade, msl, msl_shade, wind_vector, wind_arrows, title, ecmwf_text)
To generate the png file you can run the following cell.
png = mv.png_output(
output_name = "medium-wind-10m", # specify relative or full path
output_title = "medium-wind-10m", # title used by a viewer
output_width = 1000, # set width in pixels
)
mv.setoutput(png)
mv.plot(view, speed, speed_shade, msl, msl_shade, wind_vector, wind_arrows, title, ecmwf_text)
Note that plot produced using open data dataset will slightly differ from one from Open Charts. This is due to different resolution of the data.
Open data is on 0.25x0.25 resolution, while high resolution data is 0.1x0.1 grid.