Tutorial 3 – Create a climate graph application¶



What is a climate chart?¶

A climate chart displays long-term average monthly air temperature and precipitation information for a particular location. The chart consists of a line plot representing average air temperature for each month, together with monthly precipitation totals in a bar chart.

The figure below shows you the application and climate chart you are going to build in this tutorial.

Building the application step-by-step¶


Load this example in the Toolbox.

Let us walk through the steps of building a climate chart application by breaking down and analysing the example provided.


Creating the application¶

The first step is to import the cdstoolbox library.

import cdstoolbox as ct

Next, you need to initialise the application with a title. You can also add a description.

@ct.application( title=’Climate chart application’, description=’This application generates a climate chart displaying the average temperature and rainfall for a predefined location on Earth’ )

Now add an output widget.
The widget we add is ct.output.livefigure(), which returns an interactive bar or line chart based on Plotly.


So far, you have set out the general layout and the output widget of the application.

See also

Learn more about adjusting the position of input and output widgets in this how-to guide

The next step is to define the application function.

Defining the application function¶

Define the function create_climate_chart() with the def keyword:

def create_climate_chart():

Figure 1. Overview of the individual processing steps for each of the two datasets required.

Let us look at each part of the function in more detail.

1. Retrieve two datasets over a defined time range¶

You need two different data sets from the ERA5 data catalogue.

1a. Retrieve ERA5 monthly averaged data on single levels – 2m air temperature¶

As a first step you need to retrieve the 2m air temperature from the ERA5-monthly-averaged-on-single-levels data set.

The product type for this data set is ‘monthly_averaged_reanalysis’, which we specify in the retrieve function. The retrieve function also includes the variable 2m_temperature, and the years and months of interest. For a climate chart you are interested in all months, and the example below retrieves the data for the 10-year period from 2009 to 2018. Let us call the data object t2m_monthly_mean.

t2m_monthly_mean = ct.catalogue.retrieve( ‘reanalysis-era5-single-levels-monthly-means’, { ‘product_type’: ‘monthly_averaged_reanalysis’, ‘variable’: ‘2m_temperature’, ‘year’: [‘2009′,’2010′,’2011′,’2012′,’2013′,’2014′,’2015′,’2016′,’2017′,’2018’], ‘month’: [ ’01’,’02’,’03’, ’04’,’05’,’06’, ’07’,’08’,’09’, ’10’,’11’,’12’ ], ‘time’: ’00:00′, ‘grid’: [3, 3], } )

We now have the monthly mean 2m_temperature values for the period 2009 to 2018.


We include the keyword 'grid': [3, 3], which defines the spatial resolution of the retrieved data.
Using 'grid' allows you to request fewer data points and therefore speed up the data retrieval and processing.
If no grid is specified, the default resolution for ERA5 (0.25 degrees x 0.25 degrees) is used.

1b. Retrieve ERA5 hourly data on single levels – Total precipitation¶

The second dataset you need is ‘total precipitation’ from the ERA5 hourly data on single levels. The variable ‘total precipitation’ is part of the monthly aggregated ERA5 product, but the monthly aggregated data represents the average daily amount of precipitation that falls in a given month. For a climate chart, you require the total rainfall for each month. You therefore need to retrieve the raw data, which is in the form of hourly precipitation flux, measured in m/s. In a subsequent step, you will first convert the data from hourly flux to hourly rainfall height in mm and then calculate the total rainfall per month.

The retrieve request provided in the code snippet below now includes ‘day’ and ‘time’ to select all the days and hours available. Note also that the variable is now ‘total_precipitation’ and the product type ‘reanalysis’. Let us call the resulting data object tp_hourly.

