예제 #1
0
    def plot(self):
        fig, ax = self.setup_subplots(len(self.variables))

        for idx in range(0, len(self.variables)):
            ax[idx].plot(self.data[:, idx, :].transpose(),
                         self.depths[:, idx, :].transpose())
            ax[idx].xaxis.set_label_position('top')
            ax[idx].xaxis.set_ticks_position('top')
            ax[idx].set_xlabel("%s (%s)" %
                               (self.variable_names[idx],
                                utils.mathtext(self.variable_units[idx])))
            if self.variables[idx] != self.variables_anom[idx]:
                xlim = np.abs(ax[idx].get_xlim()).max()
                ax[idx].set_xlim([-xlim, xlim])

        ax[0].invert_yaxis()
        ax[0].set_ylabel(gettext("Depth (m)"))

        self.plot_legend(fig, self.names)

        wrapped_title = wrap(
            "%s Profile for %s (%s)" %
            (", ".join(self.variable_names), ", ".join(
                self.names), self.date_formatter(self.timestamp)), 80)
        plt.suptitle("\n".join(wrapped_title))
        fig.tight_layout()
        fig.subplots_adjust(top=(0.905 - len(wrapped_title) * 0.025))

        return super(ProfilePlotter, self).plot(fig)
예제 #2
0
    def plot(self):
        fig, ax = self.setup_subplots(len(self.variables))

        for idx in range(0, len(self.variables)):
            ax[idx].plot(
                self.data[:, idx, :].transpose(),
                self.depths[:, idx, :].transpose()
            )
            ax[idx].xaxis.set_label_position('top')
            ax[idx].xaxis.set_ticks_position('top')
            ax[idx].set_xlabel("%s (%s)" %
                               (self.variable_names[idx],
                                utils.mathtext(self.variable_units[idx])))
            if self.variables[idx] != self.variables_anom[idx]:
                xlim = np.abs(ax[idx].get_xlim()).max()
                ax[idx].set_xlim([-xlim, xlim])

        ax[0].invert_yaxis()
        ax[0].set_ylabel(gettext("Depth (m)"))

        self.plot_legend(fig, self.names)

        wrapped_title = wrap(
            "%s Profile for %s (%s)" % (
                ", ".join(self.variable_names),
                ", ".join(self.names),
                self.date_formatter(self.timestamp)
            ), 80)
        plt.suptitle("\n".join(wrapped_title))
        fig.tight_layout()
        fig.subplots_adjust(
            top=(0.905 - len(wrapped_title) * 0.025)
        )

        return super(ProfilePlotter, self).plot(fig)
예제 #3
0
    def _hovmoller_plot(self, subplot, map_subplot, nomap_subplot, name, vmin,
                        vmax, data, times, cmap, unit, title):
        if self.showmap:
            plt.subplot(subplot[map_subplot[0], map_subplot[1]])
        else:
            plt.subplot(subplot[nomap_subplot[0], nomap_subplot[1]])

        try:
            c = plt.pcolormesh(
                self.distance,
                times,
                data,
                cmap=cmap,
                shading='gouraud',  # Smooth shading
                vmin=vmin,
                vmax=vmax)
        except TypeError as e:
            raise ServerError(
                gettext("Internal server error occured: " + str(e)))

        ax = plt.gca()
        ax.set_title(title, fontsize=14)  # Set title of subplot
        ax.yaxis_date()
        ax.yaxis.grid(True)
        ax.set_axis_bgcolor('dimgray')

        plt.xlabel(gettext("Distance (km)"))
        plt.xlim([self.distance[0], self.distance[-1]])

        divider = make_axes_locatable(plt.gca())
        cax = divider.append_axes("right", size="5%", pad=0.05)
        bar = plt.colorbar(c, cax=cax)
        bar.set_label("%s (%s)" % (name, utils.mathtext(unit)))
예제 #4
0
    def plot(self):
        figuresize = map(float, self.size.split("x"))
        figuresize[1] *= len(self.points) * len(self.depth)
        fig, ax = plt.subplots(len(self.points) * len(self.depth),
                               1,
                               sharex=True,
                               figsize=figuresize,
                               dpi=self.dpi)
        if len(self.points) * len(self.depth) == 1:
            ax = [ax]

        if self.data.shape[1] == 2:
            for idx, p in enumerate(self.points):
                magnitude = np.sqrt(self.data[idx, 0, :, :]**2 +
                                    self.data[idx, 1, :, :]**2)
                scale = np.mean(magnitude)
                if scale != 0:
                    scale = np.round(scale, int(-np.floor(np.log10(scale))))

                for idx2, d in enumerate(self.depth):
                    datenums = date2num(self.timestamp)
                    a = ax[idx * len(self.points) + idx2]
                    q = a.quiver(
                        datenums,
                        [0] * len(self.timestamp),
                        self.data[idx, 0, idx2, :],
                        self.data[idx, 1, idx2, :],
                        angles='uv',
                        width=0.002,
                        headwidth=0,
                        headlength=0,
                        headaxislength=0,
                    )

                    a.axes.get_yaxis().set_visible(False)
                    a.axes.get_xaxis().tick_bottom()
                    a.xaxis_date()
                    a.quiverkey(
                        q, 0.1, 0.75, scale, "%.1g %s" %
                        (scale, utils.mathtext(self.variable_units[0])))
                    dx = datenums[1] - datenums[0]
                    a.set_xlim(
                        [datenums[0] - dx / 2.0, datenums[-1] + dx / 2.0])
                    a.set_frame_on(False)
                    a.axhline(0, color='grey', ls=':')
                    if self.depth[idx2] == "bottom":
                        depth = "Bottom"
                    else:
                        depth = "%d m" % np.round(self.data_depth[idx, 0, idx2,
                                                                  0])

                    a.set_title(gettext("%s at (%s)\n%s") % (self.vector_name(
                        self.variable_names[0]), self.names[idx], depth),
                                fontsize=15)

        plt.setp(plt.gca().get_xticklabels(), rotation=30)
        fig.tight_layout()

        return super(StickPlotter, self).plot(fig)
예제 #5
0
def scale(args):
    dataset_name = args.get('dataset')
    scale = args.get('scale')
    scale = [float(component) for component in scale.split(',')]

    variable = args.get('variable')
    if variable.endswith('_anom'):
        variable = variable[0:-5]
        anom = True
    else:
        anom = False

    variable = variable.split(',')

    with open_dataset(get_dataset_url(dataset_name)) as dataset:
        variable_unit = get_variable_unit(dataset_name,
                                          dataset.variables[variable[0]])
        variable_name = get_variable_name(dataset_name,
                                          dataset.variables[variable[0]])

    if variable_unit.startswith("Kelvin"):
        variable_unit = "Celsius"

    if anom:
        cmap = colormap.colormaps['anomaly']
        variable_name = gettext("%s Anomaly") % variable_name
    else:
        cmap = colormap.find_colormap(variable_name)

    if len(variable) == 2:
        if not anom:
            cmap = colormap.colormaps.get('speed')

        variable_name = re.sub(
            r"(?i)( x | y |zonal |meridional |northward |eastward )", " ",
            variable_name)
        variable_name = re.sub(r" +", " ", variable_name)

    fig = plt.figure(figsize=(2, 5), dpi=75)
    ax = fig.add_axes([0.05, 0.05, 0.25, 0.9])
    norm = matplotlib.colors.Normalize(vmin=scale[0], vmax=scale[1])

    formatter = ScalarFormatter()
    formatter.set_powerlimits((-3, 4))
    bar = ColorbarBase(ax, cmap=cmap, norm=norm, orientation='vertical',
                       format=formatter)
    bar.set_label("%s (%s)" % (variable_name.title(),
                               utils.mathtext(variable_unit)))

    buf = StringIO()
    try:
        plt.savefig(buf, format='png', dpi='figure', transparent=False,
                    bbox_inches='tight', pad_inches=0.05)
        plt.close(fig)
        return buf.getvalue()
    finally:
        buf.close()
