[1]:
from pathlib import Path
import pandas as pd
from idf_analysis.idf_class import IntensityDurationFrequencyAnalyse
from idf_analysis.definitions import *
from idf_analysis import __version__
print(f'{__version__=}')
__version__='0.3.1'
[2]:
%matplotlib inline
%load_ext autoreload
%autoreload 2

Intensity Duration Frequency Analyse

Parameter

series_kind:

SERIES.PARTIAL = Partielle Serie (partial duration series, PDS) (peak over threshold, POT)

SERIES.ANNUAL = Jährliche Serie (annual maximum series, AMS)

worksheet:

METHOD.KOSTRA:

  • DWA-A 531

  • KOSTRA - recommented

  • Parameter formula change at 60 min and 12 h

METHOD.CONVECTIVE_ADVECTIVE:

  • DWA-A 531

  • Unterscheidung in überwiegend konvektiv und advektiv verursachte Starkregen

  • Parameter formula change at 3 h and 24 h

METHOD.ATV:

  • ATV-A 121

  • Parameter formula change at 3 h and 48 h

extended_durations = Includes the durations steps [0.75d, 1d, 2d, 3d, 4d, 5d, 6d] in the analysis (d=days)

Default duration steps [5m, 10m, 15m, 20m, 30m, 45m, 60m, 1.5h, 3h, 4.5h, 6h, 7.5h, 10h, 12h]

[3]:
idf = IntensityDurationFrequencyAnalyse(series_kind=SERIES.ANNUAL, worksheet=METHOD.DWA_2025, extended_durations=True)

The data used for this calculation is a timeseries of precipitation observations. The data can be passed in mm or inch. The series should contain measured volumes and not intensities. The intervall of the series can be chosen freely, but should ideally be already time equidistant. But the results will only show duration steps that are greater or equal to the intervall.

I used the rain-time-series from ehyd.gv.at with the ID 112086 (Graz-Andritz) created with the ehyd-tools package.

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

[4]:
data = pd.read_parquet('ehyd_112086.parquet').squeeze('columns')

Get a look at the time-series

[5]:
data.head()
[5]:
datetime
2007-09-17 13:56:00    0.0
2007-09-17 13:57:00    0.0
2007-09-17 13:58:00    0.0
2007-09-17 13:59:00    0.0
2007-09-17 14:00:00    0.0
Name: N-Minutensummen-112086, dtype: float64
[6]:
data.tail()
[6]:
datetime
2019-12-31 23:56:00    0.0
2019-12-31 23:57:00    0.0
2019-12-31 23:58:00    0.0
2019-12-31 23:59:00    0.0
2020-01-01 00:00:00    NaN
Name: N-Minutensummen-112086, dtype: float64

Set the time-series to be used for the calculation of the IDF parameters

[7]:

define a working directory to save some plots and interim results

[8]:
output_directory = Path('ehyd_112086_idf_data_new')

Intermediate results are created for each new calculation, which are only dependent on the selected series series_kind and the specified/required duration steps. This process takes a few seconds. In addition, these intermediate results contain the parameters required to calculate the rainfall height. The calculation methods and formula-change-durations according to the selected worksheet are already taken into account here.

[9]:
idf.write_parameters(output_directory / 'idf_parameters.yaml')
/Users/markus/PycharmProjects/.venv12/lib/python3.12/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html
  from .autonotebook import tqdm as notebook_tqdm
Calculating Intensities for duration 8640: 100%|██████████| 21/21 [00:05<00:00,  4.00it/s]

To save time, it is possible to save the parameters temporarily and when the script is called up again, these parameters are no longer calculated but read from the file.

[10]:
idf.auto_save_parameters(output_directory / 'idf_parameters.yaml')

These interim results can be called up with:

[13]:
idf.parameters._parameter_values
[13]:
{'eta': 0.8170122825106468,
 'loc': 14.050191266395858,
 'scale': 4.780466857553214,
 'shape': -0.1,
 'theta': 8.318942091673822}
[14]:
<idf_analysis.idf_backend_2025.IdfParametersNew at 0x130a2e1e0>

