def plot(self): gs, fig, velocity = self.gridSetup() # Plot the transect on a map if self.showmap: plt.subplot(gs[0, 0]) utils.path_plot(self.transect_data['points']) # Args: # subplots: a GridSpec object (gs) # map_subplot: Row number (Note: don't use consecutive rows to allow # for expanding figure height) # data: Data to be plotted # name: subplot title # cmapLabel: label for colourmap legend # vmin: minimum value for a variable (grabbed from the lowest value of some data) # vmax: maxmimum value for a variable (grabbed from the highest value of some data)onstrate a networked Ope # units: units for variable (PSU, Celsius, etc) # cmap: colormap for variable # def do_plot(subplots, map_subplot, data, name, cmapLabel, vmin, vmax, units, cmap): plt.subplot(subplots[map_subplot[0], map_subplot[1]]) divider = self._transect_plot(data, self.depth, name, vmin, vmax, cmapLabel, units, cmap) if self.surface: self._surface_plot(divider) """ Finds and returns the correct min/max values for the variable scale Args: scale: scale for the left or Right Map (self.scale or self.compare['scale]) data: transect_data Returns: (min, max) """ def find_minmax(scale, data): if scale: return (scale[0], scale[1]) else: return (np.amin(data), np.amax(data)) # Creates and places the plots def velocity_plot(): Row = 0 if self.showmap: Col = 1 else: Col = 0 if self.selected_velocity_plots[0] == 1: do_plot( gs, [Row, Col], self.transect_data['magnitude'], gettext("Magnitude") + gettext(" for ") + self.date_formatter(self.timestamp), gettext("Magnitude"), vmin, vmax, self.transect_data['unit'], self.cmap) Row += 1 if self.selected_velocity_plots[1] == 1: do_plot( gs, [Row, Col], self.transect_data['parallel'], self.transect_data['name'] + " (" + gettext("Parallel") + ")" + gettext(" for ") + self.date_formatter(self.timestamp), gettext("Parallel"), vmin, vmax, self.transect_data['unit'], self.cmap) Row += 1 if self.selected_velocity_plots[2] == 1: do_plot( gs, [Row, Col], self.transect_data['perpendicular'], self.transect_data['name'] + " (" + gettext("Perpendicular") + ")" + gettext(" for ") + self.date_formatter(self.timestamp), gettext("Perpendicular"), vmin, vmax, self.transect_data['unit'], self.cmap) # Plot Transects # If in compare mode Type = ['magnitude', 'parallel', 'perpendicular'] if self.compare: # Velocity has 2 components if velocity: if self.scale: vmin = self.scale[0] vmax = self.scale[1] else: vmin = min(np.amin(self.transect_data['parallel']), np.amin(self.transect_data['perpendicular'])) vmax = max(np.amax(self.transect_data['parallel']), np.amin(self.transect_data['perpendicular'])) vmin = min(vmin, -vmax) vmax = max(vmax, -vmin) # Get colormap for variable if self.showmap: Col = 1 else: Col = 0 do_plot( gs, [0, Col], self.transect_data['parallel'], self.transect_data['name'] + " (" + gettext("Parallel") + ")" + gettext(" for ") + self.date_formatter(self.timestamp), gettext("Parallel"), vmin, vmax, self.transect_data['unit'], self.cmap) Col += 1 do_plot( gs, [0, Col], self.transect_data['perpendicular'], self.transect_data['name'] + " (" + gettext("Perpendicular") + ")" + gettext(" for ") + self.date_formatter(self.timestamp), gettext("Perpendicular"), vmin, vmax, self.transect_data['unit'], self.cmap) if len(self.compare['variables']) == 2: if self.compare['scale']: vmin = self.compare['scale'][0] vmax = self.compare['scale'][1] else: vmin = min(np.amin(self.compare['parallel']), np.amin(self.compare['perpendicular'])) vmax = max(np.amax(self.compare['parallel']), np.amin(self.compare['perpendicular'])) vmin = min(vmin, -vmax) vmax = max(vmax, -vmin) # Get colormap for variable cmap = colormap.find_colormap(self.compare['colormap']) if self.showmap: Col = 1 else: Col = 0 do_plot( gs, [1, Col], self.compare['parallel'], self.transect_data['name'] + " (" + gettext("Parallel") + ")" + gettext(" for ") + self.date_formatter(self.compare['date']), gettext("Parallel"), vmin, vmax, self.transect_data['unit'], cmap) Col += 1 do_plot( gs, [1, Col], self.compare['perpendicular'], self.transect_data['name'] + " (" + gettext("Perpendicular") + ")" + gettext(" for ") + self.date_formatter(self.compare['date']), gettext("Perpendicular"), vmin, vmax, self.transect_data['unit'], cmap) else: vmin, vmax = utils.normalize_scale( self.transect_data['data'], self.dataset_config.variable[self.variables[0]]) # Render primary/Left Map if self.showmap: Col = 1 else: Col = 0 do_plot( gs, [0, Col], self.transect_data['data'], self.transect_data['name'] + gettext(" for ") + self.date_formatter(self.timestamp), self.transect_data['name'], vmin, vmax, self.transect_data['unit'], self.cmap) # Render Right Map vmin, vmax = utils.normalize_scale( self.transect_data['compare_data'], self.compare_config.variable[",".join( self.compare['variables'])]) if self.showmap: Col = 1 else: Col = 0 do_plot( gs, [1, Col], self.transect_data['compare_data'], self.compare['name'] + gettext(" for ") + self.date_formatter(self.compare['date']), self.compare['name'], vmin, vmax, self.compare['unit'], self.compare['colormap']) # Show a difference plot if both variables and datasets are the same if self.variables[0] == self.compare['variables'][0]: self.transect_data['difference'] = self.transect_data['data'] - \ self.transect_data['compare_data'] # Calculate variable range if self.compare['scale_diff'] is not None: vmin = self.compare['scale_diff'][0] vmax = self.compare['scale_diff'][1] else: vmin, vmax = find_minmax( self.compare['scale_diff'], self.transect_data['difference']) vmin = min(vmin, -vmax) vmax = max(vmax, -vmin) if self.showmap: Col = 1 else: Col = 0 do_plot( gs, [2, Col], self.transect_data['difference'], self.transect_data['name'] + gettext(" Difference"), self.transect_data['name'], vmin, vmax, self.transect_data[ 'unit'], # Since both variables are the same doesn't matter which view we reference colormap.find_colormap( self.compare['colormap_diff'] ) # Colormap for difference graphs ) # Not comparing else: # Velocity has 3 possible components if velocity: if self.scale: vmin = self.scale[0] vmax = self.scale[1] else: vmin = min(np.amin(self.transect_data['magnitude']), np.amin(self.transect_data['parallel']), np.amin(self.transect_data['perpendicular'])) vmax = max(np.amax(self.transect_data['magnitude']), np.amax(self.transect_data['parallel']), np.amin(self.transect_data['perpendicular'])) vmin = min(vmin, -vmax) vmax = max(vmax, -vmin) Row = 0 velocity_plot() # All other variables have 1 component else: if self.showmap: Col = 1 else: Col = 0 if self.scale: vmin = self.scale[0] vmax = self.scale[1] else: vmin, vmax = utils.normalize_scale( self.transect_data['data'], self.dataset_config.variable[self.variables[0]]) do_plot( gs, [0, Col], self.transect_data['data'], self.transect_data['name'] + " for " + self.date_formatter(self.timestamp), self.transect_data['name'], vmin, vmax, self.transect_data['unit'], self.cmap) # Figure title if self.plotTitle is None or self.plotTitle == "": fig.suptitle("Transect Data for:\n%s" % (self.name), fontsize=15) else: fig.suptitle(self.plotTitle, fontsize=15) # Subplot padding fig.tight_layout(pad=2, w_pad=2, h_pad=2) fig.subplots_adjust(top=0.90 if self.compare else 0.85) return super(TransectPlotter, self).plot(fig)
def plot(self): if self.showmap: width = 2 width_ratios = [2, 7] else: width = 1 width_ratios = [1] numplots = len(self.variables) + len(self.buoyvariables) if "votemper" in self.variables and "sst" in self.buoyvariables: numplots -= 1 if self.latlon: numplots += 2 figuresize = list(map(float, self.size.split("x"))) figuresize[1] *= numplots fig = plt.figure(figsize=figuresize, dpi=self.dpi) gs = gridspec.GridSpec(numplots, width, width_ratios=width_ratios) if self.showmap: # Plot the path on a map if numplots > 1: plt.subplot(gs[:, 0]) else: plt.subplot(gs[0]) utils.path_plot(self.points[self.start:self.end].transpose(), False) # Plot observed if self.showmap: subplot = 1 subplot_inc = 2 else: subplot = 0 subplot_inc = 1 for j, v in enumerate(self.buoyvariables): ax = plt.subplot(gs[subplot]) subplot += subplot_inc ax.plot(self.times[self.start:self.end], self.data[j][self.start:self.end]) if v == 'sst' and 'votemper' in self.variables: i = self.variables.index('votemper') plt.plot(self.model_times, self.model_data[i]) legend = [self.name] if v == 'sst' and 'votemper' in self.variables: legend = legend + ["%s (Modelled)" % self.name] if 'votemper' in self.variables and v == 'sst': legend = [gettext("Observed"), gettext("Modelled")] if len(legend) > 1: leg = plt.legend(legend, loc='best') for legobj in leg.legendHandles: legobj.set_linewidth(4.0) if self.data_units[j] is not None: plt.ylabel( "%s (%s)" % (self.data_names[j], utils.mathtext(self.data_units[j]))) else: plt.ylabel(self.data_names[j]), plt.setp(ax.get_xticklabels(), rotation=30) for idx, v in enumerate(self.variables): if v == 'votemper' and 'sst' in self.buoyvariables: continue if np.isnan(self.model_data[idx]).all(): continue ax = plt.subplot(gs[subplot]) subplot += subplot_inc ax.plot(self.model_times, self.model_data[idx]) plt.ylabel("%s (%s)" % (self.variable_names[idx], utils.mathtext(self.variable_units[idx]))) plt.setp(ax.get_xticklabels(), rotation=30) # latlon if self.latlon: for j, label in enumerate([ gettext("Latitude (degrees)"), gettext("Longitude (degrees)") ]): plt.subplot(gs[subplot]) subplot += subplot_inc plt.plot(self.times[self.start:self.end], self.points[self.start:self.end, j]) plt.ylabel(label) plt.setp(plt.gca().get_xticklabels(), rotation=30) fig.suptitle( gettext("Drifter Plot (IMEI: %s, WMO: %s)") % (self.imei, self.wmo)) fig.tight_layout(pad=3, w_pad=4) return super(DrifterPlotter, self).plot(fig)
def plot(self): def get_depth_label(depthValue, depthUnit): if depthValue == "bottom": return " at Bottom" return " at %s %s" % (depthValue, depthUnit) # Figure size figuresize = list(map(float, self.size.split("x"))) # Vertical scaling of figure figuresize[1] *= 1.5 if self.compare else 1 fig = plt.figure(figsize=figuresize, dpi=self.dpi) if self.showmap: width = 2 # 2 columns width_ratios = [2, 7] else: width = 1 # 1 column width_ratios = [1] # Setup grid (rows, columns, column/row ratios) depending on view mode if self.compare: # Don't show a difference plot if variables are different if self.compare["variables"][0] == self.variables[0]: gs = gridspec.GridSpec(3, width, width_ratios=width_ratios, height_ratios=[1, 1, 1]) else: gs = gridspec.GridSpec(2, width, width_ratios=width_ratios, height_ratios=[1, 1]) else: gs = gridspec.GridSpec(1, width, width_ratios=width_ratios) if self.showmap: # Plot the path on a map utils.path_plot(self.path_points, gs[:, 0]) # Calculate variable range if self.scale: vmin = self.scale[0] vmax = self.scale[1] else: vmin, vmax = utils.normalize_scale( self.data, self.dataset_config.variable[self.variables[0]]) if len(self.variables) > 1: vmin = 0 # Render self._hovmoller_plot( gs, [0, 1], [0, 0], gettext(self.variable_name), vmin, vmax, self.data, self.iso_timestamps, self.cmap, self.variable_unit, gettext(self.variable_name) + gettext(get_depth_label(self.depth_value, self.depth_unit)), ) # If in compare mode if self.compare: # Calculate variable range if self.compare["scale"]: vmin = self.compare["scale"][0] vmax = self.compare["scale"][1] else: vmin = np.amin(self.compare["data"]) vmax = np.amax(self.compare["data"]) if np.any([ re.search(x, self.compare["variable_name"], re.IGNORECASE) for x in ["velocity", "surface height", "wind"] ]): vmin = min(vmin, -vmax) vmax = max(vmax, -vmin) if len(self.compare["variables"]) > 1: vmin = 0 self._hovmoller_plot( gs, [1, 1], [1, 0], gettext(self.compare["variable_name"]), vmin, vmax, self.compare["data"], self.compare["times"], self.compare["colormap"], self.compare["variable_unit"], gettext(self.compare["variable_name"]) + gettext( get_depth_label(self.compare["depth"], self.compare["depth_unit"])), ) # Difference plot if self.compare["variables"][0] == self.variables[0]: data_difference = self.data - self.compare["data"] vmin = np.amin(data_difference) vmax = np.amax(data_difference) self._hovmoller_plot( gs, [2, 1], [2, 0], gettext(self.compare["variable_name"]), vmin, vmax, data_difference, self.compare["times"], colormap.find_colormap("anomaly"), self.compare["variable_unit"], gettext(self.compare["variable_name"]) + gettext(" Difference") + gettext( get_depth_label(self.compare["depth"], self.compare["depth_unit"])), ) # Image title if self.plotTitle: fig.suptitle(gettext("Hovm\xf6ller Diagram(s) for:\n%s") % (self.name), fontsize=15) else: fig.suptitle(self.plotTitle, fontsize=15) # Subplot padding fig.tight_layout(pad=0, w_pad=4, h_pad=2) fig.subplots_adjust(top=0.9 if self.compare else 0.85) return super(HovmollerPlotter, self).plot(fig)
def plot(self): if self.showmap: width = 2 width_ratios = [3, 7] else: width = 1 width_ratios = [1] numplots = len(self.variables) + len(self.trackvariables) if "votemper" in self.variables and "sst" in self.trackvariables: numplots -= 1 if self.latlon: numplots += 2 figuresize = list(map(float, self.size.split("x"))) figuresize[1] *= numplots fig = plt.figure(figsize=figuresize, dpi=self.dpi) gs = gridspec.GridSpec(numplots, width, width_ratios=width_ratios) if self.showmap: # Plot the path on a map if numplots > 1: plt.subplot(gs[:, 0]) else: plt.subplot(gs[0]) utils.path_plot(self.points.transpose(), False) # Plot observed if self.showmap: subplot = 1 subplot_inc = 2 else: subplot = 0 subplot_inc = 1 for j, v in enumerate(self.trackvariables): ax = plt.subplot(gs[subplot]) subplot += subplot_inc # Is the depth changing? if len(np.unique(self.depth)) == 1: ax.plot(self.distances, self.data[j]) ax.set_xlim(self.distances[0], self.distances[-1]) ax.set_xlabel("Distance (km)") else: self.data[j, np.where(self.depth <= 0)] = np.nan RES = (50, 100) dd = np.empty((RES[0] + 1, RES[1] + 1)) dd[:, :] = np.nan x = np.linspace(0, max(self.distances), RES[1]) y = np.linspace(0, max(self.depth), RES[0]) di = np.digitize(self.distances, x) de = np.digitize(self.depth, y) co = np.array(list(zip(di, de))) dd[co[:, 1], co[:, 0]] = self.data[j] c = ax.pcolormesh(x, y, np.ma.masked_invalid(dd[:-1, :-1]), cmap=self.track_cmaps[j], shading='gouraud') ax.set_xlim(0, max(self.distances)) ax.invert_yaxis() ax.set_xlabel("Distance (km)") ax.set_ylim(max(self.depth), 0) divider = make_axes_locatable(ax) cax = divider.append_axes("right", size="5%", pad="5%") bar = plt.colorbar(c, cax=cax) legend = [self.name] if len(legend) > 1: leg = plt.legend(legend, loc='best') for legobj in leg.legendHandles: legobj.set_linewidth(4.0) if len(np.unique(self.depth)) == 1: if self.data_units[j] is not None: ax.set_ylabel("%s (%s)" % (self.data_names[j], utils.mathtext(self.data_units[j]))) else: ax.set_ylabel(self.data_names[j]) else: if self.data_units[j] is not None: bar.set_label("%s (%s)" % (self.data_names[j], utils.mathtext(self.data_units[j]))) else: bar.set_label(self.data_names[j]) ax.set_ylabel("Depth (m)") for idx, v in enumerate(self.variables): if np.isnan(self.model_data[idx]).all(): continue ax = plt.subplot(gs[subplot]) subplot += subplot_inc if len(np.unique(self.depth)) > 1: mdist = np.linspace(0, self.model_dist[-1], 100) f = interp1d( self.model_dist, self.model_data[idx], assume_sorted=True, bounds_error=False, ) mdata = f(mdist) mdata = np.ma.masked_invalid(mdata) mdata = np.ma.masked_greater(mdata, mdata.fill_value) c = ax.pcolormesh( mdist, self.model_depths, mdata, cmap=self.cmaps[idx], shading='gouraud', ) ax.invert_yaxis() ax.set_ylim(max(self.depth), 0) divider = make_axes_locatable(ax) cax = divider.append_axes("right", size="5%", pad="5%") bar = plt.colorbar(c, cax=cax) else: ax.plot(self.model_dist, self.model_data[idx]) ax.set_xlim( self.model_dist[0], self.model_dist[-1], ) ax.set_xlabel("Distance (km)") if len(np.unique(self.depth)) > 1: ax.set_ylabel("Depth (m)") bar.set_label("%s (%s)" % (self.variable_names[idx], utils.mathtext(self.variable_units[idx]))) else: ax.set_ylabel("%s (%s)" % (self.variable_names[idx], utils.mathtext(self.variable_units[idx]))) plt.setp(ax.get_xticklabels(), rotation=30) # latlon if self.latlon: for j, label in enumerate([ gettext("Latitude (degrees)"), gettext("Longitude (degrees)") ]): plt.subplot(gs[subplot]) subplot += subplot_inc plt.plot(self.times, self.points[:, j]) plt.ylabel(label) plt.setp(plt.gca().get_xticklabels(), rotation=30) fig.suptitle( gettext("Track Plot (Observed %s - %s, Modelled %s - %s)") % (self.times[0].strftime("%Y-%m-%d"), self.times[-1].strftime("%Y-%m-%d"), self.model_times[0].strftime("%Y-%m-%d"), self.model_times[-1].strftime("%Y-%m-%d"))) fig.tight_layout(pad=3, w_pad=4) return super().plot(fig)