예제 #6
0
def scale(args):
    dataset_name = args.get('dataset')
    scale = args.get('scale')
    scale = [float(component) for component in scale.split(',')]

    variable = args.get('variable')
    if variable.endswith('_anom'):
        variable = variable[0:-5]
        anom = True
    else:
        anom = False

    variable = variable.split(',')

    with open_dataset(get_dataset_url(dataset_name)) as dataset:
        variable_unit = get_variable_unit(dataset_name,
                                          dataset.variables[variable[0]])
        variable_name = get_variable_name(dataset_name,
                                          dataset.variables[variable[0]])

    if variable_unit.startswith("Kelvin"):
        variable_unit = "Celsius"

    if anom:
        cmap = colormap.colormaps['anomaly']
        variable_name = gettext("%s Anomaly") % variable_name
    else:
        cmap = colormap.find_colormap(variable_name)

    if len(variable) == 2:
        if not anom:
            cmap = colormap.colormaps.get('speed')

        variable_name = re.sub(
            r"(?i)( x | y |zonal |meridional |northward |eastward )", " ",
            variable_name)
        variable_name = re.sub(r" +", " ", variable_name)

    fig = plt.figure(figsize=(2, 5), dpi=75)
    ax = fig.add_axes([0.05, 0.05, 0.25, 0.9])
    norm = matplotlib.colors.Normalize(vmin=scale[0], vmax=scale[1])

    formatter = ScalarFormatter()
    formatter.set_powerlimits((-3, 4))
    bar = ColorbarBase(ax, cmap=cmap, norm=norm, orientation='vertical',
                       format=formatter)
    bar.set_label("%s (%s)" % (variable_name.title(),
                               utils.mathtext(variable_unit)))

    buf = StringIO()
    try:
        plt.savefig(buf, format='png', dpi='figure', transparent=False,
                    bbox_inches='tight', pad_inches=0.05)
        plt.close(fig)
        return buf.getvalue()
    finally:
        buf.close()
 def _surface_plot(self, axis_divider):
     ax = axis_divider.append_axes("top", size="35%", pad=0.35)
     ax.plot(self.surface_data['distance'],
             self.surface_data['data'],
             color='r')
     ax.locator_params(nbins=3)
     ax.yaxis.tick_right()
     ax.yaxis.set_label_position("right")
     label = plt.ylabel(utils.mathtext(self.surface_data['unit']))
     title = plt.title(self.surface_data['name'], y=1.1)
     plt.setp(title, size='smaller')
     plt.setp(label, size='smaller')
     plt.setp(ax.get_yticklabels(), size='x-small')
     plt.xlim([0, self.surface_data['distance'][-1]])
     if np.any(
             map(
                 lambda x: re.search(x, self.surface_data['name'], re.
                                     IGNORECASE),
                 ["free surface", "surface height"])):
         ylim = plt.ylim()
         plt.ylim([min(ylim[0], -ylim[1]), max([-ylim[0], ylim[1]])])
         ax.yaxis.grid(True)
     ax.axes.get_xaxis().set_visible(False)
예제 #8
0
 def _surface_plot(self, axis_divider):
     ax = axis_divider.append_axes("top", size="15%", pad=0.15)
     ax.plot(self.surface_data['distance'],
             self.surface_data['data'], color='r')
     ax.locator_params(nbins=3)
     ax.yaxis.tick_right()
     ax.yaxis.set_label_position("right")
     label = plt.ylabel(utils.mathtext(self.surface_data['unit']))
     title = plt.title(self.surface_data['name'], y=1.1)
     plt.setp(title, size='smaller')
     plt.setp(label, size='smaller')
     plt.setp(ax.get_yticklabels(), size='x-small')
     plt.xlim([0, self.surface_data['distance'][-1]])
     if np.any(map(
         lambda x: re.search(x, self.surface_data['name'], re.IGNORECASE),
         [
             "free surface",
             "surface height"
         ]
     )):
         ylim = plt.ylim()
         plt.ylim([min(ylim[0], -ylim[1]), max([-ylim[0], ylim[1]])])
         ax.yaxis.grid(True)
     ax.axes.get_xaxis().set_visible(False)
예제 #9
0
    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 = 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)