tp_hourly = ct.catalogue.retrieve( ‘reanalysis-era5-single-levels’, { ‘product_type’:’reanalysis’, ‘variable’:’total_precipitation’, ‘year’:[ ‘2009’, ‘2010’, ‘2011’, ‘2012’, ‘2013’, ‘2014’, ‘2015’, ‘2016’, ‘2017’, ‘2018’ ], ‘month’:[ ’01’, ’02’, ’03’, ’04’, ’05’, ’06’, ’07’, ’08’, ’09’, ’10’, ’11’, ’12’ ], ‘day’:[ ’01’, ’02’, ’03’, ’04’, ’05’, ’06’, ’07’, ’08’, ’09’, ’10’, ’11’, ’12’, ’13’, ’14’, ’15’, ’16’, ’17’, ’18’, ’19’, ’20’, ’21’, ’22’, ’23’, ’24’, ’25’, ’26’, ’27’, ’28’, ’29’, ’30’, ’31’ ], ‘time’:[ ’00:00′,’01:00′,’02:00′, ’03:00′,’04:00′,’05:00′, ’06:00′,’07:00′,’08:00′, ’09:00′,’10:00′,’11:00′, ’12:00′,’13:00′,’14:00′, ’15:00′,’16:00′,’17:00′, ’18:00′,’19:00′,’20:00′, ’21:00′,’22:00′,’23:00′ ], ‘grid’:[3, 3] } )

We now have the hourly total precipitation flux values in m/s for the period 2009 to 2018.

See also

For more detailed information on how retrieve requests work, including using 'grid' to set the resolution, have a look at this how-to guide.

2. Resample total precipitation hourly data¶

The total precipitation hourly dataset you retrieved above needs to be processed in order to get the total amount of precipitation falling in one month. The operation you are interested in is called resampling, as you reduce (i.e. resample) the time axis from an hourly basis to a daily basis.

Next, you need to update the data object’s attributes with ct.cdm.update_attributes(), in order to set the 'units' kwarg to ‘mm’.

tp_hourly_column = tp_hourly * 3600 * 1000 tp_hourly_column = ct.cdm.update_attributes(tp_hourly_column, {‘units’: ‘mm’})

Then you need to apply the ct.cube.resample() function to the tp_hourly_column data object.
Here, you resample the time dimension from hourly values to monthly sums.
You need to set the freq argument to ‘month’, the dim argument to ‘time’ and the how operation to ‘sum’.

You also need to set the kwarg closed='right' for total precipitation.
Total precipitation is a forecast parameter and the 00:00 time step gives the precipitation falling between 23:00 and 00:00 of the previous day.
Setting closed='right' ignores this first 00:00 time step for each day, and instead takes the 00:00 time step from the following day.

tp_monthly_sums = ct.cube.resample(tp_hourly_column, freq=’month’, dim=’time’, closed=’right’, how=’sum’)

We now have the cumulative total precipitation for every month from 2009 to 2018.


The print(<data_name>) statement allows you to inspect the data structure of the two retrieved data objects, tp_monthly_sums and t2m_monthly_mean.
The structure is printed to the console after you click on Run.
This can be very useful while you are developing a workflow, as the information displayed in the console includes dimensions, parameter names and other key attributes.

3. Generate climatology means for each month¶

The next step is to calculate, for each of our data objects (mean air temperature and total precipitation), the average value (climatology mean) for each month of the year over the ten-year period. The time dimension is therefore reduced to twelve values only.

You can use the ct.climate.climatology_mean() function to calculate the climatology mean of a data object.
The sampling frequency for averaging can be either ‘month’ or ‘dayofyear’.
In this case, set the frequency argument to ‘month’.

t2m_mean_climatology = ct.climate.climatology_mean(t2m_monthly_mean, frequency=’month’) tp_climatology = ct.climate.climatology_mean(tp_monthly_sums, frequency=’month’)

We now have the average value for each month of the year for the two variables (mean 2m air temperature and total precipitation), based on the ten-year period 2009-2018.

4. Select a location, defined by longitude and latitude coordinates¶

ct.geo.extract_point()to define your location. The function requires the data object you want to extract information from and the latitude and longitude coordinates. In this case we have chosen the latitude and longitude values of Rome (latitude: 41.9 and longitude: 12.5).

t2m_mean_loc = ct.geo.extract_point(t2m_mean_climatology, lon=12.5., lat=41.9) tp_loc = ct.geo.extract_point(tp_climatology, lon=12.5, lat=41.9)

We now have a time series of the monthly average values for each variable for the location Rome, Italy.

Exercise 1

5. Generate an interactive climate chart¶

The last step is to visualise the extracted data points as a climate chart, using the format we saw in the image at the beginning of the tutorial.