plot the interim results for the final parameters of the function to calculate the rainfall height depending on duration and return periods.

Calculations

[16]:
idf.depth_of_rainfall(duration=15, return_period=1)
WARNING: Using an annual series and a return period < 5 a will result in faulty values!
[16]:
np.float64(16.081944945454794)
[17]:
print('Resulting rainfall height h_N(T_n={t:0.1f}a, D={d:0.1f}min) = {h:0.2f} mm'
      ''.format(t=1, d=15, h=idf.depth_of_rainfall(15, 1)))
WARNING: Using an annual series and a return period < 5 a will result in faulty values!
Resulting rainfall height h_N(T_n=1.0a, D=15.0min) = 16.08 mm
[18]:
idf.rain_flow_rate(duration=15, return_period=1)
WARNING: Using an annual series and a return period < 5 a will result in faulty values!
[18]:
np.float64(178.68827717171993)
[19]:
print('Resulting rainfall flow rate r_N(T_n={t:0.1f}a, D={d:0.1f}min) = {r:0.2f} L/(s*ha)'
      ''.format(t=1, d=15, r=idf.rain_flow_rate(15, 1)))
WARNING: Using an annual series and a return period < 5 a will result in faulty values!
Resulting rainfall flow rate r_N(T_n=1.0a, D=15.0min) = 178.69 L/(s*ha)
[20]:
WARNING: Using an annual series and a return period < 5 a will result in faulty values!
[20]:
np.float64(10.739376745521536)
[21]:
idf.get_return_period(height_of_rainfall=10, duration=15)
[21]:
np.float64(0.30780580092695775)
[22]:
idf.get_duration(height_of_rainfall=10, return_period=1)
WARNING: Using an annual series and a return period < 5 a will result in faulty values!
WARNING: Using an annual series and a return period < 5 a will result in faulty values!
WARNING: Using an annual series and a return period < 5 a will result in faulty values!
WARNING: Using an annual series and a return period < 5 a will result in faulty values!
WARNING: Using an annual series and a return period < 5 a will result in faulty values!
WARNING: Using an annual series and a return period < 5 a will result in faulty values!
WARNING: Using an annual series and a return period < 5 a will result in faulty values!
WARNING: Using an annual series and a return period < 5 a will result in faulty values!
[22]:
np.float64(6.407029064330444)
[23]:
idf.result_table().round(2)
WARNING: Using an annual series and a return period < 5 a will result in faulty values!
WARNING: Using an annual series and a return period < 5 a will result in faulty values!
WARNING: Using an annual series and a return period < 5 a will result in faulty values!
[23]:
1 2 3 5 10 20 25 30 50 75 100
5 8.47 10.54 11.82 13.50 15.93 18.44 19.34 20.08 22.23 24.00 25.31
10 13.06 16.25 18.22 20.82 24.56 28.42 29.80 30.95 34.26 37.00 39.01
15 16.08 20.01 22.44 25.64 30.25 35.01 36.71 38.12 42.20 45.57 48.04
20 18.30 22.76 25.52 29.17 34.41 39.82 41.76 43.37 48.01 51.84 54.66
30 21.44 26.67 29.90 34.17 40.32 46.66 48.93 50.81 56.24 60.74 64.04
45 24.55 30.54 34.25 39.13 46.17 53.43 56.03 58.19 64.41 69.56 73.33
60 26.73 33.26 37.29 42.61 50.28 58.18 61.01 63.36 70.13 75.74 79.85
90 29.78 37.05 41.55 47.47 56.01 64.82 67.97 70.59 78.14 84.38 88.96
120 31.94 39.74 44.56 50.92 60.08 69.53 72.91 75.71 83.81 90.51 95.42
180 35.02 43.57 48.86 55.83 65.88 76.23 79.94 83.01 91.89 99.24 104.62
240 37.25 46.35 51.97 59.38 70.07 81.08 85.02 88.30 97.74 105.56 111.28
360 40.49 50.38 56.49 64.55 76.16 88.13 92.42 95.97 106.24 114.73 120.96
540 43.88 54.59 61.21 69.95 82.53 95.51 100.15 104.01 115.13 124.34 131.08
720 46.39 57.72 64.72 73.96 87.27 100.99 105.89 109.97 121.73 131.46 138.60
1080 50.12 62.36 69.93 79.90 94.28 109.10 114.40 118.81 131.52 142.03 149.74
1440 52.92 65.84 73.82 84.35 99.53 115.18 120.78 125.42 138.84 149.94 158.08
2880 60.21 74.92 84.00 95.99 113.26 131.06 137.43 142.72 157.99 170.62 179.87
4320 64.90 80.75 90.54 103.46 122.08 141.27 148.13 153.83 170.29 183.90 193.88
5760 68.44 85.15 95.47 109.09 128.73 148.96 156.20 162.21 179.57 193.92 204.44
7200 71.30 88.72 99.48 113.67 134.12 155.21 162.75 169.01 187.09 202.05 213.01
8640 73.74 91.74 102.87 117.54 138.69 160.50 168.30 174.77 193.47 208.94 220.27
[24]:
idf.result_table(add_names=True).round(2)
WARNING: Using an annual series and a return period < 5 a will result in faulty values!
WARNING: Using an annual series and a return period < 5 a will result in faulty values!
WARNING: Using an annual series and a return period < 5 a will result in faulty values!
[24]:
return period (a) 1 2 3 5 10 20 25 30 50 75 100
frequency (1/a) 1.000 0.500 0.333 0.200 0.100 0.050 0.040 0.033 0.020 0.013 0.010
duration (min)
5 8.47 10.54 11.82 13.50 15.93 18.44 19.34 20.08 22.23 24.00 25.31
10 13.06 16.25 18.22 20.82 24.56 28.42 29.80 30.95 34.26 37.00 39.01
15 16.08 20.01 22.44 25.64 30.25 35.01 36.71 38.12 42.20 45.57 48.04
20 18.30 22.76 25.52 29.17 34.41 39.82 41.76 43.37 48.01 51.84 54.66
30 21.44 26.67 29.90 34.17 40.32 46.66 48.93 50.81 56.24 60.74 64.04
45 24.55 30.54 34.25 39.13 46.17 53.43 56.03 58.19 64.41 69.56 73.33
60 26.73 33.26 37.29 42.61 50.28 58.18 61.01 63.36 70.13 75.74 79.85
90 29.78 37.05 41.55 47.47 56.01 64.82 67.97 70.59 78.14 84.38 88.96
120 31.94 39.74 44.56 50.92 60.08 69.53 72.91 75.71 83.81 90.51 95.42
180 35.02 43.57 48.86 55.83 65.88 76.23 79.94 83.01 91.89 99.24 104.62
240 37.25 46.35 51.97 59.38 70.07 81.08 85.02 88.30 97.74 105.56 111.28
360 40.49 50.38 56.49 64.55 76.16 88.13 92.42 95.97 106.24 114.73 120.96
540 43.88 54.59 61.21 69.95 82.53 95.51 100.15 104.01 115.13 124.34 131.08
720 46.39 57.72 64.72 73.96 87.27 100.99 105.89 109.97 121.73 131.46 138.60
1080 50.12 62.36 69.93 79.90 94.28 109.10 114.40 118.81 131.52 142.03 149.74
1440 52.92 65.84 73.82 84.35 99.53 115.18 120.78 125.42 138.84 149.94 158.08
2880 60.21 74.92 84.00 95.99 113.26 131.06 137.43 142.72 157.99 170.62 179.87
4320 64.90 80.75 90.54 103.46 122.08 141.27 148.13 153.83 170.29 183.90 193.88
5760 68.44 85.15 95.47 109.09 128.73 148.96 156.20 162.21 179.57 193.92 204.44
7200 71.30 88.72 99.48 113.67 134.12 155.21 162.75 169.01 187.09 202.05 213.01
8640 73.74 91.74 102.87 117.54 138.69 160.50 168.30 174.77 193.47 208.94 220.27

