コード例 #1
0
    def plot(self):
        figuresize = list(map(float, self.size.split("x")))
        fig = plt.figure(figsize=figuresize, dpi=self.dpi)

        width = len(self.variables)

        if self.showmap:
            width += 1  # Shift graphs to the right

        gs = gridspec.GridSpec(2, width)

        subplot = 0

        # Render point location
        if self.showmap:
            plt.subplot(gs[0, subplot])
            subplot += 1
            utils.point_plot(np.array([self.latitude, self.longitude]))
            if len(self.ids) > 1:
                plt.legend(self.ids, loc='best')

        plot_label = ""
        giops_name = "GIOPS"

        for idx, v in enumerate(self.variables):
            plt.subplot(gs[:, subplot])
            subplot += 1

            handles = []
            legend = []
            for i in range(0, len(self.forecast_data)):
                id_label = f"{self.ids[i]} " if len(self.ids) > 1 else ""

                form = '-'
                if self.observed_data[i, idx, :].count() < 3:
                    form = 'o-'

                if self.error in ['climatology', 'observation']:
                    if self.error == 'climatology':
                        plot_label = gettext("Error wrt Climatology")
                        handles.append(
                            plt.plot(
                                self.observed_data[i, idx, :] -
                                self.climatology_data[i, idx, :],
                                self.depths[i], form))
                        legend.append(f"{id_label} {gettext('Observed')}")

                        data = self.climatology_data
                    else:
                        plot_label = gettext("Error wrt Observation")

                        data = self.observed_data

                    handles.append(
                        plt.plot(
                            self.forecast_data[i, idx, :] - data[i, idx, :],
                            self.depths[i], form))
                    legend.append(f"{id_label} {giops_name}")

                    for j, model_name in enumerate(
                            self.additional_model_names):
                        handles.append(
                            plt.plot(
                                self.additional_model_data[j, i, idx, :] -
                                data[i, idx, :], self.depths[i], form))
                        legend.append(f"{id_label} {model_name}")

                    if self.error == 'observation' and self.climatology:
                        handles.append(
                            plt.plot(
                                self.climatology_data[i, idx, :] -
                                self.observed_data[i, idx, :], self.depths[i],
                                form))
                        legend.append(f"{id_label} {gettext('Climatology')}")
                    lim = np.abs(plt.xlim()).max()
                    plt.xlim([-lim, lim])
                else:
                    plot_label = gettext("Class 4")
                    handles.append(
                        plt.plot(self.observed_data[i, idx, :], self.depths[i],
                                 form))
                    legend.append("%s %s" % (id_label, gettext("Observed")))
                    handles.append(
                        plt.plot(self.forecast_data[i, idx, :], self.depths[i],
                                 form))
                    legend.append(f"{id_label} {giops_name}")
                    for j, model_name in enumerate(
                            self.additional_model_names):
                        handles.append(
                            plt.plot(self.additional_model_data[j, i, idx, :],
                                     self.depths[i], form))
                        legend.append(f"{id_label} {model_name}")

                    if self.climatology:
                        handles.append(
                            plt.plot(self.climatology_data[i, idx, :],
                                     self.depths[i], form))
                        legend.append(f"{id_label} {gettext('Climatology')}")

            plt.xlim([np.floor(plt.xlim()[0]), np.ceil(plt.xlim()[1])])

            plt.gca().xaxis.set_label_position('top')
            plt.gca().xaxis.set_ticks_position('top')
            plt.xlabel(f"{v} ({utils.mathtext(self.variable_units[idx])})",
                       fontsize=14)
            plt.gca().invert_yaxis()
            plt.ylabel(gettext(f"Depth ({utils.mathtext(self.depth_unit)})"),
                       fontsize=14)
            plt.grid(True)

        leg = fig.legend([x[0] for x in handles],
                         legend,
                         loc='lower left',
                         bbox_to_anchor=(0.05, 0.05))
        for legobj in leg.legendHandles:
            legobj.set_linewidth(4.0)

        names = [
            "{} ({:0.2f}, {:0.2f})".format(*x)
            for x in zip(self.ids, self.latitude, self.longitude)
        ]
        wrapped_names = "\n".join(wrap(", ".join(names), 60))
        plt.suptitle(f"{wrapped_names}\n{plot_label}", fontsize=15)
        fig.tight_layout(pad=3, w_pad=4)
        fig.subplots_adjust(top=0.85)

        return super(Class4Plotter, self).plot(fig)
