Compute DCSC’s TXND: the number of unusually hot days#
Example notebook that runs icclim.
The example calculates the number of unusually hot days (TXND indicator from DCSC) for the dataset chosen by the user on C4I.
./data/latest folder for model CMCC and for one member r1i1p1f1..metalink file can be downloaded with tools such as aria2 or a browser plugin such as DownThemAll! If you wish to use a different dataset, you can use the climate 4 impact portal to search and select the data you wish to use and a metalink file to the ESGF data will be provided.The data is read using xarray and a plot of the time series over a specific region is generated, as well as an average spatial map. Several output types examples are shown.
To keep this example fast to run, the following period is considered: 2015-01-01 to 2019-12-31, and plots are shown over European region.
Installation and preparation of the needed modules#
[ ]:
from pathlib import Path
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
import numpy as np
import xarray as xr
from xclim.core.calendar import select_time
import icclim
from icclim.frequency import FrequencyRegistry
Specification of the parameters#
[ ]:
DATA_DIR = Path("./data/latest")
out_f = "output/DCSC_tynn/txnd_icclim.nc"
[ ]:
historical_files = [str(f) for f in DATA_DIR.glob("tas*CMCC*historical*.nc")]
sorted(historical_files)
[ ]:
studied_files = [str(f) for f in DATA_DIR.glob("tas*CMCC*ssp585*.nc")]
sorted(studied_files)
Build NormaL#
normal, from April to September included.lat, lon couple, the values will be the mean of temperature of the summers within the reference periode.select_time to filter the summer months.ℹ️ Alternatively, the normal can be saved in a netCDF file and the path to this file can be used in
normalparameter oficclim.dcsc.txndfunction.
[ ]:
historical_tas = xr.open_mfdataset(historical_files).tas
filtered_tas = select_time(
historical_tas, month=FrequencyRegistry.AMJJAS.indexer["month"], drop=True
)
normal = filtered_tas.mean(dim="time", keep_attrs=True)
normal
Compute TXND index#
Usually TXND is computed on the maximum daily temperature (tasmax), but here we show that using var_name we can force icclim to use a different variable to compute indices, as long as its units is compatible.
[ ]:
icclim.dcsc.txnd(
in_files=studied_files[0:1],
normal=normal,
var_name="tas",
slice_mode=FrequencyRegistry.AMJJAS,
out_file=out_f,
logs_verbosity="SILENT",
)
Plot settings#
[ ]:
txnd_dataset = xr.open_dataset(out_f)
txnd_dataset
[ ]:
txnd = txnd_dataset.TXND
txnd
[ ]:
# Select a single x,y combination from the data
longitude = txnd_dataset.TXND["lon"].sel(lon=3.5, method="nearest")
latitude = txnd_dataset.TXND["lat"].sel(lat=44.2, method="nearest")
[ ]:
txnd_dataset.attrs["title"]
ℹ️ Notice that the title is not quite right in the resulting dataset.TXND assumes to be computed on tasmax, so its output title includesmaximum_air_temperaturebut here we used aair_temperaturevariable.
Subset and Plot TXND#
[ ]:
# Slice the data spatially using a single lat/lon point
one_point = txnd.sel(lat=latitude, lon=longitude)
# Use xarray to create a quick time series plot
one_point.plot.line()
plt.show()
[ ]:
# You can clean up your plot as you wish using standard matplotlib approaches
f, ax = plt.subplots(figsize=(12, 6))
one_point.plot.line(
hue="lat",
marker="o",
ax=ax,
color="grey",
markerfacecolor="purple",
markeredgecolor="purple",
)
ax.set(title="Time Series For a Single Lat / Lon Location")
plt.show()
[ ]:
# Convert to dataframe -- then this can easily be exported to a csv
one_point_df = one_point.to_dataframe()
# View just the first 5 rows of the data
one_point_df.head()
# Export data to .csv file
[ ]:
# Time subsetting: this is just an example on how to do it
start_date = "2050-01-01"
end_date = "2100-12-31"
txnd_filtered = txnd.sel(time=slice(start_date, end_date))
[ ]:
# Quickly plot the data using xarray.plot()
txnd_filtered.plot(x="lon", y="lat", col="time", col_wrap=5)
plt.suptitle("Last ten years of TXND", y=1.03)
plt.show()
[ ]:
# Set spatial extent and centre
central_lat = 47.0
central_lon = 1.0
extent = [-30, 30, 30, 56] # Western Europe
# Calculate time average
txnd_avg = txnd.mean(dim="time", keep_attrs=True)
# Set plot projection
map_proj = ccrs.AlbersEqualArea(
central_longitude=central_lon, central_latitude=central_lat
)
# Define plot
f, ax = plt.subplots(figsize=(14, 6), subplot_kw={"projection": map_proj})
# Plot data with proper colormap scale range
levels = np.arange(0, 90, 5)
p = txnd_avg.plot(levels=levels, cmap="RdBu_r", transform=ccrs.PlateCarree())
# Plot information
plt.suptitle("Two Time Steps of Europe Summer Days", y=1)
# Add the coastlines to axis and set extent
ax.coastlines()
ax.gridlines()
ax.set_extent(extent)
# Save plot as png
plt.savefig("txnd_avg_icclim.png")
[ ]:
# Re-order longitude so that there is no blank line at 0 deg because 0 deg is within our spatial selection
txnd_avg.coords["lon"] = (txnd_avg.coords["lon"] + 180) % 360 - 180
txnd_avg = txnd_avg.sortby(txnd_avg.lon)
# Define plot
f, ax = plt.subplots(figsize=(14, 6), subplot_kw={"projection": map_proj})
# Define colorscale
levels = np.arange(0, 90, 15)
# Contours lines
p = txnd_avg.plot.contour(
levels=levels, colors="k", linewidths=0.5, transform=ccrs.PlateCarree()
)
# Contour filled colors
p = txnd_avg.plot.contourf(
levels=levels, cmap="RdBu_r", extend="both", transform=ccrs.PlateCarree()
)
# Plot information
plt.suptitle("Two Time Steps of Europe Summer Days", y=1)
# Add the coastlines to axis and set extent
ax.coastlines()
ax.gridlines()
ax.set_extent(extent)
# Save plot as png
plt.savefig("txnd_avg_contours_icclim.png")
[ ]: