def _plot_latlon(self, remappedModelClimatology, remappedRefClimatology): # {{{ """ plotting a global lat-lon data set """ season = self.season config = self.config configSectionName = self.configSectionName mainRunName = config.get('runs', 'mainRunName') modelOutput = nans_to_numpy_mask( remappedModelClimatology[self.mpasFieldName].values) lon = remappedModelClimatology['lon'].values lat = remappedModelClimatology['lat'].values lonTarg, latTarg = np.meshgrid(lon, lat) if remappedRefClimatology is None: refOutput = None bias = None else: refOutput = nans_to_numpy_mask( remappedRefClimatology[self.refFieldName].values) bias = modelOutput - refOutput filePrefix = self.filePrefix outFileName = '{}/{}.png'.format(self.plotsDirectory, filePrefix) title = '{} ({}, years {:04d}-{:04d})'.format( self.fieldNameInTitle, season, self.startYear, self.endYear) plot_global_comparison(config, lonTarg, latTarg, modelOutput, refOutput, bias, configSectionName, fileout=outFileName, title=title, modelTitle='{}'.format(mainRunName), refTitle=self.refTitleLabel, diffTitle=self.diffTitleLabel, cbarlabel=self.unitsLabel) caption = '{} {}'.format(season, self.imageCaption) write_image_xml( config, filePrefix, componentName='Ocean', componentSubdirectory='ocean', galleryGroup='Global {}'.format(self.galleryGroup), groupSubtitle=self.groupSubtitle, groupLink='global_{}'.format(self.groupLink), gallery=self.galleryName, thumbnailDescription=self.thumbnailDescription, imageDescription=caption, imageCaption=caption)
def _plot_antarctic(self, remappedModelClimatology, remappedRefClimatology): # {{{ """ plotting an Antarctic data set """ season = self.season comparisonGridName = self.comparisonGridName config = self.config configSectionName = self.configSectionName mainRunName = config.get('runs', 'mainRunName') oceanMask = remappedModelClimatology['validMask'].values self.landMask = np.ma.masked_array(np.ones(oceanMask.shape), mask=np.logical_not( np.isnan(oceanMask))) modelOutput = nans_to_numpy_mask( remappedModelClimatology[self.mpasFieldName].values) if remappedRefClimatology is None: refOutput = None bias = None else: refOutput = nans_to_numpy_mask( remappedRefClimatology[self.refFieldName].values) bias = modelOutput - refOutput x = interp_extrap_corner(remappedModelClimatology['x'].values) y = interp_extrap_corner(remappedModelClimatology['y'].values) filePrefix = self.filePrefix outFileName = '{}/{}.png'.format(self.plotsDirectory, filePrefix) title = '{} ({}, years {:04d}-{:04d})'.format(self.fieldNameInTitle, season, self.startYear, self.endYear) plot_polar_projection_comparison(config, x, y, self.landMask, modelOutput, refOutput, bias, fileout=outFileName, colorMapSectionName=configSectionName, title=title, modelTitle='{}'.format(mainRunName), refTitle=self.refTitleLabel, diffTitle=self.diffTitleLabel, cbarlabel=self.unitsLabel) upperGridName = comparisonGridName[0].upper() + comparisonGridName[1:] caption = '{} {}'.format(season, self.imageCaption) write_image_xml(config, filePrefix, componentName='Ocean', componentSubdirectory='ocean', galleryGroup='{} {}'.format(upperGridName, self.galleryGroup), groupSubtitle=self.groupSubtitle, groupLink=self.groupLink, gallery=self.galleryName, thumbnailDescription=self.thumbnailDescription, imageDescription=caption, imageCaption=caption)
def _plot_transect(self, remappedModelClimatology, remappedRefClimatology): # {{{ """ plotting the transect """ season = self.season config = self.config configSectionName = self.configSectionName mainRunName = config.get('runs', 'mainRunName') # broadcast x and z to have the same dimensions x, z = xr.broadcast(remappedModelClimatology.x, remappedModelClimatology.z) # convert x and z to numpy arrays, make a copy because they are # sometimes read-only (not sure why) x = x.values.copy().transpose() z = z.values.copy().transpose() # z is masked out with NaNs in some locations (where there is land) but # this makes pcolormesh unhappy so we'll zero out those locations z[numpy.isnan(z)] = 0. modelOutput = nans_to_numpy_mask( remappedModelClimatology[self.mpasFieldName].values) modelOutput = modelOutput.transpose() if remappedRefClimatology is None: refOutput = None bias = None else: refOutput = remappedRefClimatology[self.refFieldName] dims = refOutput.dims refOutput = nans_to_numpy_mask(refOutput.values) if dims[1] != 'nPoints': assert (dims[0] == 'nPoints') refOutput = refOutput.transpose() bias = modelOutput - refOutput filePrefix = self.filePrefix outFileName = '{}/{}.png'.format(self.plotsDirectory, filePrefix) title = '{}\n({}, years {:04d}-{:04d})'.format(self.fieldNameInTitle, season, self.startYear, self.endYear) # construct a three-panel comparison plot for the transect xLabel = 'Distance [km]' yLabel = 'Depth [m]' plot_vertical_section_comparison(config, x, z, modelOutput, refOutput, bias, outFileName, configSectionName, cbarLabel=self.unitsLabel, xlabel=xLabel, ylabel=yLabel, title=title, modelTitle='{}'.format(mainRunName), refTitle=self.refTitleLabel, diffTitle=self.diffTitleLabel, invertYAxis=False, backgroundColor='#918167') caption = '{} {}'.format(season, self.imageCaption) write_image_xml(config, filePrefix, componentName='Ocean', componentSubdirectory='ocean', galleryGroup=self.galleryGroup, groupSubtitle=self.groupSubtitle, groupLink=self.groupLink, gallery=self.galleryName, thumbnailDescription=self.thumbnailDescription, imageDescription=caption, imageCaption=caption)
def _plot_transect(self, remappedModelClimatology, remappedRefClimatology): # {{{ """ plotting the transect """ season = self.season config = self.config configSectionName = self.configSectionName mainRunName = config.get('runs', 'mainRunName') # broadcast x and z to have the same dimensions x, z = xr.broadcast(remappedModelClimatology.x, remappedModelClimatology.z) # set lat and lon in case we want to plot versus these quantities lat = remappedModelClimatology.lat lon = remappedModelClimatology.lon # convert x, z, lat, and lon to numpy arrays; make a copy because # they are sometimes read-only (not sure why) x = x.values.copy().transpose() z = z.values.copy().transpose() lat = lat.values.copy().transpose() lon = lon.values.copy().transpose() self.lat = lat self.lon = lon # This will do strange things at the antemeridian but there's little # we can do about that. lon_pm180 = numpy.mod(lon + 180., 360.) - 180. if self.horizontalBounds is not None: mask = numpy.logical_and( remappedModelClimatology.x.values >= self.horizontalBounds[0], remappedModelClimatology.x.values <= self.horizontalBounds[1]) inset_lon = lon_pm180[mask] inset_lat = lat[mask] else: inset_lon = lon_pm180 inset_lat = lat fc = FeatureCollection() fc.add_feature({ "type": "Feature", "properties": { "name": self.transectName, "author": 'Xylar Asay-Davis', "object": 'transect', "component": 'ocean', "tags": '' }, "geometry": { "type": "LineString", "coordinates": list(map(list, zip(inset_lon, inset_lat))) } }) # z is masked out with NaNs in some locations (where there is land) but # this makes pcolormesh unhappy so we'll zero out those locations z[numpy.isnan(z)] = 0. modelOutput = nans_to_numpy_mask( remappedModelClimatology[self.mpasFieldName].values) modelOutput = modelOutput.transpose() if remappedRefClimatology is None: refOutput = None bias = None else: refOutput = remappedRefClimatology[self.refFieldName] dims = refOutput.dims refOutput = nans_to_numpy_mask(refOutput.values) if dims[1] != 'nPoints': assert (dims[0] == 'nPoints') refOutput = refOutput.transpose() bias = modelOutput - refOutput filePrefix = self.filePrefix outFileName = '{}/{}.png'.format(self.plotsDirectory, filePrefix) title = '{}\n({}, years {:04d}-{:04d})'.format(self.fieldNameInTitle, season, self.startYear, self.endYear) xLabel = 'Distance [km]' yLabel = 'Depth [m]' # define the axis labels and the data to use for the upper # x axis or axes, if such additional axes have been requested upperXAxes = config.get('transects', 'upperXAxes') numUpperTicks = config.getint('transects', 'numUpperTicks') upperXAxisTickLabelPrecision = config.getint( 'transects', 'upperXAxisTickLabelPrecision') self._set_third_x_axis_to_none() if upperXAxes == 'neither': self._set_second_x_axis_to_none() elif upperXAxes == 'lat': self._set_second_x_axis_to_latitude() elif upperXAxes == 'lon': self._set_second_x_axis_to_longitude() elif upperXAxes == 'both': self._set_second_x_axis_to_longitude() self._set_third_x_axis_to_latitude() elif upperXAxes == 'greatestExtent': if self._greatest_extent(lat, lon): self._set_second_x_axis_to_latitude() else: self._set_second_x_axis_to_longitude() elif upperXAxes == 'strictlyMonotonic': if self._strictly_monotonic(lat, lon): self._set_second_x_axis_to_latitude() else: self._set_second_x_axis_to_longitude() elif upperXAxes == 'mostMonotonic': if self._most_monotonic(lat, lon): self._set_second_x_axis_to_latitude() else: self._set_second_x_axis_to_longitude() elif upperXAxes == 'mostStepsInSameDirection': if self._most_steps_in_same_direction(lat, lon): self._set_second_x_axis_to_latitude() else: self._set_second_x_axis_to_longitude() elif upperXAxes == 'fewestDirectionChanges': if self._fewest_direction_changes(lat, lon): self._set_second_x_axis_to_latitude() else: self._set_second_x_axis_to_longitude() else: raise ValueError('invalid option for upperXAxes') # get the parameters determining what type of plot to use, # what line styles and line colors to use, and whether and how # to label contours compareAsContours = config.getboolean('transects', 'compareAsContoursOnSinglePlot') contourLineStyle = config.get('transects', 'contourLineStyle') contourLineColor = config.get('transects', 'contourLineColor') comparisonContourLineStyle = config.get('transects', 'comparisonContourLineStyle') comparisonContourLineColor = config.get('transects', 'comparisonContourLineColor') if compareAsContours: labelContours = config.getboolean( 'transects', 'labelContoursOnContourComparisonPlots') else: labelContours = config.getboolean('transects', 'labelContoursOnHeatmaps') contourLabelPrecision = config.getint('transects', 'contourLabelPrecision') # construct a three-panel comparison plot for the transect, or a # single-panel contour comparison plot if compareAsContours is True fig, axes, suptitle = plot_vertical_section_comparison( config, x, z, modelOutput, refOutput, bias, configSectionName, cbarLabel=self.unitsLabel, xlabel=xLabel, ylabel=yLabel, title=title, modelTitle='{}'.format(mainRunName), refTitle=self.refTitleLabel, diffTitle=self.diffTitleLabel, secondXAxisData=self.secondXAxisData, secondXAxisLabel=self.secondXAxisLabel, thirdXAxisData=self.thirdXAxisData, thirdXAxisLabel=self.thirdXAxisLabel, numUpperTicks=numUpperTicks, upperXAxisTickLabelPrecision=upperXAxisTickLabelPrecision, invertYAxis=False, backgroundColor='#918167', xLim=self.horizontalBounds, compareAsContours=compareAsContours, lineStyle=contourLineStyle, lineColor=contourLineColor, comparisonContourLineStyle=comparisonContourLineStyle, comparisonContourLineColor=comparisonContourLineColor, labelContours=labelContours, contourLabelPrecision=contourLabelPrecision) # shift the super-title a little to the left to make room for the inset pos = suptitle.get_position() suptitle.set_position((pos[0] - 0.05, pos[1])) # make a red start axis and green end axis to correspond to the dots # in the inset for ax in axes: ax.spines['left'].set_color('red') ax.spines['right'].set_color('green') ax.spines['left'].set_linewidth(4) ax.spines['right'].set_linewidth(4) add_inset(fig, fc, width=1.5, height=1.5, xbuffer=0.1, ybuffer=0.1) savefig(outFileName, tight=False) caption = '{} {}'.format(season, self.imageCaption) write_image_xml(config, filePrefix, componentName='Ocean', componentSubdirectory='ocean', galleryGroup=self.galleryGroup, groupSubtitle=self.groupSubtitle, groupLink=self.groupLink, gallery=self.galleryName, thumbnailDescription=self.thumbnailDescription, imageDescription=caption, imageCaption=caption)
def _plot_transect(self, remappedModelClimatology, remappedRefClimatology): # {{{ """ plotting the transect """ season = self.season config = self.config configSectionName = self.configSectionName mainRunName = config.get('runs', 'mainRunName') # broadcast x and z to have the same dimensions x, z = xr.broadcast(remappedModelClimatology.x, remappedModelClimatology.z) # set lat and lon in case we want to plot versus these quantities lat = remappedModelClimatology.lat lon = remappedModelClimatology.lon # convert x, z, lat, and lon to numpy arrays; make a copy because # they are sometimes read-only (not sure why) x = x.values.copy().transpose() z = z.values.copy().transpose() lat = lat.values.copy().transpose() lon = lon.values.copy().transpose() self.lat = lat self.lon = lon # z is masked out with NaNs in some locations (where there is land) but # this makes pcolormesh unhappy so we'll zero out those locations z[numpy.isnan(z)] = 0. modelOutput = nans_to_numpy_mask( remappedModelClimatology[self.mpasFieldName].values) modelOutput = modelOutput.transpose() if remappedRefClimatology is None: refOutput = None bias = None else: refOutput = remappedRefClimatology[self.refFieldName] dims = refOutput.dims refOutput = nans_to_numpy_mask(refOutput.values) if dims[1] != 'nPoints': assert (dims[0] == 'nPoints') refOutput = refOutput.transpose() bias = modelOutput - refOutput filePrefix = self.filePrefix outFileName = '{}/{}.png'.format(self.plotsDirectory, filePrefix) title = '{}\n({}, years {:04d}-{:04d})'.format(self.fieldNameInTitle, season, self.startYear, self.endYear) xLabel = 'Distance [km]' yLabel = 'Depth [m]' # define the axis labels and the data to use for the upper # x axis or axes, if such additional axes have been requested upperXAxes = config.get('transects', 'upperXAxes') numUpperTicks = config.getint('transects', 'numUpperTicks') upperXAxisTickLabelPrecision = config.getint( 'transects', 'upperXAxisTickLabelPrecision') self._set_third_x_axis_to_none() if upperXAxes == 'neither': self._set_second_x_axis_to_none() elif upperXAxes == 'lat': self._set_second_x_axis_to_latitude() elif upperXAxes == 'lon': self._set_second_x_axis_to_longitude() elif upperXAxes == 'both': self._set_second_x_axis_to_longitude() self._set_third_x_axis_to_latitude() elif upperXAxes == 'greatestExtent': if self._greatest_extent(lat, lon): self._set_second_x_axis_to_latitude() else: self._set_second_x_axis_to_longitude() elif upperXAxes == 'strictlyMonotonic': if self._strictly_monotonic(lat, lon): self._set_second_x_axis_to_latitude() else: self._set_second_x_axis_to_longitude() elif upperXAxes == 'mostMonotonic': if self._most_monotonic(lat, lon): self._set_second_x_axis_to_latitude() else: self._set_second_x_axis_to_longitude() elif upperXAxes == 'mostStepsInSameDirection': if self._most_steps_in_same_direction(lat, lon): self._set_second_x_axis_to_latitude() else: self._set_second_x_axis_to_longitude() elif upperXAxes == 'fewestDirectionChanges': if self._fewest_direction_changes(lat, lon): self._set_second_x_axis_to_latitude() else: self._set_second_x_axis_to_longitude() else: raise ValueError('invalid option for upperXAxes') # get the parameters determining what type of plot to use, # what line styles and line colors to use, and whether and how # to label contours compareAsContours = config.getboolean('transects', 'compareAsContoursOnSinglePlot') contourLineStyle = config.get('transects', 'contourLineStyle') contourLineColor = config.get('transects', 'contourLineColor') comparisonContourLineStyle = config.get('transects', 'comparisonContourLineStyle') comparisonContourLineColor = config.get('transects', 'comparisonContourLineColor') if compareAsContours: labelContours = config.getboolean( 'transects', 'labelContoursOnContourComparisonPlots') else: labelContours = config.getboolean('transects', 'labelContoursOnHeatmaps') contourLabelPrecision = config.getint('transects', 'contourLabelPrecision') # construct a three-panel comparison plot for the transect, or a # single-panel contour comparison plot if compareAsContours is True plot_vertical_section_comparison( config, x, z, modelOutput, refOutput, bias, outFileName, configSectionName, cbarLabel=self.unitsLabel, xlabel=xLabel, ylabel=yLabel, title=title, modelTitle='{}'.format(mainRunName), refTitle=self.refTitleLabel, diffTitle=self.diffTitleLabel, secondXAxisData=self.secondXAxisData, secondXAxisLabel=self.secondXAxisLabel, thirdXAxisData=self.thirdXAxisData, thirdXAxisLabel=self.thirdXAxisLabel, numUpperTicks=numUpperTicks, upperXAxisTickLabelPrecision=upperXAxisTickLabelPrecision, invertYAxis=False, backgroundColor='#918167', compareAsContours=compareAsContours, lineStyle=contourLineStyle, lineColor=contourLineColor, comparisonContourLineStyle=comparisonContourLineStyle, comparisonContourLineColor=comparisonContourLineColor, labelContours=labelContours, contourLabelPrecision=contourLabelPrecision) caption = '{} {}'.format(season, self.imageCaption) write_image_xml(config, filePrefix, componentName='Ocean', componentSubdirectory='ocean', galleryGroup=self.galleryGroup, groupSubtitle=self.groupSubtitle, groupLink=self.groupLink, gallery=self.galleryName, thumbnailDescription=self.thumbnailDescription, imageDescription=caption, imageCaption=caption)