コード例 #2
0
    def plot(self):
        # Create base figure
        fig = plt.figure(figsize=self.figuresize, dpi=self.dpi)

        # Setup figure layout
        width = 2 if self.showmap else 1
        # Scale TS Diagram to be double the size of location map
        width_ratios = [1, 3] if self.showmap else None

        # Create layout helper
        gs = gridspec.GridSpec(1, width, width_ratios=width_ratios)

        # Render point location
        if self.showmap:
            plt.subplot(gs[0, 0])
            utils.point_plot(np.array([[x[0] for x in self.points],  # Latitudes
                                       [x[1] for x in self.points]]))  # Longitudes

        # Plot TS Diagram
        plt.subplot(gs[:, 1 if self.showmap else 0])

        smin = np.amin(self.salinity) - (np.amin(self.salinity) * 0.01)
        smax = np.amax(self.salinity) + (np.amax(self.salinity) * 0.01)
        tmin = np.amin(self.temperature) - (
            np.abs(np.amax(self.temperature) * 0.1))
        tmax = np.amax(self.temperature) + (
            np.abs(np.amax(self.temperature) * 0.1))

        xdim = int(round((smax - smin) / 0.1 + 1, 0))
        ydim = int(round((tmax - tmin) + 1, 0))

        dens = np.zeros((ydim, xdim))
        ti = np.linspace(0, ydim - 1, ydim) + tmin
        si = np.linspace(0, xdim - 1, xdim) * 0.1 + smin

        for j in range(0, int(ydim)):
            for i in range(0, int(xdim)):
                dens[j, i] = seawater.dens(si[i], ti[j], 0)

        dens -= 1000

        CS = plt.contour(si, ti, dens, linestyles='dashed', colors='k')
        plt.clabel(CS, fontsize=15, inline=1, fmt=r"$\sigma_t = %1.1f$")

        for idx, _ in enumerate(self.temperature):
            plt.plot(self.salinity[idx], self.temperature[idx], '-')

        plt.xlabel(gettext("Salinity (PSU)"), fontsize=14)
        plt.ylabel(gettext("Temperature (Celsius)"), fontsize=14)

        if len(self.points) == 1:
            labels = []
            for idx, d in enumerate(self.temperature_depths[0]):
                if np.ma.is_masked(self.temperature[0][idx]):
                    break
                digits = max(np.ceil(np.log10(d)), 3)
                d = np.round(d, -int(digits - 1))
                if d not in labels:
                    labels.append(d)
                    for idx2, _ in enumerate(self.temperature):
                        plt.annotate(
                            '{:.0f}m'.format(d),
                            xy=(self.salinity[idx2][
                                idx], self.temperature[idx2][idx]),
                            xytext=(15, -15),
                            ha='left',
                            textcoords='offset points',
                            arrowprops=dict(arrowstyle='->')  # , shrinkA=0)
                        )

        self.plot_legend(fig, self.names)

        if not self.plotTitle:
            plt.title(gettext("T/S Diagram for (%s)\n%s") % (
                ", ".join(self.names),
                self.date_formatter(self.iso_timestamp)),
                fontsize=15
            )
        else:
            plt.title(self.plotTitle, fontsize=15)

        return super(TemperatureSalinityPlotter, self).plot(fig)
