#!/usr/bin/env python
# coding: utf-8
#
#

#
#
# # Ensemble mean and spread for 10m wind speed
# 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-10ws-mean-spread
#
#
#

#
# The full list of available Open data products can be found [here](https://www.ecmwf.int/en/forecasts/datasets/open-data), and more information can be found in the [User documentation](https://confluence.ecmwf.int/display/DAC/ECMWF+open+data%3A+real-time+forecasts+from+IFS+and+AIFS).
#
# Access to ECMWF Open data is governed by the Creative Commons CC-BY-4.0 licence and associated [Terms of Use](https://apps.ecmwf.int/datasets/licences/general/).
#
# 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
#
# To find out how to obtain the access to the full forecast dataset at higher resolution please visit our [Access page](https://www.ecmwf.int/en/forecasts/accessing-forecasts).
# ## Retrieve Data
# This product takes in input 2 parameters :
#
# * [10 metre U wind component](https://codes.ecmwf.int/grib/param-db/165)
# * [10 metre V wind component](https://codes.ecmwf.int/grib/param-db/166)
# In this example, we will use:
# - [**ecmwf.opendata**](https://github.com/ecmwf/ecmwf-opendata) Client to download the data
# - [**Metview**](https://metview.readthedocs.io/en/latest/) library to read, process and plot the data
# First we need to install them in the current Jupyter kernel:
#
# Note: If you are running the notebook on MyBinder or already have the libraries installed, go directly to importing the libraries.
#
#
# Note: If you don't have these libraries installed, click on three dots below, uncomment the code and run the next cell.
#
# In[1]:
#!pip install ecmwf-opendata metview metview-python
# In[2]:
import metview as mv
from ecmwf.opendata import Client
# In[3]:
client = Client("ecmwf", beta=True)
# In[4]:
parameters = ['10u','10v']
filename = 'medium-10ws-mean-spread.grib'
filename
# To calculate the mean and spread of the 10m wind speed, we need to retrieve all the ensemble members at the given time.
# We need to put both **cf** and **pf** as type **type** to download all 50 ensemble members as well as the control forecast.
# Setting date to 0 will download today's data.
# Removing date and time altogether from the request will download the latest data.
# Try commenting out date and time to download latest forecast!
# In[5]:
client.retrieve(
date=0,
time=0,
step=72,
stream="enfo",
type=['cf', 'pf'],
levtype="sfc",
param=parameters,
target=filename
)
# ## Reading and processing the data
# Now we can use **ecmwf.data** to read the file.
# In[6]:
data = mv.read(filename)
# The **describe()** function will give us the overview of the dataset.
# In[7]:
data.describe()
# We can use **ls()** function to list all the fields in the file we downloaded.
# Note that this fieldset has all fields randomly arranged. You can see that if you look at the **number** column. These are ensemble member numbers.
# In[8]:
data.ls()
# **ecmwf.data** library has a built in function to calculate the speed from u and v components. It takes u/v fieldsets as input and gives back speed intensity.
# Note that we can give a fieldset on N u/v components, not just one pair.
#
# In this case we will calculate all 51 ensemble members at the same time.
# First we need to filter out u and v and sort the fieldsets.
# In[9]:
u = data.select(shortName= '10u').sort()
v = data.select(shortName= '10v').sort()
# And then we calculate the wind speed. Metview has builti in function for this.
# In[10]:
speed = mv.speed(u,v)
speed.describe()
# In the end we still need to calculate the mean and spread (as standard deviation) of the wind speed.
# **ecmwf.data** has built in functions to calculate mean and standard deviation of a given fieldset.
# Since our data has only one date,time and step, mean() and stdev() will be calculated over the 51 ensemble members.
# In[11]:
ws_mean = mv.mean(speed)
ws_spread = mv.stdev(speed)
# ## Plotting the data
# And finally, we can plot the data on the map.
# In[12]:
# 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",
coastlines=coast
)
#define styles
speed_mean_contour = mv.mcont(legend = "on",
contour_highlight_colour = 'black',
contour_highlight_thickness = 4,
contour_interval = 5,
contour_label = 'on',
contour_label_frequency = 1,
contour_label_height = 0.4,
contour_level_selection_type = 'interval',
contour_line_colour = 'black',
contour_line_thickness = 2)
speed_spread_shade = mv.mcont(legend= "on",
contour_automatics_settings = "style_name",
contour_style_name = "sh_blu_f02t30")
title = mv.mtext(
text_lines=["Ensemble mean and spread for 10m wind speed",
"START TIME: ",
"VALID TIME: , STEP: "],
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, ws_spread, speed_spread_shade, ws_mean, speed_mean_contour, title, ecmwf_text)
# To generate the png file you can run the following cell.
# In[13]:
png = mv.png_output(
output_name = "medium-10ws-mean-spread", # specify relative or full path
output_title = "medium-10ws-mean-spread", # title used by a viewer
output_width = 1000, # set width in pixels
)
mv.setoutput(png)
mv.plot(view, ws_spread, speed_spread_shade, ws_mean, speed_mean_contour, 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.