CLIMATE-583 - Add time series plot support
Project: http://git-wip-us.apache.org/repos/asf/climate/repo Commit: http://git-wip-us.apache.org/repos/asf/climate/commit/d6be7cf6 Tree: http://git-wip-us.apache.org/repos/asf/climate/tree/d6be7cf6 Diff: http://git-wip-us.apache.org/repos/asf/climate/diff/d6be7cf6 Branch: refs/heads/master Commit: d6be7cf6266988e7e08305f5cfa481105875f2e7 Parents: c8539d0 Author: Michael Joyce <[email protected]> Authored: Thu Jun 4 14:22:19 2015 -0700 Committer: Michael Joyce <[email protected]> Committed: Thu Jun 4 14:45:22 2015 -0700 ---------------------------------------------------------------------- ocw-config-runner/configuration_parsing.py | 4 +- .../example/time_series_plot_example.yaml | 31 +++++ ocw-config-runner/plot_generation.py | 116 ++++++++++++++++--- 3 files changed, 134 insertions(+), 17 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/climate/blob/d6be7cf6/ocw-config-runner/configuration_parsing.py ---------------------------------------------------------------------- diff --git a/ocw-config-runner/configuration_parsing.py b/ocw-config-runner/configuration_parsing.py index ff853b7..5c28249 100644 --- a/ocw-config-runner/configuration_parsing.py +++ b/ocw-config-runner/configuration_parsing.py @@ -238,7 +238,9 @@ def _valid_plot_config_data(plot_config_data): 'output_name' ]) elif plot_type == 'time_series': - logger.warn('Time series plots are currently unsupported. Skipping validation') + required_keys = set([ + 'time_range' + ]) elif plot_type == 'portrait': required_keys = set([ 'metric_index', http://git-wip-us.apache.org/repos/asf/climate/blob/d6be7cf6/ocw-config-runner/example/time_series_plot_example.yaml ---------------------------------------------------------------------- diff --git a/ocw-config-runner/example/time_series_plot_example.yaml b/ocw-config-runner/example/time_series_plot_example.yaml new file mode 100644 index 0000000..b5599cc --- /dev/null +++ b/ocw-config-runner/example/time_series_plot_example.yaml @@ -0,0 +1,31 @@ +evaluation: + temporal_time_delta: 30 + spatial_regrid_lats: !!python/tuple [-20, 20, 1] + spatial_regrid_lons: !!python/tuple [-20, 20, 1] + subset: [-180, 180, -90, 90, "1989-01-01", "1990-12-01"] + +datasets: + reference: + data_source: local + file_count: 1 + path: /tmp/AFRICA_KNMI-RACMO2.2b_CTL_ERAINT_MM_50km_1989-2008_tasmax.nc + variable: tasmax + optional_args: + name: KNMI + + targets: + - data_source: local + file_count: 1 + path: /tmp/AFRICA_UC-WRF311_CTL_ERAINT_MM_50km-rg_1989-2008_tasmax.nc + variable: tasmax + optional_args: + name: WRF +metrics: + +plots: + - type: time_series + time_range: monthly + +subregions: + - [-10.0, 0.0, -19.0, 19.0] + - [0.0, 10.0, -10.0, 10.0] http://git-wip-us.apache.org/repos/asf/climate/blob/d6be7cf6/ocw-config-runner/plot_generation.py ---------------------------------------------------------------------- diff --git a/ocw-config-runner/plot_generation.py b/ocw-config-runner/plot_generation.py index c0bfa03..392331d 100644 --- a/ocw-config-runner/plot_generation.py +++ b/ocw-config-runner/plot_generation.py @@ -17,7 +17,9 @@ import logging +import ocw.dataset_processor as dsp import ocw.plotter as plots +import ocw.utils as utils import numpy as np @@ -41,7 +43,7 @@ def plot_from_config(evaluation, config_data): elif plot['type'] == 'taylor': _draw_taylor_diagram(evaluation, plot) elif plot['type'] == 'time_series': - logger.warn('Time series plots are currently unsupported. Skipping ...') + _draw_time_series_plot(evaluation, plot) elif plot['type'] == 'portrait': _draw_portrait_diagram(evaluation, plot) else: @@ -57,13 +59,20 @@ def _draw_contour_plot(evaluation, plot_config): if type(lons) != type(list): lons = np.arange(lons['range_min'], lons['range_max'], lons['range_step']) - for i, (row, col) in enumerate(plot_config['results_indices']): + for i, index in enumerate(plot_config['results_indices']): + if len(index) == 2: + target, metric = index + vals = evaluation.results[target][metric] + elif len(index) == 3: + target, metric, subregion = index + vals = evaluation.results[target][metric][subregion] + plot_name = plot_config['output_name'] + '_{}'.format(i) - plots.draw_contour_map(evaluation.results[row][col], - np.array(lats), - np.array(lons), - plot_name, - **plot_config.get('optional_args', {})) + plots.draw_contour_map(vals, + np.array(lats), + np.array(lons), + plot_name, + **plot_config.get('optional_args', {})) def _draw_taylor_diagram(evaluation, plot_config): """""" @@ -71,15 +80,26 @@ def _draw_taylor_diagram(evaluation, plot_config): ref_dataset_name = evaluation.ref_dataset.name target_dataset_names = [t.name for t in evaluation.target_datasets] - stddev_results = [ - evaluation.results[row][col] - for (row, col) in plot_config['stddev_results_indices'] - ] - - pattern_corr_results = [ - evaluation.results[row][col] - for (row, col) in plot_config['pattern_corr_results_indices'] - ] + if len(plot_config['stddev_results_indices'][0]) == 2: + stddev_results = [ + evaluation.results[tar][met] + for (tar, met) in plot_config['stddev_results_indices'] + ] + + pattern_corr_results = [ + evaluation.results[tar][met] + for (tar, met) in plot_config['pattern_corr_results_indices'] + ] + elif len(plot_config['stddev_results_indices'][0]) == 3: + stddev_results = [ + evaluation.results[tar][met][sub] + for (tar, met, sub) in plot_config['stddev_results_indices'] + ] + + pattern_corr_results = [ + evaluation.results[tar][met][sub] + for (tar, met, sub) in plot_config['pattern_corr_results_indices'] + ] plot_data = np.array([stddev_results, pattern_corr_results]).transpose() @@ -118,3 +138,67 @@ def _draw_portrait_diagram(evaluation, plot_config): subregion_names, fname=plot_config['output_name'], **plot_config.get('optional_args', {})) + +def _draw_time_series_plot(evaluation, plot_config): + """""" + time_range_info = plot_config['time_range'] + ref_ds = evaluation.ref_dataset + target_ds = evaluation.target_datasets + + if time_range_info == 'monthly': + ref_ds.values, ref_ds.times = utils.calc_climatology_monthly(ref_ds) + + for t in target_ds: + t.values, t.times = utils.calc_climatology_monthly(t) + else: + logger.error( + 'Invalid time range provided. Only monthly is supported ' + 'at the moment' + ) + return + + if evaluation.subregions: + for bound_count, bound in enumerate(evaluation.subregions): + results = [] + labels = [] + + subset = dsp.subset( + bound, + ref_ds, + subregion_name="R{}_{}".format(bound_count, ref_ds.name) + ) + + results.append(utils.calc_time_series(subset)) + labels.append(subset.name) + + for t in target_ds: + subset = dsp.subset( + bound, + t, + subregion_name="R{}_{}".format(bound_count, t.name) + ) + results.append(utils.calc_time_series(subset)) + labels.append(subset.name) + + plots.draw_time_series(np.array(results), + ref_ds.times, + labels, + 'R{}'.format(bound_count), + **plot_config.get('optional_args', {})) + + else: + results = [] + labels = [] + + results.append(utils.calc_time_series(ref_ds)) + labels.append(ref_ds.name) + + for t in target_ds: + results.append(utils.calc_time_series(t)) + labels.append(t.name) + + plots.draw_time_series(np.array(results), + ref_ds.times, + labels, + 'time_series', + **plot_config.get('optional_args', {}))