コード例 #3
0
    def plot(self):
        # Create base figure
        fig = plt.figure(figsize=self.figuresize(), dpi=self.dpi)

        # Setup figure layout
        width = len(self.variables)
        if self.showmap:
            width += 1
            # Horizontally scale the actual plots by 2x the size of
            # the location map
            width_ratios = [1]
            [width_ratios.append(2) for w in range(0, width - 1)]
        else:
            width_ratios = None

        # Create layout helper
        gs = gridspec.GridSpec(1, width, width_ratios=width_ratios)
        subplot = 0

        # Render point location
        if self.showmap:
            plt.subplot(gs[0, subplot])
            subplot += 1
            utils.point_plot(
                np.array([
                    [x[0] for x in self.points],  # Latitudes
                    [x[1] for x in self.points]
                ]))  # Longitudes

        is_y_label_plotted = False
        # Create a subplot for each variable selected
        # Each subplot has all points plotted
        for idx, v in enumerate(self.variables):
            plt.subplot(gs[:, subplot])

            plt.plot(self.data[:, idx, :].transpose(),
                     self.depths[:, idx, :].transpose())

            current_axis = plt.gca()
            current_axis.xaxis.set_label_position('top')
            current_axis.xaxis.set_ticks_position('top')
            current_axis.invert_yaxis()
            current_axis.grid(True)
            current_axis.set_xlabel("%s (%s)" %
                                    (self.variable_names[idx],
                                     utils.mathtext(self.variable_units[idx])),
                                    fontsize=14)

            # Put y-axis label on left-most graph (but after the point location)
            if not is_y_label_plotted and (subplot == 0 or subplot == 1):
                current_axis.set_ylabel(gettext("Depth (m)"), fontsize=14)
                is_y_label_plotted = True

            if self.compare:
                xlim = np.abs(plt.gca().get_xlim()).max()
                plt.gca().set_xlim([-xlim, xlim])

            subplot += 1

        self.plot_legend(fig, self.names)

        if self.plotTitle is None or self.plotTitle == "":
            plt.suptitle("%s(%s)\n%s\n%s" % (gettext("Profile for "), \
                                            ", ".join(self.names), \
                                            ", ".join(self.variable_names), \
                                            self.date_formatter(self.timestamp)), \
                        fontsize=15)
        else:
            plt.suptitle(self.plotTitle, fontsize=15)

        fig.tight_layout()
        fig.subplots_adjust(top=(0.8))

        return super(ProfilePlotter, self).plot(fig)
コード例 #4
0
    def plot(self):
        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 self.cmap is None:
            self.cmap = colormap.find_colormap(self.variable_name)

        datenum = matplotlib.dates.date2num(self.times)
        if self.depth == 'all':
            size = list(map(float, self.size.split("x")))
            numpoints = len(self.points)
            figuresize = (size[0], size[1] * numpoints)
            fig, ax = plt.subplots(numpoints,
                                   1,
                                   sharex=True,
                                   figsize=figuresize,
                                   dpi=self.dpi)

            if not isinstance(ax, np.ndarray):
                ax = [ax]

            for idx, p in enumerate(self.points):
                d = self.data[idx, 0, :]
                dlim = np.ma.flatnotmasked_edges(d[0, :])
                maxdepth = self.depths[dlim[1]].max()
                mindepth = self.depths[dlim[0]].min()

                c = ax[idx].pcolormesh(datenum,
                                       self.depths[:dlim[1] + 1],
                                       d[:, :dlim[1] + 1].transpose(),
                                       shading='gouraud',
                                       cmap=self.cmap,
                                       vmin=vmin,
                                       vmax=vmax)
                ax[idx].invert_yaxis()
                if maxdepth > LINEAR:
                    ax[idx].set_yscale('symlog', linthreshy=LINEAR)
                ax[idx].yaxis.set_major_formatter(ScalarFormatter())

                if maxdepth > LINEAR:
                    l = 10**np.floor(np.log10(maxdepth))
                    ax[idx].set_ylim(np.ceil(maxdepth / l) * l, mindepth)
                    ax[idx].set_yticks(
                        list(ax[idx].get_yticks()) + [maxdepth, LINEAR])
                else:
                    ax[idx].set_ylim(maxdepth, mindepth)
                ax[idx].set_ylabel("Depth (%s)" %
                                   utils.mathtext(self.depth_unit))

                ax[idx].xaxis_date()
                ax[idx].set_xlim(datenum[0], datenum[-1])

                divider = make_axes_locatable(ax[idx])
                cax = divider.append_axes("right", size="5%", pad=0.05)
                bar = plt.colorbar(c, cax=cax)
                bar.set_label("%s (%s)" % (self.variable_name.title(),
                                           utils.mathtext(self.variable_unit)))
                ax[idx].set_title("%s%s at %s" %
                                  (self.variable_name.title(),
                                   self.depth_label, self.names[idx]))
                plt.setp(ax[idx].get_xticklabels(), rotation=30)
            fig.autofmt_xdate()
        else:
            # Create base figure
            figure_size = self.figuresize
            figure_size[0] *= 1.5 if self.showmap else 1.0
            fig = plt.figure(figsize=figure_size, dpi=self.dpi)

            # Setup figure layout
            width = 1
            if self.showmap:
                width += 1
                # Horizontally scale the actual plots by 2x the size of
                # the location map
                width_ratios = [1, 2]
            else:
                width_ratios = None

            # Create layout helper
            gs = gridspec.GridSpec(1, width, width_ratios=width_ratios)
            subplot = 0

            # Render point location
            if self.showmap:
                plt.subplot(gs[0, 0])
                subplot += 1
                utils.point_plot(
                    np.array([
                        [x[0] for x in self.points],  # Latitudes
                        [x[1] for x in self.points]
                    ]))  # Longitudes

            plt.subplot(gs[:, subplot])
            plt.plot_date(datenum,
                          np.squeeze(self.data),
                          fmt='-',
                          figure=fig,
                          xdate=True)
            plt.ylabel(
                f"{self.variable_name.title()} ({utils.mathtext(self.variable_unit)})",
                fontsize=14)
            plt.ylim(vmin, vmax)

            # Title
            if self.plotTitle is None or self.plotTitle == "":
                wrapped_title = wrap(
                    "%s%s at %s" % (self.variable_name.title(),
                                    self.depth_label, ", ".join(self.names)),
                    80)
                plt.title("\n".join(wrapped_title), fontsize=15)
            else:
                plt.title(self.plotTitle, fontsize=15)

            plt.gca().grid(True)

            fig.autofmt_xdate()

            self.plot_legend(fig, self.names)

        return super(TimeseriesPlotter, self).plot(fig)
