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)
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)
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)))
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)
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)
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)
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)
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)
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)
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)
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
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)
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)
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)
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)
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)
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()
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()
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)