예제 #10
0
    def plot(self):
        if self.filetype == 'geotiff':
            f, fname = tempfile.mkstemp()
            os.close(f)

            driver = gdal.GetDriverByName('GTiff')
            outRaster = driver.Create(fname, self.latitude.shape[1],
                                      self.longitude.shape[0], 1,
                                      gdal.GDT_Float64)
            x = [self.longitude[0, 0], self.longitude[-1, -1]]
            y = [self.latitude[0, 0], self.latitude[-1, -1]]
            outRasterSRS = osr.SpatialReference()

            x, y = self.basemap(x, y)
            outRasterSRS.ImportFromProj4(self.basemap.proj4string)

            pixelWidth = (x[-1] - x[0]) / self.longitude.shape[0]
            pixelHeight = (y[-1] - y[0]) / self.latitude.shape[0]
            outRaster.SetGeoTransform(
                (x[0], pixelWidth, 0, y[0], 0, pixelHeight))

            outband = outRaster.GetRasterBand(1)
            d = self.data.astype("Float64")
            ndv = d.fill_value
            outband.WriteArray(d.filled(ndv))
            outband.SetNoDataValue(ndv)
            outRaster.SetProjection(outRasterSRS.ExportToWkt())
            outband.FlushCache()
            outRaster = None

            with open(fname, 'r') as f:
                buf = f.read()
            os.remove(fname)

            return (buf, self.mime, self.filename.replace(".geotiff", ".tif"))
        # Figure size
        figuresize = map(float, self.size.split("x"))
        fig = plt.figure(figsize=figuresize, dpi=self.dpi)
        ax = plt.gca()

        if self.scale:
            vmin = self.scale[0]
            vmax = self.scale[1]
        else:
            vmin = np.amin(self.data)
            vmax = np.amax(self.data)
            if self.variables != self.variables_anom:
                vmax = max(abs(vmax), abs(vmin))
                vmin = -vmax

        c = self.basemap.imshow(self.data,
                                vmin=vmin,
                                vmax=vmax,
                                cmap=self.cmap)

        if len(self.quiver_data) == 2:
            qx, qy = self.quiver_data
            quiver_mag = np.sqrt(qx**2 + qy**2)

            if self.quiver['magnitude'] != 'length':
                qx = qx / quiver_mag
                qy = qy / quiver_mag
                qscale = 50
            else:
                qscale = None

            if self.quiver['magnitude'] == 'color':
                if self.quiver['colormap'] is None or \
                   self.quiver['colormap'] == 'default':
                    qcmap = colormap.colormaps.get('speed')
                else:
                    qcmap = colormap.colormaps.get(self.quiver['colormap'])

                q = self.basemap.quiver(
                    self.quiver_longitude,
                    self.quiver_latitude,
                    qx,
                    qy,
                    quiver_mag,
                    latlon=True,
                    width=0.0035,
                    headaxislength=4,
                    headlength=4,
                    scale=qscale,
                    pivot='mid',
                    cmap=qcmap,
                )
            else:
                q = self.basemap.quiver(
                    self.quiver_longitude,
                    self.quiver_latitude,
                    qx,
                    qy,
                    latlon=True,
                    width=0.0025,
                    headaxislength=4,
                    headlength=4,
                    scale=qscale,
                    pivot='mid',
                )

            if self.quiver['magnitude'] == 'length':
                unit_length = np.mean(quiver_mag) * 2
                unit_length = np.round(unit_length,
                                       -int(np.floor(np.log10(unit_length))))
                if unit_length >= 1:
                    unit_length = int(unit_length)

                plt.quiverkey(q,
                              .65,
                              .01,
                              unit_length,
                              self.quiver_name.title() + " " +
                              str(unit_length) + " " +
                              utils.mathtext(self.quiver_unit),
                              coordinates='figure',
                              labelpos='E')

        if self.show_bathymetry:
            # Plot bathymetry on top
            cs = self.basemap.contour(
                self.longitude,
                self.latitude,
                self.bathymetry,
                latlon=True,
                lineweight=0.5,
                norm=LogNorm(vmin=1, vmax=6000),
                cmap=mcolors.LinearSegmentedColormap.from_list(
                    'transparent_gray', [(0, 0, 0, 0.5), (0, 0, 0, 0.1)]),
                levels=[100, 200, 500, 1000, 2000, 3000, 4000, 5000, 6000])
            plt.clabel(cs, fontsize='xx-small', fmt='%1.0fm')

        if self.area and self.show_area:
            for a in self.area:
                polys = []
                for co in a['polygons'] + a['innerrings']:
                    coords = np.array(co).transpose()
                    mx, my = self.basemap(coords[1], coords[0])
                    map_coords = zip(mx, my)
                    polys.append(Polygon(map_coords))

                paths = []
                for poly in polys:
                    paths.append(poly.get_path())
                path = concatenate_paths(paths)

                poly = PathPatch(path, fill=None, edgecolor='k', linewidth=1)
                plt.gca().add_patch(poly)

            if self.names is not None and len(self.names) > 1:
                for idx, name in enumerate(self.names):
                    x, y = self.basemap(self.centroids[idx].y,
                                        self.centroids[idx].x)
                    plt.annotate(
                        xy=(x, y),
                        s=name,
                        ha='center',
                        va='center',
                        size=12,
                        # weight='bold'
                    )

        if len(self.contour_data) > 0:
            if (self.contour_data[0].min() != self.contour_data[0].max()):
                cmin, cmax = utils.normalize_scale(self.contour_data[0],
                                                   self.contour_name,
                                                   self.contour_unit)
                levels = None
                if self.contour.get('levels') is not None and \
                    self.contour['levels'] != 'auto' and \
                        self.contour['levels'] != '':
                    try:
                        levels = list(
                            set([
                                float(xx)
                                for xx in self.contour['levels'].split(",")
                                if xx.strip()
                            ]))
                        levels.sort()
                    except ValueError:
                        pass

                if levels is None:
                    levels = np.linspace(cmin, cmax, 5)
                cmap = self.contour['colormap']
                if cmap is not None:
                    cmap = colormap.colormaps.get(cmap)
                    if cmap is None:
                        cmap = colormap.find_colormap(self.contour_name)

                if not self.contour.get('hatch'):
                    contours = self.basemap.contour(self.longitude,
                                                    self.latitude,
                                                    self.contour_data[0],
                                                    latlon=True,
                                                    linewidths=2,
                                                    levels=levels,
                                                    cmap=cmap)
                else:
                    hatches = [
                        '//', 'xx', '\\\\', '--', '||', '..', 'oo', '**'
                    ]
                    if len(levels) + 1 < len(hatches):
                        hatches = hatches[0:len(levels) + 2]
                    self.basemap.contour(self.longitude,
                                         self.latitude,
                                         self.contour_data[0],
                                         latlon=True,
                                         linewidths=1,
                                         levels=levels,
                                         colors='k')
                    contours = self.basemap.contourf(self.longitude,
                                                     self.latitude,
                                                     self.contour_data[0],
                                                     latlon=True,
                                                     colors=['none'],
                                                     levels=levels,
                                                     hatches=hatches,
                                                     vmin=cmin,
                                                     vmax=cmax,
                                                     extend='both')

                if self.contour['legend']:
                    handles, l = contours.legend_elements()
                    labels = []
                    for i, lab in enumerate(l):
                        if self.contour.get('hatch'):
                            if self.contour_unit == 'fraction':
                                if i == 0:
                                    labels.append(
                                        "$x \\leq {0: .0f}\\%$".format(
                                            levels[i] * 100))
                                elif i == len(levels):
                                    labels.append("$x > {0: .0f}\\%$".format(
                                        levels[i - 1] * 100))
                                else:
                                    labels.append(
                                        "${0:.0f}\\% < x \\leq {1:.0f}\\%$".
                                        format(levels[i - 1] * 100,
                                               levels[i] * 100))
                            else:
                                if i == 0:
                                    labels.append("$x \\leq %.3g$" % levels[i])
                                elif i == len(levels):
                                    labels.append("$x > %.3g$" % levels[i - 1])
                                else:
                                    labels.append("$%.3g < x \\leq %.3g$" %
                                                  (levels[i - 1], levels[i]))
                        else:
                            if self.contour_unit == 'fraction':
                                labels.append("{0:.0%}".format(levels[i]))
                            else:
                                labels.append(
                                    "%.3g %s" %
                                    (levels[i],
                                     utils.mathtext(self.contour_unit)))

                    ax = plt.gca()

                    if self.contour_unit != 'fraction' and not \
                            self.contour.get('hatch'):
                        contour_title = "%s (%s)" % (self.contour_name,
                                                     utils.mathtext(
                                                         self.contour_unit))
                    else:
                        contour_title = self.contour_name

                    leg = ax.legend(handles[::-1],
                                    labels[::-1],
                                    loc='lower left',
                                    fontsize='medium',
                                    frameon=True,
                                    framealpha=0.75,
                                    title=contour_title)
                    leg.get_title().set_fontsize('medium')
                    if not self.contour.get('hatch'):
                        for legobj in leg.legendHandles:
                            legobj.set_linewidth(3)

        # Map Info
        self.basemap.drawmapboundary(fill_color=(0.3, 0.3, 0.3), zorder=-1)
        self.basemap.drawcoastlines(linewidth=0.5)
        self.basemap.fillcontinents(color='grey', lake_color='dimgrey')

        def find_lines(values):
            if np.amax(values) - np.amin(values) < 1:
                return [values.mean()]
            elif np.amax(values) - np.amin(values) < 25:
                return np.round(
                    np.arange(np.amin(values), np.amax(values),
                              round(np.amax(values) - np.amin(values)) / 5))
            else:
                return np.arange(round(np.amin(values), -1),
                                 round(np.amax(values), -1), 5)

        parallels = find_lines(self.latitude)
        meridians = find_lines(self.longitude)
        self.basemap.drawparallels(parallels,
                                   labels=[1, 0, 0, 0],
                                   color=(0, 0, 0, 0.5))
        self.basemap.drawmeridians(meridians,
                                   labels=[0, 0, 0, 1],
                                   color=(0, 0, 0, 0.5),
                                   latmax=85)

        area_title = "\n".join(wrap(", ".join(self.names), 60)) + "\n"

        title = "%s %s %s, %s" % (area_title, self.variable_name.title(),
                                  self.depth_label,
                                  self.date_formatter(self.timestamp))
        plt.title(title.strip())
        ax = plt.gca()
        divider = make_axes_locatable(ax)
        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)))

        if self.quiver is not None and \
            self.quiver['variable'] != '' and \
            self.quiver['variable'] != 'none' and \
                self.quiver['magnitude'] == 'color':
            bax = divider.append_axes("bottom", size="5%", pad=0.35)
            qbar = plt.colorbar(q, orientation='horizontal', cax=bax)
            qbar.set_label(self.quiver_name.title() + " " +
                           utils.mathtext(self.quiver_unit))

        fig.tight_layout(pad=3, w_pad=4)

        return super(MapPlotter, self).plot(fig)
예제 #11
0
    def plot(self):
        if len(self.variables) > 1:
            self.variable_name = self.vector_name(self.variable_name)
            if self.scale:
                vmin = self.scale[0]
                vmax = self.scale[1]
            else:
                vmin = 0
                vmax = self.data.max()
                if self.cmap is None:
                    self.cmap = colormap.colormaps.get('speed')
        else:
            if self.scale:
                vmin = self.scale[0]
                vmax = self.scale[1]
            else:
                vmin = self.data.min()
                vmax = self.data.max()

                if self.variable_unit == "fraction":
                    vmin = 0
                    vmax = 1
                elif np.any(
                        map(
                            lambda x: re.
                            search(x, self.variable_name, re.IGNORECASE), [
                                "free surface", "surface height", "velocity",
                                "wind"
                            ])):
                    vmin = min(vmin, -vmax)
                    vmax = max(vmax, -vmin)

        if self.cmap is None:
            self.cmap = colormap.find_colormap(self.variable_name)

        datenum = matplotlib.dates.date2num(self.times)
        if self.depth == 'all':
            size = 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:
            fig = plt.figure(figsize=self.figuresize(), dpi=self.dpi)
            wrapped_title = wrap(
                "%s%s at %s" % (self.variable_name.title(), self.depth_label,
                                ", ".join(self.names)), 80)

            plt.title("\n".join(wrapped_title))
            plt.plot_date(datenum,
                          self.data[:, 0, :].transpose(),
                          '-',
                          figure=fig)
            plt.ylabel("%s (%s)" % (self.variable_name.title(),
                                    utils.mathtext(self.variable_unit)))
            plt.ylim(vmin, vmax)
            plt.gca().xaxis.grid(True)
            plt.gca().yaxis.grid(True)
            fig.autofmt_xdate()

            self.plot_legend(fig, self.names)

        return super(TimeseriesPlotter, self).plot(fig)