コード例 #5
0
    def plot(self):
        # Create base figure
        fig = plt.figure(figsize=self.figuresize(), dpi=self.dpi)

        # Setup figure layout
        width = 2 if self.showmap else 1
        # Scale TS Diagram to be double the size of location map
        width_ratios = [1, 3] if self.showmap else None

        # Create layout helper
        gs = gridspec.GridSpec(1, width, width_ratios=width_ratios)

        # Render point location
        if self.showmap:
            plt.subplot(gs[0, 0])
            utils.point_plot(
                np.array([
                    [x[0] for x in self.points],  # Latitudes
                    [x[1] for x in self.points]
                ]))  # Longitudes

        # Plot Sound Speed profile
        plt.subplot(gs[:, 1 if self.showmap else 0])
        ax = plt.gca()
        for i, ss in enumerate(self.sspeed):
            ax.plot(ss, self.temperature_depths[i], '-')

        minspeed = np.amin(self.sspeed)
        maxspeed = np.amax(self.sspeed)

        ax.set_xlim([
            np.amin(self.sspeed) - (maxspeed - minspeed) * 0.1,
            np.amax(self.sspeed) + (maxspeed - minspeed) * 0.1,
        ])
        ax.set_xlabel(gettext("Sound Speed (m/s)"), fontsize=14)
        ax.set_ylabel(gettext("Depth (m)"), fontsize=14)
        ax.invert_yaxis()
        ax.xaxis.set_ticks_position('top')
        ax.xaxis.set_label_position('top')
        x_format = tkr.FuncFormatter(lambda x, pos: "%d" % x)
        ax.xaxis.set_major_formatter(x_format)

        if self.plotTitle is None or self.plotTitle == "":
            ax.set_title(
                gettext("Sound Speed Profile for (%s)\n%s") %
                (", ".join(self.names), self.date_formatter(self.timestamp)),
                fontsize=15)
        else:
            ax.set_title(self.plotTitle, fontsize=15)

        ax.title.set_position([.5, 1.10])
        plt.subplots_adjust(top=0.85)
        ax.xaxis.grid(True)

        self.plot_legend(fig, self.names)

        ylim = ax.get_ylim()
        ax2 = ax.twinx()
        ureg = pint.UnitRegistry()
        ax2.set_ylim((ylim * ureg.meters).to(ureg.feet).magnitude)
        ax2.set_ylabel(gettext("Depth (ft)"), fontsize=14)

        return super(plTS.TemperatureSalinityPlotter, self).plot(fig)