To save the table as a csv:

[25]:
idf.result_table(add_names=True).round(2).to_csv(output_directory / 'idf_table_UNIX.csv', sep=',', decimal='.', float_format='%0.2f')
WARNING: Using an annual series and a return period < 5 a will result in faulty values!
WARNING: Using an annual series and a return period < 5 a will result in faulty values!
WARNING: Using an annual series and a return period < 5 a will result in faulty values!
[26]:
print(idf.result_table(add_names=True).round(2).to_string())
WARNING: Using an annual series and a return period < 5 a will result in faulty values!
WARNING: Using an annual series and a return period < 5 a will result in faulty values!
WARNING: Using an annual series and a return period < 5 a will result in faulty values!
return period (a)    1      2       3       5       10      20      25      30      50      75      100
frequency (1/a)    1.000  0.500   0.333   0.200   0.100   0.050   0.040   0.033   0.020   0.013   0.010
duration (min)
5                   8.47  10.54   11.82   13.50   15.93   18.44   19.34   20.08   22.23   24.00   25.31
10                 13.06  16.25   18.22   20.82   24.56   28.42   29.80   30.95   34.26   37.00   39.01
15                 16.08  20.01   22.44   25.64   30.25   35.01   36.71   38.12   42.20   45.57   48.04
20                 18.30  22.76   25.52   29.17   34.41   39.82   41.76   43.37   48.01   51.84   54.66
30                 21.44  26.67   29.90   34.17   40.32   46.66   48.93   50.81   56.24   60.74   64.04
45                 24.55  30.54   34.25   39.13   46.17   53.43   56.03   58.19   64.41   69.56   73.33
60                 26.73  33.26   37.29   42.61   50.28   58.18   61.01   63.36   70.13   75.74   79.85
90                 29.78  37.05   41.55   47.47   56.01   64.82   67.97   70.59   78.14   84.38   88.96
120                31.94  39.74   44.56   50.92   60.08   69.53   72.91   75.71   83.81   90.51   95.42
180                35.02  43.57   48.86   55.83   65.88   76.23   79.94   83.01   91.89   99.24  104.62
240                37.25  46.35   51.97   59.38   70.07   81.08   85.02   88.30   97.74  105.56  111.28
360                40.49  50.38   56.49   64.55   76.16   88.13   92.42   95.97  106.24  114.73  120.96
540                43.88  54.59   61.21   69.95   82.53   95.51  100.15  104.01  115.13  124.34  131.08
720                46.39  57.72   64.72   73.96   87.27  100.99  105.89  109.97  121.73  131.46  138.60
1080               50.12  62.36   69.93   79.90   94.28  109.10  114.40  118.81  131.52  142.03  149.74
1440               52.92  65.84   73.82   84.35   99.53  115.18  120.78  125.42  138.84  149.94  158.08
2880               60.21  74.92   84.00   95.99  113.26  131.06  137.43  142.72  157.99  170.62  179.87
4320               64.90  80.75   90.54  103.46  122.08  141.27  148.13  153.83  170.29  183.90  193.88
5760               68.44  85.15   95.47  109.09  128.73  148.96  156.20  162.21  179.57  193.92  204.44
7200               71.30  88.72   99.48  113.67  134.12  155.21  162.75  169.01  187.09  202.05  213.01
8640               73.74  91.74  102.87  117.54  138.69  160.50  168.30  174.77  193.47  208.94  220.27

To create a color plot of the IDF curves:

[27]:
fig, ax = idf.curve_figure(color=True)
WARNING: Using an annual series and a return period < 5 a will result in faulty values!
WARNING: Using an annual series and a return period < 5 a will result in faulty values!
../_images/examples_example_python_api_2025_36_1.png

To create a black/white plot of the IDF curves:

[29]:
fig, ax = idf.curve_figure(color=False)
WARNING: Using an annual series and a return period < 5 a will result in faulty values!
WARNING: Using an annual series and a return period < 5 a will result in faulty values!
../_images/examples_example_python_api_2025_38_1.png
[30]:
fig, ax = idf.curve_figure(color=True, logx=True, duration_steps_ticks=True)
WARNING: Using an annual series and a return period < 5 a will result in faulty values!
WARNING: Using an annual series and a return period < 5 a will result in faulty values!
../_images/examples_example_python_api_2025_39_1.png