예제 #12
0
    def plot(self):
        if self.filetype == 'geotiff':
            f, fname = tempfile.mkstemp()
            os.close(f)

            driver = gdal.GetDriverByName('GTiff')
            outRaster = driver.Create(fname,
                                      self.latitude.shape[1],
                                      self.longitude.shape[0],
                                      1, gdal.GDT_Float64)
            x = [self.longitude[0, 0], self.longitude[-1, -1]]
            y = [self.latitude[0, 0], self.latitude[-1, -1]]
            outRasterSRS = osr.SpatialReference()

            x, y = self.basemap(x, y)
            outRasterSRS.ImportFromProj4(self.basemap.proj4string)

            pixelWidth = (x[-1] - x[0]) / self.longitude.shape[0]
            pixelHeight = (y[-1] - y[0]) / self.latitude.shape[0]
            outRaster.SetGeoTransform((x[0], pixelWidth, 0, y[0], 0,
                                       pixelHeight))

            outband = outRaster.GetRasterBand(1)
            d = self.data.astype("Float64")
            ndv = d.fill_value
            outband.WriteArray(d.filled(ndv))
            outband.SetNoDataValue(ndv)
            outRaster.SetProjection(outRasterSRS.ExportToWkt())
            outband.FlushCache()
            outRaster = None

            with open(fname, 'r') as f:
                buf = f.read()
            os.remove(fname)

            return (buf, self.mime, self.filename.replace(".geotiff", ".tif"))
        # Figure size
        figuresize = map(float, self.size.split("x"))
        fig = plt.figure(figsize=figuresize, dpi=self.dpi)
        ax = plt.gca()

        if self.scale:
            vmin = self.scale[0]
            vmax = self.scale[1]
        else:
            vmin = np.amin(self.data)
            vmax = np.amax(self.data)
            if self.variables != self.variables_anom:
                vmax = max(abs(vmax), abs(vmin))
                vmin = -vmax

        c = self.basemap.imshow(
            self.data, vmin=vmin, vmax=vmax, cmap=self.cmap)

        if len(self.quiver_data) == 2:
            qx, qy = self.quiver_data
            quiver_mag = np.sqrt(qx ** 2 + qy ** 2)

            if self.quiver['magnitude'] != 'length':
                qx = qx / quiver_mag
                qy = qy / quiver_mag
                qscale = 50
            else:
                qscale = None

            if self.quiver['magnitude'] == 'color':
                if self.quiver['colormap'] is None or \
                   self.quiver['colormap'] == 'default':
                    qcmap = colormap.colormaps.get('speed')
                else:
                    qcmap = colormap.colormaps.get(self.quiver['colormap'])

                q = self.basemap.quiver(
                    self.quiver_longitude, self.quiver_latitude,
                    qx, qy,
                    quiver_mag,
                    latlon=True, width=0.0035,
                    headaxislength=4, headlength=4,
                    scale=qscale,
                    pivot='mid',
                    cmap=qcmap,
                )
            else:
                q = self.basemap.quiver(
                    self.quiver_longitude, self.quiver_latitude,
                    qx, qy,
                    latlon=True, width=0.0025,
                    headaxislength=4, headlength=4,
                    scale=qscale,
                    pivot='mid',
                )

            if self.quiver['magnitude'] == 'length':
                unit_length = np.mean(quiver_mag) * 2
                unit_length = np.round(unit_length,
                                       -int(np.floor(np.log10(unit_length))))
                if unit_length >= 1:
                    unit_length = int(unit_length)

                plt.quiverkey(q, .65, .01,
                              unit_length,
                              self.quiver_name.title() + " " +
                              str(unit_length) + " " +
                              utils.mathtext(self.quiver_unit),
                              coordinates='figure',
                              labelpos='E')

        if self.show_bathymetry:
            # Plot bathymetry on top
            cs = self.basemap.contour(
                self.longitude, self.latitude, self.bathymetry, latlon=True,
                lineweight=0.5,
                norm=LogNorm(vmin=1, vmax=6000),
                cmap=mcolors.LinearSegmentedColormap.from_list(
                    'transparent_gray',
                    [(0, 0, 0, 0.5), (0, 0, 0, 0.1)]
                ),
                levels=[100, 200, 500, 1000, 2000, 3000, 4000, 5000, 6000])
            plt.clabel(cs, fontsize='xx-small', fmt='%1.0fm')

        if self.area and self.show_area:
            for a in self.area:
                polys = []
                for co in a['polygons'] + a['innerrings']:
                    coords = np.array(co).transpose()
                    mx, my = self.basemap(coords[1], coords[0])
                    map_coords = zip(mx, my)
                    polys.append(Polygon(map_coords))

                paths = []
                for poly in polys:
                    paths.append(poly.get_path())
                path = concatenate_paths(paths)

                poly = PathPatch(path,
                                 fill=None,
                                 edgecolor='k',
                                 linewidth=1
                                 )
                plt.gca().add_patch(poly)

            if self.names is not None and len(self.names) > 1:
                for idx, name in enumerate(self.names):
                    x, y = self.basemap(
                        self.centroids[idx].y, self.centroids[idx].x)
                    plt.annotate(
                        xy=(x, y),
                        s=name,
                        ha='center',
                        va='center',
                        size=12,
                        # weight='bold'
                    )

        if len(self.contour_data) > 0:
            if (self.contour_data[0].min() != self.contour_data[0].max()):
                cmin, cmax = utils.normalize_scale(
                    self.contour_data[0],
                    self.contour_name, self.contour_unit
                )
                levels = None
                if self.contour.get('levels') is not None and \
                    self.contour['levels'] != 'auto' and \
                        self.contour['levels'] != '':
                    try:
                        levels = list(
                            set(
                                [float(xx)
                                 for xx in self.contour['levels'].split(",")
                                 if xx.strip()]
                            )
                        )
                        levels.sort()
                    except ValueError:
                        pass

                if levels is None:
                    levels = np.linspace(cmin, cmax, 5)
                cmap = self.contour['colormap']
                if cmap is not None:
                    cmap = colormap.colormaps.get(cmap)
                    if cmap is None:
                        cmap = colormap.find_colormap(self.contour_name)

                if not self.contour.get('hatch'):
                    contours = self.basemap.contour(
                        self.longitude, self.latitude, self.contour_data[
                            0], latlon=True,
                        linewidths=2,
                        levels=levels,
                        cmap=cmap)
                else:
                    hatches = [
                        '//', 'xx', '\\\\', '--', '||', '..', 'oo', '**'
                    ]
                    if len(levels) + 1 < len(hatches):
                        hatches = hatches[0:len(levels) + 2]
                    self.basemap.contour(
                        self.longitude, self.latitude, self.contour_data[
                            0], latlon=True,
                        linewidths=1,
                        levels=levels,
                        colors='k')
                    contours = self.basemap.contourf(
                        self.longitude, self.latitude, self.contour_data[0],
                        latlon=True, colors=['none'],
                        levels=levels,
                        hatches=hatches,
                        vmin=cmin, vmax=cmax, extend='both')

                if self.contour['legend']:
                    handles, l = contours.legend_elements()
                    labels = []
                    for i, lab in enumerate(l):
                        if self.contour.get('hatch'):
                            if self.contour_unit == 'fraction':
                                if i == 0:
                                    labels.append("$x \\leq {0: .0f}\\%$".
                                                  format(levels[i] * 100))
                                elif i == len(levels):
                                    labels.append("$x > {0: .0f}\\%$".
                                                  format(levels[i - 1] * 100))
                                else:
                                    labels.append(
                                        "${0:.0f}\\% < x \\leq {1:.0f}\\%$".
                                        format(levels[i - 1] * 100,
                                               levels[i] * 100))
                            else:
                                if i == 0:
                                    labels.append("$x \\leq %.3g$" %
                                                  levels[i])
                                elif i == len(levels):
                                    labels.append("$x > %.3g$" %
                                                  levels[i - 1])
                                else:
                                    labels.append("$%.3g < x \\leq %.3g$" %
                                                  (levels[i - 1], levels[i]))
                        else:
                            if self.contour_unit == 'fraction':
                                labels.append("{0:.0%}".format(levels[i]))
                            else:
                                labels.append("%.3g %s" % (
                                    levels[i],
                                    utils.mathtext(self.contour_unit)
                                ))

                    ax = plt.gca()

                    if self.contour_unit != 'fraction' and not \
                            self.contour.get('hatch'):
                        contour_title = "%s (%s)" % (
                            self.contour_name, utils.mathtext(
                                self.contour_unit)
                        )
                    else:
                        contour_title = self.contour_name

                    leg = ax.legend(handles[::-1], labels[::-1],
                                    loc='lower left', fontsize='medium',
                                    frameon=True, framealpha=0.75,
                                    title=contour_title)
                    leg.get_title().set_fontsize('medium')
                    if not self.contour.get('hatch'):
                        for legobj in leg.legendHandles:
                            legobj.set_linewidth(3)

        # Map Info
        self.basemap.drawmapboundary(fill_color=(0.3, 0.3, 0.3), zorder=-1)
        self.basemap.drawcoastlines(linewidth=0.5)
        self.basemap.fillcontinents(color='grey', lake_color='dimgrey')

        def find_lines(values):
            if np.amax(values) - np.amin(values) < 1:
                return [values.mean()]
            elif np.amax(values) - np.amin(values) < 25:
                return np.round(
                    np.arange(
                        np.amin(values),
                        np.amax(values),
                        round(
                            np.amax(values) - np.amin(values)) / 5
                    )
                )
            else:
                return np.arange(
                    round(np.amin(values), -1),
                    round(np.amax(values), -1),
                    5
                )

        parallels = find_lines(self.latitude)
        meridians = find_lines(self.longitude)
        self.basemap.drawparallels(
            parallels, labels=[1, 0, 0, 0], color=(0, 0, 0, 0.5))
        self.basemap.drawmeridians(
            meridians, labels=[0, 0, 0, 1], color=(0, 0, 0, 0.5), latmax=85)

        area_title = "\n".join(
            wrap(", ".join(self.names), 60)
        ) + "\n"

        title = "%s %s %s, %s" % (
            area_title,
            self.variable_name.title(),
            self.depth_label,
            self.date_formatter(self.timestamp)
        )
        plt.title(title.strip())
        ax = plt.gca()
        divider = make_axes_locatable(ax)
        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)))

        if self.quiver is not None and \
            self.quiver['variable'] != '' and \
            self.quiver['variable'] != 'none' and \
                self.quiver['magnitude'] == 'color':
            bax = divider.append_axes("bottom", size="5%", pad=0.35)
            qbar = plt.colorbar(q, orientation='horizontal', cax=bax)
            qbar.set_label(
                self.quiver_name.title() + " " +
                utils.mathtext(self.quiver_unit))

        fig.tight_layout(pad=3, w_pad=4)

        return super(MapPlotter, self).plot(fig)
