Plotting Precipitation Overview Maps

Here, we combine several aspects explored in the previous notebooks. We will

  • read the ICON grid file

  • read multiple ICON 2D data file and extract information on precipitation and

  • finally combine all precipitation fields to a multi-panel plot

Load Python Libraries

[1]:
%matplotlib inline

# system libs
import os, sys, glob

# array operators and netcdf datasets
import numpy as np
import xarray as xr
import datetime

# plotting
import pylab as plt
import seaborn as sns
sns.set_context('talk')

# drawing onto a map
import cartopy.crs as ccrs
import cartopy.feature as cfeature
import cartopy.io.shapereader as shpreader

As mentioned in the notebook 03-Plottting_Precipitation_as_Time_Series.ipynb, here we will import our tools module. The imported function convert_timevec will handle the time axis in the ICON data.

[2]:
sys.path.append( '/work/bb1224/2023_MS-COURSE/tools/analysis' )
from tools import convert_timevec

Open Data with xarray

General Paths

[3]:
exercise_path = '/work/bb1224/2023_MS-COURSE'
data_path = f'{exercise_path}/data'
icon_data_path = f'{data_path}/icon-lem'

This is the content of the data directory:

[4]:
os.listdir(icon_data_path)
[4]:
['grids-extpar', 'experiments', 'bc-init']
[5]:
grid_name = 'lpz_r2'
grid_path = f'{icon_data_path}/grids-extpar/{grid_name}'
[6]:
exp_name = 'icon_lam_1dom_lpz-base'
exp_path = f'{icon_data_path}/experiments/{exp_name}'

Grid File

[7]:
grid1 = xr.open_dataset( f'{grid_path}/lpz_r2_dom01_DOM01.nc', chunks={} )
# grid1 = xr.open_dataset( f'{grid_path}/lpz_r2_dom02_DOM02.nc', chunks={} )

Data Files

Again, we use the xarrayfunction open_mfdataset to read in multiple ICON datasets. The data are not load into memory, but handled as pointers.

[8]:
dset = xr.open_mfdataset( f'{exp_path}/2d_cloud_DOM01_ML_20210516T*Z.nc', chunks={'time':1}, combine='by_coords' )
# dset = xr.open_mfdataset( f'{exp_path}/2d_cloud_DOM02_ML_20210516T*.nc', chunks={'time':1}, combine='by_coords' )
[9]:
dset['time'] = convert_timevec( dset.time.data )
[10]:
dset
[10]:
<xarray.Dataset>
Dimensions:        (time: 288, plev: 1, bnds: 2, plev_2: 1, plev_3: 1,
                    ncells: 10212)
Coordinates:
  * time           (time) datetime64[ns] 2021-05-16 ... 2021-05-16T23:55:00
  * plev           (plev) float64 0.0
  * plev_2         (plev_2) float64 400.0
  * plev_3         (plev_3) float64 800.0
Dimensions without coordinates: bnds, ncells
Data variables: (12/17)
    plev_bnds      (time, plev, bnds) float64 dask.array<chunksize=(12, 1, 2), meta=np.ndarray>
    plev_2_bnds    (time, plev_2, bnds) float64 dask.array<chunksize=(12, 1, 2), meta=np.ndarray>
    plev_3_bnds    (time, plev_3, bnds) float64 dask.array<chunksize=(12, 1, 2), meta=np.ndarray>
    tqv_dia        (time, ncells) float32 dask.array<chunksize=(1, 10212), meta=np.ndarray>
    tqc_dia        (time, ncells) float32 dask.array<chunksize=(1, 10212), meta=np.ndarray>
    tqi_dia        (time, ncells) float32 dask.array<chunksize=(1, 10212), meta=np.ndarray>
    ...             ...
    cape           (time, ncells) float32 dask.array<chunksize=(1, 10212), meta=np.ndarray>
    cape_ml        (time, ncells) float32 dask.array<chunksize=(1, 10212), meta=np.ndarray>
    cin_ml         (time, ncells) float32 dask.array<chunksize=(1, 10212), meta=np.ndarray>
    rain_con_rate  (time, ncells) float32 dask.array<chunksize=(1, 10212), meta=np.ndarray>
    prec_con       (time, ncells) float32 dask.array<chunksize=(1, 10212), meta=np.ndarray>
    prec_gsp       (time, ncells) float32 dask.array<chunksize=(1, 10212), meta=np.ndarray>
