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)
示例#2
0
    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)
示例#4
0
    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)