예제 #13
0
    def _transect_plot(self, values, depths, name, vmin, vmax):
        self.__fill_invalid_shift(values)

        dist = np.tile(self.transect_data['distance'], (values.shape[0], 1))
        c = plt.pcolormesh(dist, depths.transpose(), values,
                           cmap=self.cmap,
                           shading='gouraud',
                           vmin=vmin,
                           vmax=vmax)
        ax = plt.gca()
        ax.invert_yaxis()
        if self.depth_limit is None or (
            self.depth_limit is not None and
            self.linearthresh < self.depth_limit
        ):
            plt.yscale('symlog', linthreshy=self.linearthresh)
        ax.yaxis.set_major_formatter(ScalarFormatter())

        # Mask out the bottom
        plt.fill_between(
            self.bathymetry['x'],
            self.bathymetry['y'] * -1,
            plt.ylim()[0],
            facecolor='dimgray',
            hatch='xx'
        )
        ax.set_axis_bgcolor('dimgray')

        plt.xlabel(gettext("Distance (km)"))
        plt.ylabel(gettext("Depth (m)"))
        plt.xlim([self.transect_data['distance'][0],
                  self.transect_data['distance'][-1]])

        # Tighten the y-limits
        if self.depth_limit:
            plt.ylim(self.depth_limit, 0)
        else:
            deep = np.amax(self.bathymetry['y'] * -1)
            l = 10 ** np.floor(np.log10(deep))
            plt.ylim(np.ceil(deep / l) * l, 0)

        ticks = sorted(set(list(plt.yticks()[0]) + [self.linearthresh,
                                                    plt.ylim()[0]]))
        if self.depth_limit is not None:
            ticks = filter(lambda y: y <= self.depth_limit, ticks)

        plt.yticks(ticks)

        # Show the linear threshold
        plt.plot([self.transect_data['distance'][0],
                  self.transect_data['distance'][-1]],
                 [self.linearthresh, self.linearthresh],
                 'k:', alpha=0.5)

        divider = make_axes_locatable(ax)
        cax = divider.append_axes("right", size="5%", pad=0.05)
        bar = plt.colorbar(c, cax=cax)
        bar.set_label(
            name + " (" + utils.mathtext(self.transect_data['unit']) + ")")

        if len(self.points) > 2:
            station_distances = []
            current_dist = 0
            d = VincentyDistance()
            for idx, p in enumerate(self.points):
                if idx == 0:
                    station_distances.append(0)
                else:
                    current_dist += d.measure(
                        p, self.points[idx - 1])
                    station_distances.append(current_dist)

            ax2 = ax.twiny()
            ax2.set_xticks(station_distances)
            ax2.set_xlim([self.transect_data['distance'][0],
                          self.transect_data['distance'][-1]])
            ax2.tick_params(
                'x',
                length=0,
                width=0,
                pad=-3,
                labelsize='xx-small',
                which='major')
            ax2.xaxis.set_major_formatter(StrMethodFormatter(u"$\u25bc$"))
            cax = make_axes_locatable(ax2).append_axes(
                "right", size="5%", pad=0.05)
            bar2 = plt.colorbar(c, cax=cax)
            bar2.remove()
        return divider
예제 #14
0
    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 = 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)
예제 #15
0
    def plot(self):
        figuresize = map(float, self.size.split("x"))
        figuresize[1] *= len(self.points) * len(self.depth)
        fig, ax = plt.subplots(
            len(self.points) * len(self.depth),
            1,
            sharex=True,
            figsize=figuresize,
            dpi=self.dpi
        )
        if len(self.points) * len(self.depth) == 1:
            ax = [ax]

        if self.data.shape[1] == 2:
            for idx, p in enumerate(self.points):
                magnitude = np.sqrt(self.data[idx, 0, :, :] ** 2 +
                                    self.data[idx, 1, :, :] ** 2)
                scale = np.mean(magnitude)
                if scale != 0:
                    scale = np.round(
                        scale,
                        int(-np.floor(np.log10(scale)))
                    )

                for idx2, d in enumerate(self.depth):
                    datenums = date2num(self.timestamp)
                    a = ax[idx * len(self.points) + idx2]
                    q = a.quiver(
                        datenums,
                        [0] * len(self.timestamp),
                        self.data[idx, 0, idx2, :],
                        self.data[idx, 1, idx2, :],
                        angles='uv',
                        width=0.002,
                        headwidth=0,
                        headlength=0,
                        headaxislength=0,
                    )

                    a.axes.get_yaxis().set_visible(False)
                    a.axes.get_xaxis().tick_bottom()
                    a.xaxis_date()
                    a.quiverkey(
                        q, 0.1, 0.75, scale, "%.1g %s" % (
                            scale,
                            utils.mathtext(self.variable_units[0])
                        )
                    )
                    dx = datenums[1] - datenums[0]
                    a.set_xlim(
                        [datenums[0] - dx / 2.0, datenums[-1] + dx / 2.0])
                    a.set_frame_on(False)
                    a.axhline(0, color='grey', ls=':')
                    if self.depth[idx2] == "bottom":
                        depth = "Bottom"
                    else:
                        depth = "%d m" % np.round(self.data_depth[
                            idx, 0, idx2, 0
                        ])

                    a.set_title(gettext("%s at %s (%s)") % (
                        self.vector_name(self.variable_names[0]),
                        self.names[idx],
                        depth
                    ))

        plt.setp(plt.gca().get_xticklabels(), rotation=30)
        fig.tight_layout()

        return super(StickPlotter, self).plot(fig)
예제 #16
0
    def plot(self):
        if len(self.variables) > 1:
            self.variable_name = self.vector_name(self.variable_name)
            if self.scale:
                vmin = self.scale[0]
                vmax = self.scale[1]
            else:
                vmin = 0
                vmax = self.data.max()
                if self.cmap is None:
                    self.cmap = colormap.colormaps.get('speed')
        else:
            if self.scale:
                vmin = self.scale[0]
                vmax = self.scale[1]
            else:
                vmin = self.data.min()
                vmax = self.data.max()

                if self.variable_unit == "fraction":
                    vmin = 0
                    vmax = 1
                elif np.any(map(lambda x: re.search(x, self.variable_name,
                                                    re.IGNORECASE), [
                    "free surface",
                    "surface height",
                    "velocity",
                    "wind"
                ])):
                    vmin = min(vmin, -vmax)
                    vmax = max(vmax, -vmin)

        if self.cmap is None:
            self.cmap = colormap.find_colormap(self.variable_name)

        datenum = matplotlib.dates.date2num(self.times)
        if self.depth == 'all':
            size = 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:
            fig = plt.figure(figsize=self.figuresize(), dpi=self.dpi)
            wrapped_title = wrap(
                "%s%s at %s" % (
                    self.variable_name.title(),
                    self.depth_label,
                    ", ".join(self.names)
                ), 80)

            plt.title("\n".join(wrapped_title))
            plt.plot_date(
                datenum, self.data[:, 0, :].transpose(), '-', figure=fig)
            plt.ylabel("%s (%s)" % (self.variable_name.title(),
                                    utils.mathtext(self.variable_unit)))
            plt.ylim(vmin, vmax)
            plt.gca().xaxis.grid(True)
            plt.gca().yaxis.grid(True)
            fig.autofmt_xdate()

            self.plot_legend(fig, self.names)

        return super(TimeseriesPlotter, self).plot(fig)
