Example for Heavy Rainfall Index

Based on the IntensityDurationFrequencyAnalysis, the HeavyRainIndexAnalysis enables the creation of location-dependent heavy rain indices according to the methods of Schmitt, Mudersbach and also those of Krüger and Pfister. Furthermore, the possibility of creating heavy rain index curves according to the Krüger and Pfister method was included and implemented for the other two methods. Thus, heavy rainfall index curves can be compared with each other. Furthermore, it is possible to assign individual rain events to a heavy rain index using existing rain data.

[24]:
from pathlib import Path

import matplotlib.pyplot as plt
import pandas as pd
from matplotlib.colors import ListedColormap

from idf_analysis.definitions import METHOD, SERIES, COL
from idf_analysis.heavy_rainfall_index import HeavyRainfallIndexAnalyse
from idf_analysis.little_helpers import minutes_readable
from idf_analysis.sww_utils import rain_events, event_duration, agg_events
from idf_analysis import __version__
print(f'{__version__=}')
__version__='0.2.9'
Implemented Methods for the HeavyRainIndexAnalysis:
SCHMITT = ‘Schmitt’
KRUEGER_PFISTER = ‘KruegerPfister’
MUDERSBACH = ‘Mudersbach’
[2]:
hri = HeavyRainfallIndexAnalyse(method=HeavyRainfallIndexAnalyse.METHODS.KRUEGER_PFISTER,
                                series_kind=SERIES.PARTIAL, worksheet=METHOD.KOSTRA, extended_durations=True)
[3]:
cmap = ListedColormap([(1,1,1)] + list(hri.indices_color.values()))

You need to install pyarrow or fastparquet to read and write parquet files.

[4]:
data = pd.read_parquet('ehyd_112086.parquet').squeeze('columns')
[5]:
output_directory = Path('hri_results')
[6]:
[7]:
hri.auto_save_parameters(output_directory / 'idf_parameters.yaml')

Heavy rainfall index-matrix is created with regard to the individual procedures for SRI generation

[21]:
hri.interim_sri_table()
[21]:
Return Period in a 1 2 3 5 10 20 25 30 50 75 100
duration in min
5 1 1 2 2 3 4 4 5 6 6 7
10 1 1 2 2 3 4 4 5 6 6 7
15 1 1 2 2 3 4 4 5 6 6 7
20 1 1 2 2 3 4 4 5 6 6 7
30 1 1 2 2 3 4 4 5 6 6 7
45 1 1 2 2 3 4 4 5 6 6 7
60 1 1 2 2 3 4 4 5 6 6 7
90 1 1 2 2 3 4 4 5 6 6 7
120 1 1 2 2 3 4 4 5 6 6 7
180 1 1 2 2 3 4 4 5 6 6 7
240 1 1 2 2 3 4 4 5 6 6 7
360 1 1 2 2 3 4 4 5 6 6 7
540 1 1 2 2 3 4 4 5 6 6 7
720 1 1 2 2 3 4 4 5 6 6 7
1080 1 1 2 2 3 4 4 5 6 6 7
1440 1 1 2 2 3 4 4 5 6 6 7
2880 1 1 2 2 3 4 4 5 6 6 7
4320 1 1 2 2 3 4 4 5 6 6 7
5760 1 1 2 2 3 4 4 5 6 6 7
7200 1 1 2 2 3 4 4 5 6 6 7
8640 1 1 2 2 3 4 4 5 6 6 7
[9]:
hri.interim_sri_table().style.background_gradient(cmap=cmap, vmin=1, vmax=12)
[9]:
Return Period in a 1 2 3 5 10 20 25 30 50 75 100
duration in min                      
5 0 0 0 0 1 1 1 1 1 1 1
10 0 0 0 1 1 1 1 1 2 2 2
15 0 0 0 1 1 1 2 2 2 2 3
20 0 0 1 1 1 2 2 2 2 3 3
30 0 0 1 1 1 2 2 2 3 3 4
45 0 1 1 1 2 2 3 3 4 4 5
60 0 1 1 1 2 3 3 3 4 5 5
90 0 1 1 1 2 3 3 3 4 5 5
120 0 1 1 1 2 3 3 4 4 5 6
180 0 1 1 1 2 3 4 4 5 5 6
240 0 1 1 2 2 3 4 4 5 6 6
360 0 1 1 2 3 4 4 4 5 6 7
540 0 1 1 2 3 4 4 5 6 6 7
720 0 1 1 2 3 4 4 5 6 7 7
1080 0 1 1 2 3 4 5 5 6 7 8
1440 0 1 2 2 3 4 5 5 6 7 8
2880 1 1 2 2 4 5 5 6 7 8 8
4320 1 1 2 3 4 5 6 6 8 9 10
5760 1 1 2 3 4 6 7 7 9 10 11
7200 1 2 2 3 5 7 7 8 9 11 12
8640 1 2 2 3 5 7 8 8 10 12 12