The first step is to define the general layout of the chart.
We define a dictionary with relevant keyword arguments (kwargs) and call it layout_kwargs.

'height': to specify the final width and height of the chart
'legend': to define a horizontal orientation and the x and y position of the legend
'yaxis': to define the axis title and the order of the different charts. In our example, the line plot is on top of the bar chart. For this reason, you need to specify the
‘overlaying’kwarg for the
'xaxis': with the
'ticktext'kwargs, you can customise the tick labels. In this chart, we use month names for the tick labels instead of the number of the month
'yaxis2': you need to define a second y-axis for precipitation. With the side kwarg you can define which side of the chart the second y-axis will be located on
'margin': to define the top, bottom, right and left (
'l') margins of your chart. The example shows how to change the default margin at the top.

layout_kwargs = { ‘width’: 1000, ‘height’: 700, ‘legend’: { ‘orientation’: ‘h’, ‘y’: -0.15, ‘x’: 0.1 }, ‘yaxis’: { ‘overlaying’: ‘y2’, ‘zeroline’: False, ‘title’: ‘2m air temperature in deg C’ }, ‘margin’: {‘t’: 25}, ‘xaxis’: { ‘tickvals’: [1,2,3,4,5,6,7,8,9,10,11,12], ‘ticktext’: [‘Jan’, ‘Feb’, ‘Mar’, ‘Apr’, ‘May’, ‘Jun’,’Jul’,’Aug’,’Sep’,’Oct’,’Nov’,’Dec’], ‘title’: ‘Month’ }, ‘yaxis2’: { ‘showgrid’: False, ‘side’: ‘right’, ‘zeroline’: False, ‘title’: ‘Total precipitation in mm’ } }

Once you have specified the general layout options of your chart, you can define your chart object.
Let us call it fig.

We start by plotting the total precipitation as a bar chart.
You can use the ct.chart.bar() function to generate a bar plot.
The bar_kwargs argument allows you to define a name.
With yaxis you can specify that this plot will be associated with the secondary y-axis on the right.
The marker argument allows you to modify the style of the bars.
The example changes the color to ‘lightsteelblue’.
The layout_kwargs dictionary you have defined above is assigned to the layout_kwargs argument of the chart.

fig = ct.chart.bar( tp_loc, bar_kwargs={ ‘name’:’Total precipitation’, ‘yaxis’: ‘y2’ }, marker={‘color’:’lightsteelblue’}, layout_kwargs=layout_kwargs )

The next step is to overlay the data object for mean air temperature as a line chart.
You can do this by creating a new chart object with ct.chart.line().
The fig argument allows you to define the figure object you would like to add this chart to.

scatter_kwargs: to define the type of line plot as well as a name
marker: to change any default styles, e.g. set a different colour
layout_kwargs: to assign the same layout options as defined above.

Now you can define a ct.chart.line() plot for the mean air temperature data object:

# Add a line plot for 2m mean temperature to the plot fig = ct.chart.line( t2m_mean_loc, fig=fig, scatter_kwargs={ ‘name’:’Mean temperature’, ‘mode’:’lines’ }, marker={‘color’:’firebrick’}, layout_kwargs=layout_kwargs )

The final step is to return the fig object from the function.

return fig

The result is a climate chart application for a predefined location on Earth.

Exercise 2

  • Change the colour of the 2m temperature line to ‘orange’ and the colour of the precipitation bars to ‘green’

  • Explore the different options for line styles. Try ‘dash’, ‘dot’ and ‘dashdot’ as entry for the key argument


See also

Have a look at this how-to guide for more information on how to set up a livefigure chart.

Next steps¶

Congratulations on finishing this tutorial on climate chart applications. You should now be able to create a climate chart for a predefined location worldwide and understand how climatologies are calculated in the toolbox.


You might like to look at an example of how the application can be developed further. In this advanced version, the workflow also includes minimum and maximum air temperatures, and results in the following chart:

Next Tutorial

Have a look at the next tutorial on how to create an input user interface.

You are watching: Create a climate graph application — Climate Data Store Toolbox 1.1.5 documentation. Info created by GBee English Center selection and synthesis along with other related topics.