def load_cubes(filenames, obs_filename, metadata): """ Organize data provided by recipe. Parameters ---------- filenames: dict input files listed in the recipe obs_filename: str the preprocessed observations file. metadata: dict the input files dictionary """ # check if observations are provided if obs_filename: obsname = metadata[obs_filename]['dataset'] filenames.remove(obs_filename) filenames.insert(0, obs_filename) else: obsname = '' logger.info('Observations not provided. Plot each model data.') # Load the data for each layer as a separate cube layers = {} cubes = {} for thename in filenames: logger.debug('loading: \t%s', thename) cube = iris.load_cube(thename) cube = diagtools.bgc_units(cube, metadata[thename]['short_name']) model_name = metadata[thename]['dataset'] cubes[model_name] = diagtools.make_cube_layer_dict(cube) for layer in cubes[model_name]: layers[layer] = True logger.debug('layers: %s', layers) logger.debug('cubes: %s', ', '.join(cubes.keys())) return cubes, layers, obsname
def make_map_extent_plots( cfg, metadata, filename, ): """ Make an extent map plot showing several times for an individual model. Parameters ---------- cfg: dict the opened global config dictionairy, passed by ESMValTool. metadata: dict The metadata dictionairy for a specific model. filename: str The preprocessed model file. """ # Load cube and set up units cube = iris.load_cube(filename) iris.coord_categorisation.add_year(cube, 'time') cube = diagtools.bgc_units(cube, metadata['short_name']) cube = agregate_by_season(cube) # Is this data is a multi-model dataset? multi_model = metadata['dataset'].find('MultiModel') > -1 # Make a dict of cubes for each layer. cubes = diagtools.make_cube_layer_dict(cube) # Load image format extention image_extention = diagtools.get_image_format(cfg) # Load threshold, pole and season threshold = float(cfg['threshold']) pole = get_pole(cube) season = get_season(cube) # Start making figure for layer_index, (layer, cube_layer) in enumerate(cubes.items()): fig = plt.figure() fig.set_size_inches(7, 7) if pole == 'North': # North Hemisphere projection = cartopy.crs.NorthPolarStereo() ax1 = plt.subplot(111, projection=projection) ax1.set_extent([-180, 180, 50, 90], cartopy.crs.PlateCarree()) if pole == 'South': # South Hemisphere projection = cartopy.crs.SouthPolarStereo() ax1 = plt.subplot(111, projection=projection) ax1.set_extent([-180, 180, -90, -50], cartopy.crs.PlateCarree()) try: ax1.add_feature(cartopy.feature.LAND, zorder=10, facecolor=[0.8, 0.8, 0.8]) except ConnectionRefusedError: logger.error('Cartopy was unable add coastlines due to a ' 'connection error.') ax1.gridlines(linewidth=0.5, color='black', zorder=20, alpha=0.5, linestyle='--') try: plt.gca().coastlines() except AttributeError: logger.warning('make_polar_map: Not able to add coastlines') times = np.array(cube.coord('time').points.astype(float)) plot_desc = {} for time_itr, time in enumerate(times): cube = cube_layer[time_itr] line_width = 1 color = plt.cm.jet(float(time_itr) / float(len(times))) label = get_year(cube) plot_desc[time] = { 'label': label, 'c': [ color, ], 'lw': [ line_width, ], 'ls': [ '-', ] } layer = str(layer) qplt.contour(cube, [ threshold, ], colors=plot_desc[time]['c'], linewidths=plot_desc[time]['lw'], linestyles=plot_desc[time]['ls'], rasterized=True) # Add legend legend_size = len(plot_desc) + 1 ncols = int(legend_size / 25) + 1 ax1.set_position([ ax1.get_position().x0, ax1.get_position().y0, ax1.get_position().width * (1. - 0.1 * ncols), ax1.get_position().height ]) fig.set_size_inches(7 + ncols * 1.2, 7) # Construct dummy plots. for i in sorted(plot_desc): plt.plot( [], [], c=plot_desc[i]['c'][0], lw=plot_desc[i]['lw'][0], ls=plot_desc[i]['ls'][0], label=plot_desc[i]['label'], ) legd = ax1.legend(loc='center left', ncol=ncols, prop={'size': 10}, bbox_to_anchor=(1., 0.5)) legd.draw_frame(False) legd.get_frame().set_alpha(0.) # Add title to plot title = ' '.join([ metadata['dataset'], ]) if layer: title = ' '.join([ title, '(', layer, str(cube_layer.coords('depth')[0].units), ')' ]) plt.title(title) # Determine image filename: suffix = '_'.join(['ortho_map', pole, season, str(layer_index)]) suffix = suffix.replace(' ', '') + image_extention if multi_model: path = diagtools.folder(cfg['plot_dir']) path = path + os.path.basename(filename) path = path.replace('.nc', suffix) else: path = diagtools.get_image_path( cfg, metadata, suffix=suffix, ) # Saving files: if cfg['write_plots']: logger.info('Saving plots to %s', path) plt.savefig(path) plt.close()
def make_map_plots( cfg, metadata, filename, ): """ Make a simple map plot for an individual model. Parameters ---------- cfg: dict the opened global config dictionairy, passed by ESMValTool. metadata: dict The metadata dictionairy for a specific model. filename: str The preprocessed model file. """ # Load cube and set up units cube = iris.load_cube(filename) iris.coord_categorisation.add_year(cube, 'time') cube = diagtools.bgc_units(cube, metadata['short_name']) cube = agregate_by_season(cube) # Is this data is a multi-model dataset? multi_model = metadata['dataset'].find('MultiModel') > -1 # Make a dict of cubes for each layer. cubes = diagtools.make_cube_layer_dict(cube) # Load image format extention and threshold. image_extention = diagtools.get_image_format(cfg) threshold = float(cfg['threshold']) # Making plots for each layer plot_types = ['Fractional cover', 'Ice Extent'] plot_times = [0, -1] for plot_type, plot_time in product(plot_types, plot_times): for layer_index, (layer, cube_layer) in enumerate(cubes.items()): layer = str(layer) if plot_type == 'Fractional cover': cmap = 'Blues_r' if plot_type == 'Ice Extent': cmap = create_ice_cmap(threshold) cube = cube_layer[plot_time] # use cube to determine which hemisphere, season and year. pole = get_pole(cube) time_str = get_time_string(cube) # Make the polar map. make_polar_map(cube, pole=pole, cmap=cmap) # Add title to plot title = ' '.join([metadata['dataset'], plot_type, time_str]) if layer: title = ' '.join([ title, '(', layer, str(cube_layer.coords('depth')[0].units), ')' ]) plt.title(title) # Determine image filename: suffix = '_'.join( ['ortho_map', plot_type, time_str, str(layer_index)]) suffix = suffix.replace(' ', '') + image_extention if multi_model: path = diagtools.folder(cfg['plot_dir']) path = path + os.path.basename(filename) path = path.replace('.nc', suffix) else: path = diagtools.get_image_path( cfg, metadata, suffix=suffix, ) # Saving files: if cfg['write_plots']: logger.info('Saving plots to %s', path) plt.savefig(path) plt.close()
def make_ts_plots( cfg, metadata, filename, ): """ Make a ice extent and ice area time series plot for an individual model. Parameters ---------- cfg: dict the opened global config dictionairy, passed by ESMValTool. metadata: dict The metadata dictionairy for a specific model. filename: str The preprocessed model file. """ # Load cube and set up units cube = iris.load_cube(filename) iris.coord_categorisation.add_year(cube, 'time') cube = diagtools.bgc_units(cube, metadata['short_name']) cube = agregate_by_season(cube) # Is this data is a multi-model dataset? multi_model = metadata['dataset'].find('MultiModel') > -1 # Make a dict of cubes for each layer. cubes = diagtools.make_cube_layer_dict(cube) # Load image format extention image_extention = diagtools.get_image_format(cfg) # # Load threshold, pole, season. threshold = float(cfg['threshold']) pole = get_pole(cube) season = get_season(cube) # Making plots for each layer for plot_type in ['Ice Extent', 'Ice Area']: for layer_index, (layer, cube_layer) in enumerate(cubes.items()): layer = str(layer) times, data = calculate_area_time_series(cube_layer, plot_type, threshold) plt.plot(times, data) # Add title to plot title = ' '.join( [metadata['dataset'], pole, 'hemisphere', season, plot_type]) if layer: title = ' '.join([ title, '(', layer, str(cube_layer.coords('depth')[0].units), ')' ]) plt.title(title) # y axis label: plt.ylabel(' '.join([plot_type, 'm^2'])) # Determine image filename: suffix = '_'.join(['ts', metadata['preprocessor'], season, pole, plot_type, str(layer_index)])\ + image_extention suffix = suffix.replace(' ', '') if multi_model: path = diagtools.folder( cfg['plot_dir']) + os.path.basename(filename) path = path.replace('.nc', suffix) else: path = diagtools.get_image_path( cfg, metadata, suffix=suffix, ) # Saving files: if cfg['write_plots']: logger.info('Saving plots to %s', path) plt.savefig(path) plt.close()
def multi_model_time_series( cfg, metadata, ): """ Make a time series plot showing several preprocesssed datasets. This tool loads several cubes from the files, checks that the units are sensible BGC units, checks for layers, adjusts the titles accordingly, determines the ultimate file name and format, then saves the image. Parameters ---------- cfg: dict the opened global config dictionairy, passed by ESMValTool. metadata: dict The metadata dictionairy for a specific model. """ #### # Load the data for each layer as a separate cube model_cubes = {} layers = {} for filename in sorted(metadata): if metadata[filename]['frequency'] != 'fx': cube = iris.load_cube(filename) cube = diagtools.bgc_units(cube, metadata[filename]['short_name']) cubes = diagtools.make_cube_layer_dict(cube) model_cubes[filename] = cubes for layer in cubes: layers[layer] = True # Load image format extention image_extention = diagtools.get_image_format(cfg) # Make a plot for each layer for layer in layers: title = '' z_units = '' plot_details = {} cmap = plt.cm.get_cmap('viridis') # Plot each file in the group for index, filename in enumerate(sorted(metadata)): if len(metadata) > 1: color = cmap(index / (len(metadata) - 1.)) else: color = 'blue' # Take a moving average, if needed. if 'moving_average' in cfg: cube = moving_average(model_cubes[filename][layer], cfg['moving_average']) else: cube = model_cubes[filename][layer] if 'MultiModel' in metadata[filename]['dataset']: timeplot( cube, c=color, # label=metadata[filename]['dataset'], ls=':', lw=2., ) plot_details[filename] = { 'c': color, 'ls': ':', 'lw': 2., 'label': metadata[filename]['dataset'] } else: timeplot( cube, c=color, # label=metadata[filename]['dataset']) ls='-', lw=2., ) plot_details[filename] = { 'c': color, 'ls': '-', 'lw': 2., 'label': metadata[filename]['dataset'] } title = metadata[filename]['long_name'] if layer != '': if model_cubes[filename][layer].coords('depth'): z_units = model_cubes[filename][layer].coord('depth').units else: z_units = '' # Add title, legend to plots if layer: title = ' '.join([title, '(', str(layer), str(z_units), ')']) plt.title(title) plt.legend(loc='best') plt.ylabel(str(model_cubes[filename][layer].units)) # Saving files: if cfg['write_plots']: path = diagtools.get_image_path( cfg, metadata[filename], prefix='MultipleModels_', suffix='_'.join(['timeseries', str(layer) + image_extention]), metadata_id_list=[ 'field', 'short_name', 'preprocessor', 'diagnostic', 'start_year', 'end_year' ], ) # Resize and add legend outside thew axes. plt.gcf().set_size_inches(9., 6.) diagtools.add_legend_outside_right(plot_details, plt.gca(), column_width=0.15) logger.info('Saving plots to %s', path) plt.savefig(path) plt.close()
def make_time_series_plots( cfg, metadata, filename, ): """ Make a simple time series plot for an indivudual model 1D cube. This tool loads the cube from the file, checks that the units are sensible BGC units, checks for layers, adjusts the titles accordingly, determines the ultimate file name and format, then saves the image. Parameters ---------- cfg: dict the opened global config dictionairy, passed by ESMValTool. metadata: dict The metadata dictionairy for a specific model. filename: str The preprocessed model file. """ # Load cube and set up units cube = iris.load_cube(filename) cube = diagtools.bgc_units(cube, metadata['short_name']) # Is this data is a multi-model dataset? multi_model = metadata['dataset'].find('MultiModel') > -1 # Make a dict of cubes for each layer. cubes = diagtools.make_cube_layer_dict(cube) # Load image format extention image_extention = diagtools.get_image_format(cfg) # Making plots for each layer for layer_index, (layer, cube_layer) in enumerate(cubes.items()): layer = str(layer) if 'moving_average' in cfg: cube_layer = moving_average(cube_layer, cfg['moving_average']) if multi_model: timeplot(cube_layer, label=metadata['dataset'], ls=':') else: timeplot(cube_layer, label=metadata['dataset']) # Add title, legend to plots title = ' '.join([metadata['dataset'], metadata['long_name']]) if layer != '': if cube_layer.coords('depth'): z_units = cube_layer.coord('depth').units else: z_units = '' title = ' '.join([title, '(', layer, str(z_units), ')']) plt.title(title) plt.legend(loc='best') plt.ylabel(str(cube_layer.units)) # Determine image filename: if multi_model: path = diagtools.get_image_path( cfg, metadata, prefix='MultiModel', suffix='_'.join(['timeseries', str(layer) + image_extention]), metadata_id_list=[ 'field', 'short_name', 'preprocessor', 'diagnostic', 'start_year', 'end_year' ], ) else: path = diagtools.get_image_path( cfg, metadata, suffix='timeseries_' + str(layer_index) + image_extention, ) # Saving files: if cfg['write_plots']: logger.info('Saving plots to %s', path) plt.savefig(path) plt.close()
def make_map_plots( cfg, metadata, filename, ): """ Make a simple map plot for an individual model. Parameters ---------- cfg: dict the opened global config dictionary, passed by ESMValTool. metadata: dict the metadata dictionary filename: str the preprocessed model file. """ # Load cube and set up units cube = iris.load_cube(filename) cube = diagtools.bgc_units(cube, metadata['short_name']) # Is this data is a multi-model dataset? multi_model = metadata['dataset'].find('MultiModel') > -1 # Make a dict of cubes for each layer. cubes = diagtools.make_cube_layer_dict(cube) # Load image format extention image_extention = diagtools.get_image_format(cfg) # Making plots for each layer for layer_index, (layer, cube_layer) in enumerate(cubes.items()): layer = str(layer) qplt.contourf(cube_layer, 25, linewidth=0, rasterized=True) try: plt.gca().coastlines() except AttributeError: logger.warning('Not able to add coastlines') # Add title to plot title = ' '.join([metadata['dataset'], metadata['long_name']]) if layer: title = ' '.join([ title, '(', layer, str(cube_layer.coords('depth')[0].units), ')' ]) plt.title(title) # Determine image filename: if multi_model: path = diagtools.folder( cfg['plot_dir']) + os.path.basename(filename).replace( '.nc', '_map_' + str(layer_index) + image_extention) else: path = diagtools.get_image_path( cfg, metadata, suffix='map_' + str(layer_index) + image_extention, ) # Saving files: if cfg['write_plots']: logger.info('Saving plots to %s', path) plt.savefig(path) plt.close()
def multi_model_contours( cfg, metadata, ): """ Make a contour map showing several models. Parameters ---------- cfg: dict the opened global config dictionary, passed by ESMValTool. metadata: dict the metadata dictionary. """ #### # Load the data for each layer as a separate cube model_cubes = {} layers = {} for filename in sorted(metadata): cube = iris.load_cube(filename) cube = diagtools.bgc_units(cube, metadata[filename]['short_name']) cubes = diagtools.make_cube_layer_dict(cube) model_cubes[filename] = cubes for layer in cubes: layers[layer] = True # Load image format extention image_extention = diagtools.get_image_format(cfg) # Load threshold/thresholds. thresholds = diagtools.load_thresholds(cfg, metadata) # Make a plot for each layer and each threshold for layer, threshold in itertools.product(layers, thresholds): title = '' z_units = '' plot_details = {} cmap = plt.cm.get_cmap('jet') land_drawn = False # Plot each file in the group for index, filename in enumerate(sorted(metadata)): if len(metadata) > 1: color = cmap(index / (len(metadata) - 1.)) else: color = 'blue' linewidth = 1. linestyle = '-' # Determine line style for Observations if metadata[filename]['project'] in diagtools.get_obs_projects(): color = 'black' linewidth = 1.7 linestyle = '-' # Determine line style for MultiModel statistics: if 'MultiModel' in metadata[filename]['dataset']: color = 'black' linestyle = ':' linewidth = 1.4 cube = model_cubes[filename][layer] qplt.contour(cube, [ threshold, ], colors=[ color, ], linewidths=linewidth, linestyles=linestyle, rasterized=True) plot_details[filename] = { 'c': color, 'ls': linestyle, 'lw': linewidth, 'label': metadata[filename]['dataset'] } if not land_drawn: try: plt.gca().coastlines() except AttributeError: logger.warning('Not able to add coastlines') plt.gca().add_feature(cartopy.feature.LAND, zorder=10, facecolor=[0.8, 0.8, 0.8]) land_drawn = True title = metadata[filename]['long_name'] if layer != '': z_units = model_cubes[filename][layer].coords('depth')[0].units units = str(model_cubes[filename][layer].units) # Add title, threshold, legend to plots title = ' '.join([title, str(threshold), units]) if layer: title = ' '.join([title, '(', str(layer), str(z_units), ')']) plt.title(title) plt.legend(loc='best') # Saving files: if cfg['write_plots']: path = diagtools.get_image_path( cfg, metadata[filename], prefix='MultipleModels_', suffix='_'.join([ '_contour_map_', str(threshold), str(layer) + image_extention ]), metadata_id_list=[ 'field', 'short_name', 'preprocessor', 'diagnostic', 'start_year', 'end_year' ], ) # Resize and add legend outside thew axes. plt.gcf().set_size_inches(9., 6.) diagtools.add_legend_outside_right(plot_details, plt.gca(), column_width=0.15) logger.info('Saving plots to %s', path) plt.savefig(path) plt.close()
def make_map_contour( cfg, metadata, filename, ): """ Make a simple contour map plot for an individual model. Parameters ---------- cfg: dict the opened global config dictionary, passed by ESMValTool. metadata: dict the metadata dictionary filename: str the preprocessed model file. """ # Load cube and set up units cube = iris.load_cube(filename) cube = diagtools.bgc_units(cube, metadata['short_name']) # Is this data is a multi-model dataset? multi_model = metadata['dataset'].find('MultiModel') > -1 # Make a dict of cubes for each layer. cubes = diagtools.make_cube_layer_dict(cube) # Load image format extention and threshold.thresholds. image_extention = diagtools.get_image_format(cfg) # Load threshold/thresholds. plot_details = {} colours = [] thresholds = diagtools.load_thresholds(cfg, metadata) for itr, thres in enumerate(thresholds): if len(thresholds) > 1: colour = plt.cm.jet(float(itr) / float(len(thresholds) - 1.)) else: colour = plt.cm.jet(0) label = str(thres) + ' ' + str(cube.units) colours.append(colour) plot_details[thres] = {'c': colour, 'lw': 1, 'ls': '-', 'label': label} linewidths = [1 for thres in thresholds] linestyles = ['-' for thres in thresholds] # Making plots for each layer for layer_index, (layer, cube_layer) in enumerate(cubes.items()): layer = str(layer) qplt.contour(cube_layer, thresholds, colors=colours, linewidths=linewidths, linestyles=linestyles, rasterized=True) try: plt.gca().coastlines() except AttributeError: logger.warning('Not able to add coastlines') try: plt.gca().add_feature(cartopy.feature.LAND, zorder=10, facecolor=[0.8, 0.8, 0.8]) except AttributeError: logger.warning('Not able to add coastlines') # Add legend diagtools.add_legend_outside_right(plot_details, plt.gca(), column_width=0.02, loc='below') # Add title to plot title = ' '.join([metadata['dataset'], metadata['long_name']]) depth_units = str(cube_layer.coords('depth')[0].units) if layer: title = '{} ({} {})'.format(title, layer, depth_units) plt.title(title) # Determine image filename: if multi_model: path = os.path.join(diagtools.folder(cfg['plot_dir']), os.path.basename(filename)) path = path.replace('.nc', '_contour_map_' + str(layer_index)) path = path + image_extention else: path = diagtools.get_image_path( cfg, metadata, suffix='_contour_map_' + str(layer_index) + image_extention, ) # Saving files: if cfg['write_plots']: logger.info('Saving plots to %s', path) plt.savefig(path) plt.close()
def make_scatter(cfg, metadata, model_filename, obs_filename): """ Makes Scatter plots of model vs observational data. Make scatter plot showing the matched model and observational data with the model data as the x-axis coordinate and the observational data as the y-axis coordinate. A linear regression is also applied to the matched data and the result of the fit is shown on the figure. Parameters ---------- cfg: dict the opened global config dictionairy, passed by ESMValTool. metadata: dict the input files dictionairy model_filename: str the preprocessed model file. obs_filename: str the preprocessed observations file. """ filenames = {'model': model_filename, 'obs': obs_filename} logger.debug('make_model_vs_obs_plots: \t%s', filenames) # #### # Load the data for each layer as a separate cube layers = {} cubes = {} for model_type, input_file in filenames.items(): logger.debug('loading: \t%s, \t%s', model_type, input_file) cube = iris.load_cube(input_file) cube = diagtools.bgc_units(cube, metadata[input_file]['short_name']) cubes[model_type] = diagtools.make_cube_layer_dict(cube) for layer in cubes[model_type]: layers[layer] = True logger.debug('layers: %s', layers) logger.debug('cubes: %s', ', '.join(cubes)) # #### # load names: model = metadata[filenames['model']]['dataset'] obs = metadata[filenames['obs']]['dataset'] long_name = cubes['model'][list(layers.keys())[0]].long_name # Load image format extention image_extention = diagtools.get_image_format(cfg) # Make a plot for each layer for layer in layers: fig = plt.figure() fig.set_size_inches(7, 6) # Create the cubes model_data = np.ma.array(cubes['model'][layer].data) obs_data = np.ma.array(cubes['obs'][layer].data) mask = model_data.mask + obs_data.mask model_data = np.ma.masked_where(mask, model_data).compressed() obs_data = np.ma.masked_where(mask, obs_data).compressed() colours = 'gist_yarg' zrange = diagtools.get_array_range([model_data, obs_data]) plotrange = [zrange[0], zrange[1], zrange[0], zrange[1]] x_scale = 'log' if np.min(zrange) * np.max(zrange) < -1: x_scale = 'linear' if np.min(zrange) < 0.: logger.info('Skip scatter for %s. Min is < 0', long_name) return pyplot.hexbin( model_data, obs_data, xscale=x_scale, yscale=x_scale, bins='log', # extent=np.log10(plotrange), gridsize=50, cmap=pyplot.get_cmap(colours), mincnt=0) cbar = pyplot.colorbar() cbar.set_label('log10(N)') pyplot.gca().set_aspect("equal") pyplot.axis(plotrange) add_linear_regression(pyplot.gca(), model_data, obs_data, showtext=True, add_diagonal=True, extent=plotrange) pyplot.title(long_name) pyplot.xlabel(model) pyplot.ylabel(obs) # Determine image filename: fn_list = [ 'model_vs_obs', long_name, model, obs, str(layer), 'scatter' ] path = diagtools.folder(cfg['plot_dir']) + '_'.join(fn_list) path = path.replace(' ', '') + image_extention # Saving files: if cfg['write_plots']: logger.info('Saving plots to %s', path) plt.savefig(path) plt.close()
def make_model_vs_obs_plots(cfg, metadata, model_filename, obs_filename): """ Make a figure showing four maps and the other shows a scatter plot. The four pane image is a latitude vs longitude figures showing: * Top left: model * Top right: observations * Bottom left: model minus observations * Bottom right: model over observations Parameters ---------- cfg: dict the opened global config dictionairy, passed by ESMValTool. metadata: dict the input files dictionairy model_filename: str the preprocessed model file. obs_filename: str the preprocessed observations file. """ filenames = {'model': model_filename, 'obs': obs_filename} logger.debug('make_model_vs_obs_plots filenames: %s', filenames) # #### # Load the data for each layer as a separate cube input_file = None layers = {} cubes = {} for model_type, input_file in filenames.items(): logger.debug('loading: \t%s, \t%s', model_type, input_file) cube = iris.load_cube(input_file) cube = diagtools.bgc_units(cube, metadata[input_file]['short_name']) cubes[model_type] = diagtools.make_cube_layer_dict(cube) for layer in cubes[model_type]: layers[layer] = True logger.debug('layers: %s', layers) logger.debug('cubes: %s', ', '.join(cubes.keys())) # #### # load names: model = metadata[filenames['model']]['dataset'] obs = metadata[filenames['obs']]['dataset'] long_name = cubes['model'][list(layers.keys())[0]].long_name units = str(cubes['model'][list(layers.keys())[0]].units) # Load image format extention image_extention = diagtools.get_image_format(cfg) # Make a plot for each layer for layer in layers: fig = plt.figure() fig.set_size_inches(9, 6) # Create the cubes cube221 = cubes['model'][layer] cube222 = cubes['obs'][layer] cube223 = cubes['model'][layer] - cubes['obs'][layer] cube224 = cubes['model'][layer] / cubes['obs'][layer] # create the z axis for plots 2, 3, 4. extend = 'neither' zrange12 = diagtools.get_cube_range([cube221, cube222]) if 'maps_range' in metadata[input_file]: zrange12 = metadata[input_file]['maps_range'] extend = 'both' zrange3 = diagtools.get_cube_range_diff([cube223]) if 'diff_range' in metadata[input_file]: zrange3 = metadata[input_file]['diff_range'] extend = 'both' cube224.data = np.ma.clip(cube224.data, 0.1, 10.) n_points = 12 linspace12 = np.linspace(zrange12[0], zrange12[1], n_points, endpoint=True) linspace3 = np.linspace(zrange3[0], zrange3[1], n_points, endpoint=True) logspace4 = np.logspace(-1., 1., 12, endpoint=True) # Add the sub plots to the figure. add_map_subplot(221, cube221, linspace12, cmap='viridis', title=model, extend=extend) add_map_subplot(222, cube222, linspace12, cmap='viridis', title=' '.join([obs]), extend=extend) add_map_subplot(223, cube223, linspace3, cmap='bwr', title=' '.join([model, 'minus', obs]), extend=extend) if np.min(zrange12) > 0.: add_map_subplot(224, cube224, logspace4, cmap='bwr', title=' '.join([model, 'over', obs]), log=True) # Add overall title fig.suptitle(long_name + ' [' + units + ']', fontsize=14) # Determine image filename: fn_list = ['model_vs_obs', long_name, model, obs, str(layer), 'maps'] path = diagtools.folder(cfg['plot_dir']) + '_'.join(fn_list) path = path.replace(' ', '') + image_extention # Saving files: if cfg['write_plots']: logger.info('Saving plots to %s', path) plt.savefig(path, dpi=200) plt.close()
def multi_model_maps( cfg, input_files, ): """ Make the four pane model vs model vs obs comparison plot. Parameters ---------- cfg: dict the opened global config dictionairy, passed by ESMValTool. input_files: dict the metadata dictionairy """ filenames = {} ctl_key = 'control_model' exp_key = 'exper_model' obs_key = 'observational_dataset' model_types = [ctl_key, exp_key, obs_key] for model_type in model_types: logger.debug(model_type, cfg[model_type]) filenames[model_type] = diagtools.match_model_to_key( model_type, cfg[model_type], input_files) # #### # Load the data for each layer as a separate cube layers = {} cubes = {} for model_type, input_file in filenames.items(): cube = iris.load_cube(input_file) cube = diagtools.bgc_units(cube, input_files[input_file]['short_name']) cubes[model_type] = diagtools.make_cube_layer_dict(cube) for layer in cubes[model_type]: layers[layer] = True logger.debug('layers: %s', ', '.join(layers)) logger.debug('cubes: %s', ', '.join(cubes.keys())) # #### # load names: exper = input_files[filenames[exp_key]]['dataset'] control = input_files[filenames[ctl_key]]['dataset'] obs = input_files[filenames[obs_key]]['dataset'] long_name = cubes[exp_key][list(layers.keys())[0]].long_name # Load image format extention image_extention = diagtools.get_image_format(cfg) # Make a plot for each layer for layer in layers: fig = plt.figure() fig.set_size_inches(9, 6) # Create the cubes cube221 = cubes[exp_key][layer] cube222 = cubes[exp_key][layer] - cubes[ctl_key][layer] cube223 = cubes[ctl_key][layer] - cubes[obs_key][layer] cube224 = cubes[exp_key][layer] - cubes[obs_key][layer] # create the z axis for plots 2, 3, 4. zrange1 = diagtools.get_cube_range([ cube221, ]) zrange2 = diagtools.get_cube_range_diff([cube222, cube223, cube224]) linspace1 = np.linspace(zrange1[0], zrange1[1], 12, endpoint=True) linspace2 = np.linspace(zrange2[0], zrange2[1], 12, endpoint=True) # Add the sub plots to the figure. add_map_subplot(221, cube221, linspace1, cmap='viridis', title=exper) add_map_subplot(222, cube222, linspace2, cmap='bwr', title=' '.join([exper, 'minus', control])) add_map_subplot(223, cube223, linspace2, cmap='bwr', title=' '.join([control, 'minus', obs])) add_map_subplot(224, cube224, linspace2, cmap='bwr', title=' '.join([exper, 'minus', obs])) # Add overall title fig.suptitle(long_name, fontsize=14) # Determine image filename: fn_list = [long_name, exper, control, obs, str(layer)] path = diagtools.folder(cfg['plot_dir']) + '_'.join(fn_list) path = path.replace(' ', '') + image_extention # Saving files: if cfg['write_plots']: logger.info('Saving plots to %s', path) plt.savefig(path) plt.close()