An auxiliary table must be generated for the creation of the heavy rain index-curves. Here, the rainfall heights are shown depending on the duration and the heavy rain index.

[10]:
hri.result_sri_table().style.background_gradient(cmap=cmap, vmin=0, vmax=700).format("{:.1f}")
[10]:
SRI 1 2 3 4 5 6 7 8 9 10 11 12
duration in min                        
5 18.8 26.6 32.5 37.6 42.0 46.0 49.7 53.1 56.4 59.4 62.3 65.1
10 23.2 32.8 40.2 46.4 51.9 56.8 61.4 65.6 69.6 73.4 77.0 80.4
15 26.0 36.7 45.0 52.0 58.1 63.7 68.8 73.5 78.0 82.2 86.2 90.0
20 28.0 39.6 48.5 56.0 62.6 68.6 74.1 79.2 84.0 88.6 92.9 97.0
30 30.9 43.7 53.5 61.8 69.1 75.7 81.8 87.4 92.7 97.7 102.5 107.0
45 33.9 47.9 58.7 67.7 75.7 83.0 89.6 95.8 101.6 107.1 112.3 117.3
60 36.0 51.0 62.4 72.1 80.6 88.3 95.3 101.9 108.1 113.9 119.5 124.8
90 37.1 52.5 64.3 74.3 83.0 91.0 98.3 105.0 111.4 117.4 123.2 128.6
120 37.9 53.7 65.7 75.9 84.8 92.9 100.4 107.3 113.8 120.0 125.8 131.4
180 39.1 55.3 67.7 78.2 87.5 95.8 103.5 110.6 117.3 123.7 129.7 135.5
240 40.0 56.5 69.2 79.9 89.4 97.9 105.7 113.0 119.9 126.4 132.5 138.4
360 41.2 58.3 71.4 82.4 92.1 100.9 109.0 116.5 123.6 130.3 136.6 142.7
540 42.5 60.1 73.6 84.9 95.0 104.0 112.4 120.1 127.4 134.3 140.9 147.1
720 43.4 61.4 75.2 86.8 97.1 106.3 114.8 122.8 130.2 137.3 144.0 150.4
1080 43.8 61.9 75.8 87.6 97.9 107.3 115.8 123.8 131.4 138.5 145.2 151.7
1440 44.1 62.3 76.3 88.1 98.5 107.9 116.6 124.6 132.2 139.3 146.2 152.6
2880 46.3 65.4 80.1 92.5 103.4 113.3 122.4 130.8 138.8 146.3 153.4 160.2
4320 49.7 70.3 86.1 99.5 111.2 121.8 131.6 140.7 149.2 157.3 164.9 172.3
5760 53.4 75.6 92.6 106.9 119.5 130.9 141.4 151.2 160.3 169.0 177.3 185.1
7200 55.1 77.9 95.4 110.2 123.2 135.0 145.8 155.8 165.3 174.2 182.7 190.9
8640 56.8 80.3 98.4 113.6 127.0 139.1 150.3 160.7 170.4 179.6 188.4 196.8

Using heavy rainfall index curves, the necessary rainfall heights can be read off depending on the respective index.

[22]:
hri.method = hri.METHODS.KRUEGER_PFISTER
fig, ax = hri.result_sri_figure()
ax.legend(loc='upper left')
ax.grid(color='grey', linestyle=':', linewidth=0.3)
ax.set_ylim(0, 230)
old_labels = ax.get_xticklabels()
old_labels[2] = ''
old_labels[5] = ''
old_labels[19] = ''
ax.set_xticklabels(old_labels, rotation=90)
handles, labels = ax.get_legend_handles_labels()
ax.legend(handles[::-1], labels[::-1], title='SRI', loc='upper left')
plt.savefig(output_directory / "kruegerpfister.svg")
../_images/examples_example_heavy_rainfall_index_17_0.png

Heavy rain index allocation of a specific rain event

[12]:
events = rain_events(hri.series, min_gap=pd.Timedelta(days=2))
events[COL.DUR] = event_duration(events)
events[COL.LP] = agg_events(events, hri.series, 'sum').round(1)
events[COL.LAST] = events[COL.START] - events[COL.END].shift()

hri.add_max_return_periods_to_events(events)

events = events[events[COL.LP] > 10]
events = events[events[COL.MAX_PERIOD] > 2]

