def result_plot(self, min_duration=5.0, max_duration=720.0, logx=False, fmt='png', show=False): duration_steps = np.arange(min_duration, max_duration + 1, 1) plt.style.use('bmh') return_periods = [0.5, 1, 10, 50, 100] return_periods = [1, 2, 5, 10, 50] table = self.result_table(durations=duration_steps, return_periods=return_periods) ax = table.plot(color='black', logx=logx, legend=False) for _, return_time in enumerate(return_periods): p = self.measured_points(return_time, max_duration=max_duration) ax.plot(p, 'k' + 'x') x, y = list(p.tail(1).items())[0] ax.text( x + 10, y, '{} a'.format(return_time), verticalalignment='center', horizontalalignment='left', #bbox=dict(facecolor='white', alpha=1.0, lw=1) ) ax.tick_params(axis='both', which='both', direction='out') ax.set_xlabel('Duration D in (min)') ax.set_ylabel('Rainfall h$_N$ in (mm)') ax.set_title('IDF curves') fig = ax.get_figure() fn = self.output_filename + '_idf_plot.' + fmt cm_to_inch = 2.54 fig.set_size_inches(h=21 / cm_to_inch, w=29.7 / cm_to_inch) # (11.69, 8.27) fig.tight_layout() fig.savefig(fn, dpi=260) plt.close(fig) if show: show_file(fn) return fn
def result_plot_v2(idf, filename, min_duration=5.0, max_duration=720.0, logx=False, show=False): duration_steps = np.arange(min_duration, max_duration + 1, 1) colors = ['r', 'g', 'b', 'y', 'm'] plt.style.use('bmh') # return_periods = [0.5, 1, 10, 50, 100] return_periods = [1, 2, 5, 10, 50] table = idf.result_table(durations=duration_steps, return_periods=return_periods) table.index = pd.to_timedelta(table.index, unit='m') ax = table.plot(color=colors, logx=logx) ax.tick_params(axis='both', which='both', direction='out') for i in range(len(return_periods)): return_time = return_periods[i] color = colors[i] p = measured_points(idf, return_time, max_duration=max_duration) p.index = pd.to_timedelta(p.index, unit='m') ax.plot(p, color + 'x') # plt.text(max_duration * ((10 - offset) / 10), depth_of_rainfall(max_duration * ((10 - offset) / 10), # return_time, parameter_1, # parameter_2) + offset, '$T_n=$' + str( # return_time)) ax.set_xlabel('Dauerstufe $D$ in $[min]$') ax.set_ylabel('Regenhöhe $h_N$ in $[mm]$') ax.set_title('Regenhöhenlinien') ax.legend(title='$T_n$= ... [a]') if max_duration > 1.5 * 60: pass else: pass major_ticks = np.array( [d * 60 * 1.0e9 for d in idf.duration_steps if d <= max_duration]) # minor_ticks = pd.date_range("00:00", "23:59", freq='15T').time # print(major_ticks) # exit() ax.set_xticks(major_ticks) # print(ax.get_xticks()) from matplotlib import ticker def time_ticks(x, _): x = pd.to_timedelta(x, unit='ns').total_seconds() / 60 h = int(x / 60) m = int(x % 60) s = '' if h: s += '{}h'.format(h) if m: s += '{}min'.format(m) return s formatter = ticker.FuncFormatter(time_ticks) ax.xaxis.set_major_formatter(formatter) # print(ax.get_xticks()) # plt.axis([0, max_duration, 0, depth_of_rainfall(max_duration, # return_periods[len(return_periods) - 1], # parameter_1, parameter_2) + 10]) fig = ax.get_figure() cm_to_inch = 2.54 fig.set_size_inches(h=21 / cm_to_inch, w=29.7 / cm_to_inch) # (11.69, 8.27) fig.tight_layout() fig.savefig(filename, dpi=260) plt.close(fig) if show: show_file(filename) return filename
def run_script(start=None, end=None, id_=None, input_=None, meta=False, max10a=False, add_gaps=True, statistics=False, to_csv=False, to_parquet=False, plot=False, unix=False): # __________________________________________________________________________________________________________________ if start is not None: start = convert_time(start, 'start') # __________________________________________________________________________________________________________________ if end is not None: end = convert_time(end, 'end') # __________________________________________________________________________________________________________________ series, name = get_data(id_, input_, meta, unix) # __________________________________________________________________________________________________________________ series = series[start:end].copy() check_period(series) # ______________________________________________________ tags = None availability = None # __________________________________________________________________________________________________________________ if max10a: tags = data_validation(series) availability = data_availability(tags) start, end = max_10a(availability) series = series.loc[start:end].copy() check_period(series) if start or end or max10a: print('The time-series is clipped to ' 'start at "{:%Y-%m-%d}" and end at "{:%Y-%m-%d}".'.format( *start_end_date(series))) # __________________________________________________________________________________________________________________ if add_gaps: if tags is None: tags = data_validation(series) if availability is None: availability = data_availability(tags) gaps = span_table(~availability) gaps['delta'] = (gaps['end'] - gaps['start']).dt.total_seconds() / (60 * 60 * 24) gaps = gaps.sort_values('delta', ascending=False) gaps.columns = ['start', 'end', 'gaps in days'] gaps_fn = '{}_gaps.csv'.format(name) gaps.to_csv(gaps_fn, float_format='%0.3f', **csv_args(unix)) print('The gaps table is saved {}.'.format(output_filename(gaps_fn))) # __________________________________________________________________________________________________________________ if statistics: if tags is None: tags = data_validation(series) if availability is None: availability = data_availability(tags) availability_cut = 0.9 stats = create_statistics(series, availability, availability_cut=availability_cut) with open('{}_stats.txt'.format(name), 'w+') as f: rain_fmt = '{:0.0f} mm' date_fmt = '{:%Y}' avail_fmt = '{:0.0%}' f.write( 'The annual totals of the data series serve as the data basis.\n' 'The following statistics were analyzed:\n' 'Only years with a availability of {avail} will be evaluated.\n' '\n' 'The maximum is {rain} and was in the year {date} (with {avail} Data available).\n' 'The minimum is {rain} and was in the year {date} (with {avail} Data available).\n' 'The mean is {rain} (with {avail} Data available in average).' ''.format(rain=rain_fmt, date=date_fmt, avail=avail_fmt).format(availability_cut, *stats['maximum'], *stats['minimum'], *stats['mean'])) print('The statistics are saved {}.'.format(output_filename( f.name))) # __________________________________________________________________________________________________________________ save_formats = list() if to_csv: save_formats.append('csv') if to_parquet: save_formats.append('parquet') for save_as in save_formats: out_fn = export_series(series, filename=name, save_as=save_as, unix=unix) print('The time-series is saved {}.'.format(output_filename(out_fn))) # __________________________________________________________________________________________________________________ if plot: if tags is None: tags = data_validation(series) if availability is None: availability = data_availability(tags) plot_fn = '{}_plot.png'.format(name) rain_plot(series, availability, plot_fn) print('The plot is saved {}.'.format(output_filename(plot_fn))) show = True if show: show_file(plot_fn)
def command_line_tool(cls): user = heavy_rain_parser() # -------------------------------------------------- # use the same directory as the input file and make as subdir with the name of the input_file + "_idf_data" out = '{label}_idf_data'.format( label='.'.join(user.input.split('.')[:-1])) if not path.isdir(out): mkdir(out) action = 'Creating' else: action = 'Using' print( '{} the subfolder "{}" for the interim- and final-results.'.format( action, out)) fn_pattern = path.join(out, 'idf_{}') # -------------------------------------------------- idf = cls(series_kind=user.series_kind, worksheet=user.worksheet, extended_durations=True) # -------------------------------------------------- parameters_fn = fn_pattern.format('parameters.yaml') if path.isfile(parameters_fn): print( 'Found existing interim-results in "{}" and using them for calculations.' .format(parameters_fn)) else: print('Start reading the time-series {} for the analysis.'.format( user.input)) ts = import_series(user.input).replace(0, np.NaN).dropna() # -------------------------------------------------- idf.set_series(ts) print('Finished reading.') # -------------------------------------------------- idf.auto_save_parameters(parameters_fn) # -------------------------------------------------- h = user.height_of_rainfall r = user.flow_rate_of_rainfall d = user.duration t = user.return_period if r is not None: if h is None and d is not None: h = rate2height(rain_flow_rate=r, duration=d) elif d is None and h is not None: d = h / r * 1000 / 6 if user.r_720_1: d = 720 t = 1 if any((h, d, t)): if all((d, t)): pass elif all((d, h)): t = idf.get_return_period(h, d) print('The return period is {:0.1f} years.'.format(t)) elif all((h, t)): d = idf.get_duration(h, t) print('The duration is {:0.1f} minutes.'.format(d)) print( 'Resultierende Regenhöhe h_N(T_n={t:0.1f}a, D={d:0.1f}min) = {h:0.2f} mm' ''.format(t=t, d=d, h=idf.depth_of_rainfall(d, t))) print( 'Resultierende Regenspende r_N(T_n={t:0.1f}a, D={d:0.1f}min) = {r:0.2f} L/(s*ha)' ''.format(t=t, d=d, r=idf.rain_flow_rate(d, t))) # -------------------------------------------------- if user.plot: fig, ax = idf.result_figure() plot_fn = fn_pattern.format('curves_plot.png') fig.savefig(plot_fn, dpi=260) plt.close(fig) show_file(plot_fn) print('Created the IDF-curves-plot and saved the file as "{}".'. format(plot_fn)) # -------------------------------------------------- if user.export_table: table = idf.result_table(add_names=True) print(table.round(2).to_string()) table_fn = fn_pattern.format('table.csv') table.to_csv(table_fn, sep=';', decimal=',', float_format='%0.2f') print('Created the IDF-curves-plot and saved the file as "{}".'. format(table_fn))
def execute_tool(): args = ehyd_parser() # __________________________________________________________________________________________________________________ if args.start is not None: try: start = to_datetime(args.start) except ValueError(): raise UserWarning( 'Wrong time format for the start time. Use the format="YYYY-MM-DD"' ) else: start = None # __________________________________________________________________________________________________________________ if args.end is not None: try: end = to_datetime(args.end) except ValueError(): raise UserWarning( 'Wrong time format for the end time. Use the format="YYYY-MM-DD"' ) else: end = None # __________________________________________________________________________________________________________________ if args.id is not None: id_number = args.id name = 'ehyd_{}'.format(id_number) if args.meta: with open('{}_meta.txt'.format(name), 'w') as f: f.write(get_station_meta(id_number)) print('Meta-data written in "{}".'.format(f.name)) series = get_series(id_number) # __________________________________________________________________________________________________________________ elif args.input is not None: fn = args.input series = import_series(fn, args.unix) print('Series "{}" was imported.'.format(fn)) name = path.basename(fn).split('.')[0] print('The filename basis of the output files is "{}".'.format(name)) # __________________________________________________________________________________________________________________ else: raise UserWarning( 'No data selected. Use either a input file or a id. See help menu.' ) print('The original time series has the start at "{:%Y-%m-%d}"' ' and the end at "{:%Y-%m-%d}".'.format( *series.index[[0, -1]].tolist())) # __________________________________________________________________________________________________________________ if start is not None: series = series[start:].copy() check_period(series) if end is not None: series = series[:end].copy() check_period(series) # __________________________________________________________________________________________________________________ if args.max10a: tags = data_validation(series) availability = data_availability(tags) start, end = max_10a(availability) series = series.loc[start:end].copy() check_period(series) else: tags = DataFrame() availability = Series() print('Data was clipped to start="{:%Y-%m-%d}" and end="{:%Y-%m-%d}".' ''.format(*series.index[[0, -1]].tolist())) # __________________________________________________________________________________________________________________ if args.add_gaps: if tags.empty: tags = data_validation(series) if availability.empty: availability = data_availability(tags) gaps = span_table(availability.index, ~availability) gaps['delta'] = gaps['delta'].dt.total_seconds() / (60 * 60 * 24) gaps = gaps.sort_values('delta', ascending=False) gaps.columns = ['start', 'end', 'gaps in days'] gaps_fn = '{}_gaps.csv'.format(name) gaps.to_csv(gaps_fn, float_format='%0.3f', **csv_args(args.unix)) print('The gaps table was written in "{}".'.format(gaps_fn)) # __________________________________________________________________________________________________________________ if args.statistics: with open('{}_stats.txt'.format(name), 'w+') as f: if tags.empty: tags = data_validation(series) if availability.empty: availability = data_availability(tags) stats = statistics(series, availability) rain_fmt = '{:0.0f} mm' date_fmt = '{:%Y}' avail_fmt = '{:0.0%}' f.write( 'The annual totals of the data series serve as the data basis.\n' 'The following statistics were analyzed:\n' '\n' 'The maximum is {rain} and was in the year {date} (with {avail} Data available).\n' 'The minimum is {rain} and was in the year {date} (with {avail} Data available).\n' 'The mean is {rain} (with {avail} Data available in average).' ''.format(rain=rain_fmt, date=date_fmt, avail=avail_fmt).format(*stats['maximum'], *stats['minimum'], *stats['mean'])) print('The statistics was written in the file "{}".'.format( f.name)) # __________________________________________________________________________________________________________________ if args.to_csv: out_fn = export_series(series, filename=name, save_as='csv', unix=args.unix) print('The time series was saved in the file "{}".'.format(out_fn)) # __________________________________________________________________________________________________________________ if args.to_ixx: out_fn = export_series(series, filename=name, save_as='ixx', unix=args.unix) print('The time series was saved in the file "{}".'.format(out_fn)) # __________________________________________________________________________________________________________________ if args.to_parquet: out_fn = export_series(series, filename=name, save_as='parquet') print('The time series was saved in the file "{}".'.format(out_fn)) # __________________________________________________________________________________________________________________ if args.plot: if tags.empty: tags = data_validation(series) if availability.empty: availability = data_availability(tags) plot_fn = '{}_plot.png'.format(name) rain_plot(series, availability, plot_fn) print('The plot was saved in the file "{}".'.format(plot_fn)) show = True if show: show_file(plot_fn)
def run_script(identifier=None, filename=None, start=None, end=None, max10a=False, add_gaps=True, to_csv=False, to_parquet=False, plot=False, statistics=False, meta=False, unix=False, availability_cut=0.9, agg='sum', field=FIELDS.NIEDERSCHLAG): """ get eHYD.gv.at data and run simple analysis on it and finally save the data to a local file. """ # __________________________________________________________________________________________________________________ if start is not None: start = _convert_time(start, 'start') # __________________________________________________________________________________________________________________ if end is not None: end = _convert_time(end, 'end') # __________________________________________________________________________________________________________________ if identifier is not None: identifier = int(identifier) name = f'ehyd_{field}_{identifier}' print(f'You choose the id: "{identifier}" with the meta-data: ' f'{get_basic_station_meta(identifier, field=field)}.') if meta: with open('{}_meta.json'.format(name), 'w') as f: json.dump(get_station_reference_data( identifier, field=field, data_kind=DATA_KIND.MEASUREMENT), f, indent=4) print('The meta-data are saved in {}.'.format( _output_filename(f.name))) series = get_ehyd_data(identifier, field=field, data_kind=DATA_KIND.MEASUREMENT) # __________________________________________________________________________________________________________________ elif filename is not None: series = import_series(filename, unix=unix) print( f'The data in "{filename}" were imported and are used as the precipitation time-series.' ) name = path.basename(filename).split('.')[0] # __________________________________________________________________________________________________________________ else: raise UserWarning( 'No data selected. Use either a input file or a id. See help menu.' ) print( f'The selected time-series start at "{series.index[0]:%Y-%m-%d}" and ends at "{series.index[0]:%Y-%m-%d}".' ) # __________________________________________________________________________________________________________________ series = series[start:end].copy() check_period(series) # ______________________________________________________ tags = None availability = None # __________________________________________________________________________________________________________________ if max10a: tags = data_validation(series) availability = data_availability(tags) start, end = max_10a(availability) series = series.loc[start:end].copy() check_period(series) if start or end or max10a: print( f'The time-series is clipped to start at "{series.index[0]:%Y-%m-%d}" and end at "' f'{series.index[0]:%Y-%m-%d}".') # __________________________________________________________________________________________________________________ if add_gaps: if tags is None: tags = data_validation(series) if availability is None: availability = data_availability(tags) gaps = span_table(~availability) gaps['delta'] = (gaps['end'] - gaps['start']).dt.total_seconds() / (60 * 60 * 24) gaps = gaps.sort_values('delta', ascending=False) gaps.columns = ['start', 'end', 'gaps in days'] gaps_fn = f'{name}_gaps.csv' gaps.to_csv(gaps_fn, float_format='%0.3f', **csv_args(unix)) print(f'The gaps table is saved {_output_filename(gaps_fn)}.') # __________________________________________________________________________________________________________________ if statistics: if tags is None: tags = data_validation(series) if availability is None: availability = data_availability(tags) stats = create_statistics(series, availability, availability_cut=availability_cut) with open('{}_stats.txt'.format(name), 'w+') as f: rain_fmt = '{:0.0f} mm' date_fmt = '{:%Y}' avail_fmt = '{:0.0%}' f.write( f'The annual totals of the data series serve as the data basis.\n' f'The following statistics were analyzed:\n' f'Only years with a availability of {availability_cut:{avail_fmt}} will be evaluated.\n' f'\n' f'The maximum is {stats["maximum"]:{rain_fmt}} and was in the year {stats["maximum_date"]:{date_fmt}} ' f'(with {stats["maximum_avail"]:{avail_fmt}} Data available).\n' f'The minimum is {stats["minimum"]:{rain_fmt}} and was in the year {stats["minimum_date"]:{date_fmt}} ' f'(with {stats["minimum_avail"]:{avail_fmt}} Data available).\n' f'The mean is {stats["mean"]:{rain_fmt}} ' f'(with {stats["mean_avail"]:{avail_fmt}} Data available in average).' ) print(f'The statistics are saved {_output_filename(f.name)}.') # __________________________________________________________________________________________________________________ save_formats = [] if to_csv: save_formats.append('csv') if to_parquet: save_formats.append('parquet') for save_as in save_formats: out_fn = export_series(series, filename=name, save_as=save_as, unix=unix) print(f'The time-series is saved {_output_filename(out_fn)}.') # __________________________________________________________________________________________________________________ if plot: if tags is None: tags = data_validation(series) if availability is None: availability = data_availability(tags) plot_fn = f'{name}_plot.png' agg_data_plot(series, availability, plot_fn, agg=agg) print(f'The plot is saved {_output_filename(plot_fn)}.') show = True if show: show_file(plot_fn)