==== Plotting with Python ====
This tutorial is the third part of a series that shows how to process climate model data on distributed High Performance Computing (HPC) environments with state of the art python libraries. Visit the [[analysis:postprocessing_icon:regridding:python:start|**Part 2**]] and [[analysis:postprocessing_icon:1._open_read:python:start|**Part 1**]] to see how to read and remap the data.
In this tutorial we are going to plot the data that has been processed previously. Like in any other tutorial lets import the libraries we are going to use first using the //python 3 unstable// kernel:
from getpass import getuser # Libaray to copy things
from pathlib import Path # Object oriented libary to deal with paths
from cartopy import crs as ccrs # Cartography library
from matplotlib import pyplot as plt # Standard Plotting library
import numpy as np # Standard array library
import pandas as pd # Libary to work with labeled data frames and time series
import seaborn as sns # Makes plots more beautiful
import xarray as xr # Libary to work with labeled n-dimensional data and dask
In [[analysis:postprocessing_icon:regridding:python:start|**Part 2**]] of this tutorial we remapped the output of global storm resolving model simulations to a regular latitude-longitude grid and save the averages over time and space to file. We are now going to read the saved files and display the content:
scratch_dir = Path('/scratch') / getuser()[0] / getuser() # Define the users scratch dir
out_file = Path(scratch_dir) / 'dpp0016_PreProc.nc'
time_mean = xr.open_dataset(out_file, group='time_mean').load()
field_mean = xr.open_dataset(out_file, group='field_mean').load()
time_mean
Dimensions: (lat: 1800, lon: 3600)
Coordinates:
* lon (lon) float64 -179.9 -179.8 -179.8 -179.6 ... 179.8 179.9 180.0
* lat (lat) float64 -89.95 -89.85 -89.75 -89.65 ... 89.75 89.85 89.95
Data variables:
ts (lat, lon) float32 221.04167 221.04166 ... 257.14673 257.14676
rsus (lat, lon) float32 55.74567 55.745674 ... 56.61574 56.615986
rlus (lat, lon) float32 136.61485 136.6148 ... 253.50243 253.50249
rlds (lat, lon) float32 108.62206 108.622185 ... 232.81358 232.81357
rsds (lat, lon) float32 69.93069 69.930695 69.9307 ... 84.0771 84.07749
hfls (lat, lon) float32 0.0656544 0.06563331 ... -6.8061843 -6.806321
hfss (lat, lon) float32 10.846811 10.845357 ... 0.60061556 0.60098815
Attributes:
CDI: Climate Data Interface version 1.8.3rc (http://mpim...
Conventions: CF-1.6
number_of_grid_used: 15
grid_file_uri: http://icon-downloads.mpimet.mpg.de/grids/public/mp...
uuidOfHGrid: 0f1e7d66-637e-11e8-913b-51232bb4d8f9
title: ICON simulation
institution: Max Planck Institute for Meteorology/Deutscher Wett...
source: git@gitlab.dkrz.de:icon/icon-aes.git@b582fb87edbd30...
history: /work/mh0287/k203123/GIT/icon-aes-dyw_albW/bin/icon...
references: see MPIM/DWD publications
comment: Sapphire Dyamond (k203123) on m21322 (Linux 2.6.32-...
field_mean
Dimensions: (time: 304)
Coordinates:
* time (time) datetime64[ns] 2020-02-01 2020-02-02 ... 2020-11-30
Data variables:
ts (time) float32 286.06442 285.98172 ... 287.01483 287.09506
rsus (time) float32 35.026955 35.132553 ... 38.266792 37.940987
rlus (time) float32 387.74957 387.44562 ... 392.57364 392.88156
rlds (time) float32 335.21866 334.84085 334.0962 ... 340.49408 341.90875
rsds (time) float32 200.44205 200.92815 ... 202.39125 201.83057
hfls (time) float32 -76.36643 -77.96001 ... -89.82848 -84.05612
hfss (time) float32 -22.51513 -23.409267 ... -24.214497 -22.375736
Attributes:
CDI: Climate Data Interface version 1.8.3rc (http://mpim...
Conventions: CF-1.6
number_of_grid_used: 15
grid_file_uri: http://icon-downloads.mpimet.mpg.de/grids/public/mp...
uuidOfHGrid: 0f1e7d66-637e-11e8-913b-51232bb4d8f9
title: ICON simulation
institution: Max Planck Institute for Meteorology/Deutscher Wett...
source: git@gitlab.dkrz.de:icon/icon-aes.git@b582fb87edbd30...
history: /work/mh0287/k203123/GIT/icon-aes-dyw_albW/bin/icon...
references: see MPIM/DWD publications
comment: Sapphire Dyamond (k203123) on m21322 (Linux 2.6.32-...
xarray has a powerful plot functionality that can be used to quickly plot and inspect the data:
time_mean['ts'].plot()
{{ :analysis:postprocessing_icon:3.plottting:python:map_1.png?600 |}}
These plots are not very nice but we can make them much nicer by using cartopy to draw maps. Xarray supports subplots and fiddeling with the colorbar. Let's create a nicer plot of net surface energy using the cartopy library. Net surface energy is defined as the sum of net surface radiation, latent and surface heat fluxes:
time_mean['surf_energy'] = (time_mean['rsds'] - time_mean['rsus']) \
+ (time_mean['rlds'] - time_mean['rlus']) \
+ (time_mean['hfls'] + time_mean['hfss'])
proj = ccrs.Mollweide(50.) # Create Mollweide projections
fig = plt.figure(figsize=(12, 8))
ax = fig.add_subplot(111, projection=proj)
plot = time_mean['surf_energy'].plot(
ax=ax,
transform=ccrs.PlateCarree(),
cmap='RdYlBu_r',
vmin=-120,
vmax=120,
cbar_kwargs={'label': 'Net Surface Energy [W/m$^2$]',
'extend': 'both',
'shrink': .8,
'orientation': 'horizontal'},
)
ax.coastlines(resolution='10m', lw=0.51)
ax.set_title(f'Net Surface Energy Feb. 2020 - Nov. 2020')
_ = fig.subplots_adjust(left=0.01, right=0.98, hspace=0, wspace=0, top=0.9, bottom=0.25)
{{ :analysis:postprocessing_icon:3.plottting:python:map_2.png?800 |}}
Time series plots can be done in a similar fashion:
field_mean['ts'].plot()
[]
{{ :analysis:postprocessing_icon:3.plottting:python:series_1.png?400 |}}
Let's make this plot a little more pretty. The Seaborn library provides a nice interface for that:
col_blind = sns.color_palette("colorblind", 10)
sns.set_style('ticks')
sns.set_palette(col_blind)
sns.set_context("notebook", font_scale=1., rc={"lines.linewidth": 3.5})
Now let's create two plots showing the time series and zonal averages next to each other:
fig, axs = plt.subplots(1, 2,figsize=(12, 6), sharey=False)
_ = (field_mean['ts'] - 273.15).plot.line(x='time', ax=axs[0], add_legend=False)
axs[0].set_ylabel('Surface Temperature [$^\\circ$C]')
_ = (time_mean['ts']-273.15).mean(dim='lon').plot.line(x='lat', ax=axs[1])
axs[-1].set_ylabel('')
axs[-1].set_xlabel('Latitude [$^\\circ$N]')
fig.suptitle('Surface temperature Feb 2020 - Nov 2020')
fig.subplots_adjust(left=0.1, right=0.99, wspace=0.2, top=.95, bottom=0.3)
sns.despine()
{{ :analysis:postprocessing_icon:3.plottting:python:series_2.png?800 |}}