events.sort_values(COL.LP)
/Users/markus/PycharmProjects/intensity_duration_frequency_analysis/idf_analysis/idf_class.py:654: FutureWarning: The behavior of DataFrame.idxmax with all-NA values, or any-NA and skipna=False, is deprecated. In a future version this will raise ValueError
  events[COL.MAX_PERIOD_DURATION] = return_periods_frame.loc[datetime_max].idxmax(axis=1, skipna=True).values
[12]:
start end duration rain_sum last_event max_return_period max_return_period_duration
40 2008-07-20 17:43:00 2008-07-21 08:57:00 0 days 15:14:00 28.0 2 days 02:48:00 3.630220 5760.0
36 2008-06-23 19:50:00 2008-06-24 19:48:00 0 days 23:58:00 35.8 2 days 21:52:00 5.087283 15.0
94 2009-08-27 19:52:00 2009-08-29 13:25:00 1 days 17:33:00 55.1 4 days 23:06:00 17.905569 20.0
520 2018-04-15 21:33:00 2018-04-17 05:39:00 1 days 08:06:00 55.9 2 days 18:30:00 2.004036 360.0
86 2009-07-18 08:55:00 2009-07-18 13:19:00 0 days 04:24:00 58.0 2 days 01:56:00 3.917100 240.0
93 2009-08-21 19:49:00 2009-08-22 20:46:00 1 days 00:57:00 64.2 4 days 03:04:00 3.971078 20.0
425 2016-05-30 12:38:00 2016-06-06 12:54:00 7 days 00:16:00 66.4 4 days 17:44:00 5.084535 5.0
95 2009-09-04 00:31:00 2009-09-05 01:32:00 1 days 01:01:00 69.8 5 days 11:06:00 3.212078 1080.0
186 2011-07-27 20:38:00 2011-08-04 07:44:00 7 days 11:06:00 70.5 3 days 05:30:00 11.866560 20.0
383 2015-07-08 11:50:00 2015-07-09 00:25:00 0 days 12:35:00 77.8 8 days 13:53:00 7.104642 720.0
528 2018-06-12 17:00:00 2018-06-13 22:27:00 1 days 05:27:00 85.1 3 days 16:11:00 10.040058 20.0
388 2015-08-16 19:26:00 2015-08-19 23:38:00 3 days 04:12:00 85.5 13 days 18:23:00 2.365394 4320.0
129 2010-06-13 20:35:00 2010-06-25 19:12:00 11 days 22:37:00 99.6 18 days 20:30:00 2.137450 4320.0
323 2014-05-07 16:50:00 2014-05-18 20:02:00 11 days 03:12:00 109.9 4 days 03:31:00 3.486477 5760.0
294 2013-08-24 01:34:00 2013-08-29 08:19:00 5 days 06:45:00 114.1 9 days 12:53:00 4.260903 2880.0
342 2014-09-09 12:34:00 2014-09-16 23:56:00 7 days 11:22:00 114.5 2 days 22:04:00 2.423020 5760.0
39 2008-07-12 22:10:00 2008-07-18 14:55:00 5 days 16:45:00 122.8 2 days 11:12:00 7.432810 120.0
237 2012-07-09 18:49:00 2012-07-16 05:42:00 6 days 10:53:00 123.1 5 days 23:08:00 4.649434 8640.0
433 2016-07-21 22:29:00 2016-07-28 14:13:00 6 days 15:44:00 136.6 5 days 00:05:00 5.938593 8640.0
279 2013-05-02 02:46:00 2013-05-07 21:37:00 5 days 18:51:00 148.2 9 days 05:08:00 40.647772 2880.0
[13]:
hri.add_max_return_periods_to_events(hri.rain_events)
/Users/markus/PycharmProjects/intensity_duration_frequency_analysis/idf_analysis/idf_class.py:654: FutureWarning: The behavior of DataFrame.idxmax with all-NA values, or any-NA and skipna=False, is deprecated. In a future version this will raise ValueError
  events[COL.MAX_PERIOD_DURATION] = return_periods_frame.loc[datetime_max].idxmax(axis=1, skipna=True).values
[14]:
hri.rain_events.sort_values('max_return_period', ascending=False).head()
[14]:
start end duration rain_sum last_event max_return_period max_return_period_duration
773 2013-05-07 20:58:00 2013-05-07 21:37:00 0 days 00:40:00 2.0 0 days 08:18:00 40.647772 2880.0
772 2013-05-05 20:47:00 2013-05-07 12:40:00 1 days 15:54:00 119.5 0 days 17:31:00 38.092568 2880.0
282 2009-08-28 23:41:00 2009-08-29 00:42:00 0 days 01:02:00 49.3 1 days 03:44:00 17.905569 20.0
544 2011-08-03 19:53:00 2011-08-04 07:44:00 0 days 11:52:00 54.7 1 days 23:11:00 11.866560 20.0
1532 2018-06-13 14:58:00 2018-06-13 22:27:00 0 days 07:30:00 63.5 0 days 21:27:00 10.040058 20.0
[15]:
event = hri.rain_events.loc[797].copy()