예제 #17
0
    def plot(self):
        figuresize = map(float, self.size.split("x"))
        fig = plt.figure(figsize=figuresize, dpi=self.dpi)

        width = len(self.variables)

        if self.showmap:
            width += 1

        gs = gridspec.GridSpec(2, width)

        subplot = 0

        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 = gettext("Model")
        if len(self.additional_model_names) > 0:
            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)):
                if len(self.ids) > 1:
                    id_label = self.ids[i] + " "
                else:
                    id_label = ""

                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("%s %s" %
                                      (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("%s %s" % (id_label, giops_name))

                    for j, m 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("%s %s" % (id_label, m))

                    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("%s %s" %
                                      (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("%s %s" % (id_label, giops_name))
                    for j, m in enumerate(self.additional_model_names):
                        handles.append(
                            plt.plot(self.additional_model_data[j, i, idx, :],
                                     self.depths[i], form))
                        legend.append("%s %s" % (id_label, m))

                    if self.climatology:
                        handles.append(
                            plt.plot(self.climatology_data[i, idx, :],
                                     self.depths[i], form))
                        legend.append("%s %s" %
                                      (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("%s (%s)" %
                       (v, utils.mathtext(self.variable_units[idx])))
            plt.gca().invert_yaxis()
            plt.ylabel(gettext("Depth (%s)") % utils.mathtext(self.depth_unit))
            plt.grid(True)

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

        names = map(lambda x: "%s (%0.2f, %0.2f)" % x,
                    zip(self.ids, self.latitude, self.longitude))

        plt.suptitle("%s\n%s" %
                     ("\n".join(wrap(", ".join(names), 60)), plot_label))
        fig.tight_layout(pad=3, w_pad=4)
        fig.subplots_adjust(top=0.88)

        return super(Class4Plotter, self).plot(fig)
예제 #18
0
    def plot(self):
        # Figure size
        figuresize = map(float, self.size.split("x"))
        fig = plt.figure(figsize=figuresize, dpi=self.dpi)

        if self.showmap:
            width = 2
            width_ratios = [2, 7]
        else:
            width = 1
            width_ratios = [1]

        gs = gridspec.GridSpec(1, width, width_ratios=width_ratios)

        if self.showmap:
            # Plot the path on a map
            plt.subplot(gs[0])

            utils.path_plot(self.path_points)

        if self.scale:
            vmin = self.scale[0]
            vmax = self.scale[1]
        else:
            vmin = np.amin(self.data)
            vmax = np.amax(self.data)
            if np.any(map(
                lambda x: re.search(x, self.variable_name, re.IGNORECASE),
                [
                    "velocity",
                    "surface height",
                    "wind"
                ]
            )):
                vmin = min(vmin, -vmax)
                vmax = max(vmax, -vmin)
            if len(self.variables) > 1:
                vmin = 0

        if self.showmap:
            plt.subplot(gs[1])

        if len(self.variables) > 1:
            self.variable_name = self.vector_name(self.variable_name)

        c = plt.pcolormesh(self.distance, self.times, self.data,
                           cmap=self.cmap,
                           shading='gouraud',
                           vmin=vmin,
                           vmax=vmax)
        ax = plt.gca()
        ax.yaxis_date()
        ax.yaxis.grid(True)
        ax.set_axis_bgcolor('dimgray')

        plt.xlabel(gettext("Distance (km)"))
        plt.xlim([self.distance[0], self.distance[-1]])

        divider = make_axes_locatable(plt.gca())
        cax = divider.append_axes("right", size="5%", pad=0.05)
        bar = plt.colorbar(c, cax=cax)
        bar.set_label("%s (%s)" % (self.variable_name,
                                   utils.mathtext(self.variable_unit)))

        if self.depth == 'bottom':
            depth_label = " at Bottom"
        else:
            depth_label = " at %d %s" % (self.depth_value, self.depth_unit)

        fig.suptitle(gettext(u"Hovm\xf6ller Diagram for %s%s,\n%s") % (
            self.variable_name,
            depth_label,
            self.name
        ))

        fig.tight_layout(pad=3, w_pad=4)
        fig.subplots_adjust(top=0.92)

        return super(HovmollerPlotter, self).plot(fig)
예제 #19
0
    def plot(self):
        v = set([])
        for idx in self.observation_variable:
            v.add(self.observation_variable_names[idx])
        for n in self.variable_names:
            v.add(n)

        numplots = len(v)

        fig, ax = self.setup_subplots(numplots)

        data = []
        for o in self.observation:
            d = np.ma.MaskedArray(o['data'])
            d[np.where(d == '')] = np.ma.masked
            d = np.ma.masked_invalid(d.filled(np.nan).astype(np.float32))
            data.append(d)

        ureg = pint.UnitRegistry()
        ax_idx = -1
        udepth = ureg.parse_expression(self.observation[0]['depthunit'])
        axis_map = {}
        unit_map = {}
        for idx in self.observation_variable:
            ax_idx += 1
            for d in data:
                ax[ax_idx].plot(
                    d[:, idx],
                    self.observation[0]['depth'] * udepth.to(ureg.meter)
                )
            ax[ax_idx].xaxis.set_label_position('top')
            ax[ax_idx].xaxis.set_ticks_position('top')
            ax[ax_idx].set_xlabel("%s (%s)" % (
                self.observation_variable_names[idx],
                utils.mathtext(self.observation_variable_units[idx]),
            ))
            axis_map[self.observation_variable_names[idx]] = ax[ax_idx]

            try:
                if "_" in self.observation_variable_units[idx]:
                    u = self.observation_variable_units[idx].lower().split(
                        "_",
                        1
                    )[1]
                else:
                    u = self.observation_variable_units[idx].lower()
                unit_map[
                    self.observation_variable_names[idx]] = ureg.parse_units(u)

            except:
                unit_map[
                    self.observation_variable_names[idx]] = ureg.dimensionless

        for k, v in unit_map.iteritems():
            if v == ureg.speed_of_light:
                unit_map[k] = ureg.celsius

        for idx, var in enumerate(self.variables):
            if axis_map.get(self.variable_names[idx]) is not None:
                axis = axis_map.get(self.variable_names[idx])
                showlegend = True
                destunit = unit_map.get(self.variable_names[idx])
            else:
                ax_idx += 1
                axis = ax[ax_idx]
                showlegend = False
                try:
                    destunit = ureg.parse_units(
                        self.variable_units[idx].lower())
                    if destunit == ureg.speed_of_light:
                        destunit = ureg.celsius

                except:
                    destunit = ureg.dimensionless

            for j in range(0, self.data.shape[0]):
                try:
                    u = ureg.parse_units(self.variable_units[idx].lower())
                    if u == ureg.speed_of_light:
                        u = ureg.celsius

                    quan = ureg.Quantity(self.data[j, idx, :], u)
                except:
                    quan = ureg.Quantity(
                        self.data[j, idx, :], ureg.dimensionless)

                axis.plot(quan.to(destunit).magnitude, self.depths[j, idx, :])

            showlegend = showlegend or len(self.observation) > 1
            if not showlegend:
                axis.xaxis.set_label_position('top')
                axis.xaxis.set_ticks_position('top')
                axis.set_xlabel("%s (%s)" % (
                    self.variable_names[idx],
                    utils.mathtext(self.variable_units[idx]),
                ))
            else:
                l = []
                for j in [
                    (gettext("Observed"), self.observation_times),
                    (gettext("Modelled"), self.timestamps)
                ]:
                    for i, name in enumerate(self.names):
                        if len(self.names) == 1:
                            name = ""
                        else:
                            name = name + " "

                        l.append("%s%s (%s)" % (
                            name,
                            j[0],
                            format_datetime(j[1][i])
                        ))

                leg = axis.legend(l, loc='best')

                for legobj in leg.legendHandles:
                    legobj.set_linewidth(4.0)

        ax[0].invert_yaxis()
        ax[0].set_ylabel(gettext("Depth (m)"))

        if len(self.variables) > 0:
            plt.suptitle("\n".join(
                wrap(
                    gettext("Profile for %s, Observed at %s, Modelled at %s")
                    % (
                        ", ".join(self.names),
                        format_datetime(self.observation_time),
                        format_datetime(self.timestamp)
                    ), 80)
            ))
        else:
            plt.suptitle("\n".join(
                wrap(
                    gettext("Profile for %s (%s)") % (
                        ", ".join(self.names),
                        format_datetime(self.observation_time)
                    ), 80)
            ))

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

        return super(ObservationPlotter, self).plot()
예제 #20
0
    def plot(self):
        v = set([])
        for idx in self.observation_variable:
            v.add(self.observation_variable_names[idx])
        for n in self.variable_names:
            v.add(n)

        numplots = len(v)

        fig, ax = self.setup_subplots(numplots)

        data = []
        for o in self.observation:
            d = np.ma.MaskedArray(o['data'])
            d[np.where(d == '')] = np.ma.masked
            d = np.ma.masked_invalid(d.filled(np.nan).astype(np.float32))
            data.append(d)

        ureg = pint.UnitRegistry()
        ax_idx = -1
        udepth = ureg.parse_expression(self.observation[0]['depthunit'])
        axis_map = {}
        unit_map = {}
        for idx in self.observation_variable:
            ax_idx += 1
            for d in data:
                ax[ax_idx].plot(
                    d[:, idx],
                    self.observation[0]['depth'] * udepth.to(ureg.meter)
                )
            ax[ax_idx].xaxis.set_label_position('top')
            ax[ax_idx].xaxis.set_ticks_position('top')
            ax[ax_idx].set_xlabel("%s (%s)" % (
                self.observation_variable_names[idx],
                utils.mathtext(self.observation_variable_units[idx]),
            ))
            axis_map[self.observation_variable_names[idx]] = ax[ax_idx]

            try:
                if "_" in self.observation_variable_units[idx]:
                    u = self.observation_variable_units[idx].lower().split(
                        "_",
                        1
                    )[1]
                else:
                    u = self.observation_variable_units[idx].lower()
                unit_map[
                    self.observation_variable_names[idx]] = ureg.parse_units(u)

            except:
                unit_map[
                    self.observation_variable_names[idx]] = ureg.dimensionless

        for k, v in unit_map.iteritems():
            if v == ureg.speed_of_light:
                unit_map[k] = ureg.celsius

        for idx, var in enumerate(self.variables):
            if axis_map.get(self.variable_names[idx]) is not None:
                axis = axis_map.get(self.variable_names[idx])
                showlegend = True
                destunit = unit_map.get(self.variable_names[idx])
            else:
                ax_idx += 1
                axis = ax[ax_idx]
                showlegend = False
                try:
                    destunit = ureg.parse_units(
                        self.variable_units[idx].lower())
                    if destunit == ureg.speed_of_light:
                        destunit = ureg.celsius

                except:
                    destunit = ureg.dimensionless

            for j in range(0, self.data.shape[0]):
                try:
                    u = ureg.parse_units(self.variable_units[idx].lower())
                    if u == ureg.speed_of_light:
                        u = ureg.celsius

                    quan = ureg.Quantity(self.data[j, idx, :], u)
                except:
                    quan = ureg.Quantity(
                        self.data[j, idx, :], ureg.dimensionless)

                axis.plot(quan.to(destunit).magnitude, self.depths[j, idx, :])

            showlegend = showlegend or len(self.observation) > 1
            if not showlegend:
                axis.xaxis.set_label_position('top')
                axis.xaxis.set_ticks_position('top')
                axis.set_xlabel("%s (%s)" % (
                    self.variable_names[idx],
                    utils.mathtext(self.variable_units[idx]),
                ))
            else:
                l = []
                for j in [
                    (gettext("Observed"), self.observation_times),
                    (gettext("Modelled"), self.timestamps)
                ]:
                    for i, name in enumerate(self.names):
                        if len(self.names) == 1:
                            name = ""
                        else:
                            name = name + " "

                        l.append("%s%s (%s)" % (
                            name,
                            j[0],
                            format_datetime(j[1][i])
                        ))

                leg = axis.legend(l, loc='best')

                for legobj in leg.legendHandles:
                    legobj.set_linewidth(4.0)

        ax[0].invert_yaxis()
        ax[0].set_ylabel(gettext("Depth (m)"))

        if len(self.variables) > 0:
            plt.suptitle("\n".join(
                wrap(
                    gettext("Profile for %s, Observed at %s, Modelled at %s")
                    % (
                        ", ".join(self.names),
                        format_datetime(self.observation_time),
                        format_datetime(self.timestamp)
                    ), 80)
            ))
        else:
            plt.suptitle("\n".join(
                wrap(
                    gettext("Profile for %s (%s)") % (
                        ", ".join(self.names),
                        format_datetime(self.observation_time)
                    ), 80)
            ))

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

        return super(ObservationPlotter, self).plot()
예제 #21
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

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

            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)

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

        # Put y-axis label on left-most graph
        if self.showmap:
            plt.subplot(gs[:, 1])
        else:
            plt.subplot(gs[:, 0])
        plt.gca().set_ylabel(gettext("Depth (m)"), fontsize=14)

        self.plot_legend(fig, self.names)

        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)
        fig.tight_layout()
        fig.subplots_adjust(top=(0.8))

        return super(ProfilePlotter, self).plot(fig)