Attributes:
    CDI:                  Climate Data Interface version 1.8.4 (http://mpimet...
    Conventions:          CF-1.6
    number_of_grid_used:  99
    uuidOfHGrid:          718d4bb6-2c67-4c84-a5ab-440d28412a00
    institution:          Max Planck Institute for Meteorology/Deutscher Wett...
    title:                ICON simulation
    source:               @
    history:              /home/k/k206107/workspace/icon-build/bin/icon at 20...
    references:           see MPIM/DWD publications
    comment:              v107 Workshop (k206107) on l30004 (Linux 4.18.0-348...

Prepare Precip Data

Again, we need to combine grid-scale and subgrid-scale contributions to precipitation.

  • Do you understand why we have two parts?

  • Which model parameterization is responsible for which part?

[11]:
rain = dset['rain_con_rate'] + dset['rain_gsp_rate']
rain.attrs['long_name'] = 'rain rate'
[12]:
conversion_factor = 3600 * 24
[13]:
rain = conversion_factor * rain
rain.attrs['units'] = 'mm day-1'
[14]:
rain
[14]:
<xarray.DataArray (time: 288, ncells: 10212)>
dask.array<mul, shape=(288, 10212), dtype=float64, chunksize=(1, 10212), chunktype=numpy.ndarray>
Coordinates:
  * time     (time) datetime64[ns] 2021-05-16 ... 2021-05-16T23:55:00
Dimensions without coordinates: ncells
Attributes:
    units:    mm day-1

Plotting Precip Maps

Shortcuts for Fieldnames

[15]:
# read center lon/lat in radiant
clon_rad = grid1['clon']                # center longitude  / rad
clat_rad = grid1['clat']                # center latitutde  / rad

# convert to degrees
clon = np.rad2deg( clon_rad )
clat = np.rad2deg( clat_rad )

# select a subset, each 12th time slot
rr  = rain.isel( time = slice(0, None, 12) )

Plotting Precip onto a Map

The map plotting is borrowed from the notebook 01-Plotting-ICON-Topography.ipynb.

Define States

[16]:
# read shape file
shape_file = f'{data_path}/shapes/vg2500_bld.shp'
reader = shpreader.Reader( shape_file )

#  and create cartopy feature
states_data = list(reader.geometries())
states = cfeature.ShapelyFeature(states_data, ccrs.PlateCarree())


Make a Multi-Panel Plot

[17]:
fig = plt.figure( figsize = (20,20) )
plt.subplots_adjust( wspace = 0.05, hspace = 0.1) # it looks nicer if spaces between subpanels are smaller

rr_values = [0, 0.1, 0.5, 1, 2, 5, 8, 10, 15, 20, 30, 50]
norm = plt.matplotlib.colors.BoundaryNorm(boundaries = rr_values, ncolors = 256, )

for i in range( 24 ):

    ax = plt.subplot(6,4,i+1, projection = ccrs.PlateCarree() )
    ax.add_feature(cfeature.LAND, facecolor='lightgray')

    v =  rr.isel( time = i )
    plt.tricontourf( clon, clat, v,
                     levels = rr_values,
                     cmap = plt.cm.CMRmap_r,
                     norm = norm,
                     extend = 'both'
                   )
    # and here we draw country borders
    ax.add_feature(cfeature.BORDERS.with_scale('50m'), linewidth = 2)
    ax.add_feature(states, facecolor='none', edgecolor='black', linewidth = 0.4)

    # write time as string in the corner
    t = v.time.data.astype('datetime64[m]')
    date, time  = str( t ).split('T')
    ax.text( 14.8, 53.3, time[:5])
../_images/nbooks_04-Plotting_Precipitation_Overview_Maps_34_0.png

How do the plots look like if you choose a different matplotlib colormap (see here: https://matplotlib.org/stable/tutorials/colors/colormaps.html )?

A “nice” Colormap from blue to red

[18]:
cmap_new =  plt.matplotlib.colors.LinearSegmentedColormap.from_list('rr_colors',
                                        ['white', '#1ca8e9','#097cc4', '#095389',
                                         'forestgreen','yellowgreen',  'gold','orangered',
                                         'brown', 'black'], gamma = 1.)
[19]:
fig = plt.figure( figsize = (16,2) )
plt.subplots_adjust( wspace = 0.05, hspace = 0.1) # it looks nicer if spaces between subpanels are smaller

rr_values = [0, 0.1, 0.5, 1, 2, 5, 8, 10, 15, 20, 30, 50]
norm = plt.matplotlib.colors.BoundaryNorm(boundaries = rr_values, ncolors = 256, )

for i in range( 24 ):

    ax = plt.subplot(2,12,i+1, projection = ccrs.PlateCarree() )
    ax.add_feature(cfeature.LAND, facecolor='lightgray')


    plt.tricontourf( clon, clat, rr.isel( time = i ),
                     levels = rr_values,
                     cmap = cmap_new,
                     extend = 'both',
                     norm = norm
                    )


    # and here we draw country borders
    ax.add_feature(cfeature.BORDERS.with_scale('50m'), linewidth = 2)
    ax.add_feature(states, facecolor='none', edgecolor='black', linewidth = 0.4)
../_images/nbooks_04-Plotting_Precipitation_Overview_Maps_38_0.png

Accumulated Rain

Calculating the rain accumulation is easy! We already have rain in mm day-1 and the output frequency is regular. So, we just take the average a get the average rain in mm day-1.

[20]:
fig = plt.figure( figsize = (12,6) )
plt.subplots_adjust( wspace = 0.05, hspace = 0.1) # it looks nicer if spaces between subpanels are smaller

rr_values = [0, 0.1, 0.5, 1, 2, 5, 8, 10, 15, 20, 30, 50]
norm = plt.matplotlib.colors.BoundaryNorm(boundaries = rr_values, ncolors = 256, )

rain_accu = rain.mean('time').compute()

ax = plt.subplot(1,1,1, projection = ccrs.PlateCarree() )
ax.add_feature(cfeature.LAND, facecolor='lightgray')


plt.tricontourf( clon, clat, rain_accu,
                     levels = rr_values,
                     cmap = cmap_new,
                     extend = 'both',
                     norm = norm
                    )
plt.colorbar()

# and here we draw country borders
ax.add_feature(cfeature.BORDERS.with_scale('50m'), linewidth = 2)
ax.add_feature(states, facecolor='none', edgecolor='black', linewidth = 0.4)
[20]:
<cartopy.mpl.feature_artist.FeatureArtist at 0x7fff8f5a2800>
../_images/nbooks_04-Plotting_Precipitation_Overview_Maps_41_1.png

Tasks

Please explore the data with this notebook:

  • Check how the temporal evolution looks like for

    • total cloud cover, variable name clct

    • liquid water path, variable name: tqc_dia

    • ice water path, variable name: tqi_dia