event[COL.START] = pd.to_datetime('2013-05-06 20:00:00')
event
[15]:
start                         2013-05-06 20:00:00
end                           2013-06-22 15:59:00
duration                          0 days 01:00:00
rain_sum                                      1.6
last_event                        6 days 13:51:00
max_return_period                        0.078798
max_return_period_duration                   60.0
Name: 797, dtype: object
[16]:
rainfall_sum_frame = hri.rainfall_sum_frame[event[COL.START]:event[COL.END]]
return_periods_frame = hri.return_periods_frame[event[COL.START]:event[COL.END]]
[17]:
rainfall_sum_frame.\
    max().\
    rename('max. Regensumme').\
    to_frame().\
    rename(minutes_readable).\
    style.bar(vmin=0, vmax=100).format("{:.1f}")
[17]:
  max. Regensumme
5 min 9.9
10 min 16.3
15 min 21.9
20 min 28.2
30 min 40.7
45 min 46.3
60 min 57.0
1.5 h 69.6
2 h 74.3
3 h 76.5
4 h 78.7
6 h 89.6
9 h 92.8
12 h 93.0
18 h 96.4
1 d 98.2
2 d 120.5
3 d 138.0
4 d 138.0
5 d 143.7
6 d 148.2
[18]:
return_periods_frame.\
    max().\
    rename('max. Wiederkehrperiode').\
    to_frame().\
    rename(minutes_readable).\
    style.bar(vmin=0, vmax=100).format("{:.1f}")
[18]:
  max. Wiederkehrperiode
5 min 1.4
10 min 1.5
15 min 2.0
20 min 3.2
30 min 8.0
45 min 6.8
60 min 11.2
1.5 h 23.7
2 h 26.9
3 h 22.0
4 h 20.0
6 h 30.2
9 h 25.3
12 h 19.5
18 h 20.2
1 d 19.3
2 d 40.7
3 d 39.8
4 d 16.2
5 d 14.0
6 d 12.5
[19]:
sri_table_event = pd.DataFrame(index=hri.duration_steps)

hri.method = hri.METHODS.KRUEGER_PFISTER
sri_table_event[hri.METHODS.KRUEGER_PFISTER] = hri.get_event_sri_max(event[COL.START], event[COL.END])

hri.method = hri.METHODS.MUDERSBACH
sri_table_event[hri.METHODS.MUDERSBACH] = hri.get_event_sri_max(event[COL.START], event[COL.END])

hri.method = hri.METHODS.SCHMITT
sri_table_event[hri.METHODS.SCHMITT] = hri.get_event_sri_max(event[COL.START], event[COL.END])

Specific rain event with allocation of heavy rain indices depending on the method and duration.

[20]:
cmap = ListedColormap([(1,1,1)] + list(hri.indices_color.values()))
_df = sri_table_event.astype(int).copy()
_df['max. Wiederkehrperiode'] = return_periods_frame.max()
_df['max. Regensumme'] = rainfall_sum_frame.max()
_df.rename(minutes_readable).style.\
    background_gradient(subset=[hri.METHODS.SCHMITT,
                                hri.METHODS.KRUEGER_PFISTER,
                                hri.METHODS.MUDERSBACH], cmap=cmap, vmin=0, vmax=12).\
    bar(subset=['max. Wiederkehrperiode', 'max. Regensumme'], vmin=0, vmax=100).format("{:.1f}", subset=['max. Wiederkehrperiode', 'max. Regensumme'])
[20]:
  KruegerPfister Mudersbach Schmitt max. Wiederkehrperiode max. Regensumme
5 min 1 1 1 1.4 9.9
10 min 1 2 1 1.5 16.3
15 min 1 2 1 2.0 21.9
20 min 1 3 2 3.2 28.2
30 min 2 4 3 8.0 40.7
45 min 2 4 3 6.8 46.3
60 min 2 5 4 11.2 57.0
1.5 h 4 7 4 23.7 69.6
2 h 4 7 5 26.9 74.3
3 h 4 7 4 22.0 76.5
4 h 4 7 4 20.0 78.7
6 h 5 7 6 30.2 89.6
9 h 5 7 5 25.3 92.8
12 h 4 7 4 19.5 93.0
18 h 5 7 4 20.2 96.4
1 d 5 7 4 19.3 98.2
2 d 7 9 6 40.7 120.5
3 d 8 9 6 39.8 138.0
4 d 6 8 4 16.2 138.0
5 d 6 8 4 14.0 143.7
6 d 6 7 4 12.5 148.2