def settextstyle(font='', color='', bold = False, italic=False): """ Sets the text style for any text in plots generated after this command using the Ferret SET TEXT command. font (string): name of the font to use; if empty, 'Arial' is used. color (string): color name, RGB tuple, or RGBA tuple describing the color of the text. The R,G,B, and A components are integer percentages; thus values in [0,100] bold (bool): use bold font? italic (bool): use italic font? """ # First run CANCEL TEXT to clear any /BOLD and /ITALIC (errval, errmsg) = pyferret.run('CANCEL TEXT/ALL') if errval != pyferret.FERR_OK: raise ValueError('problems resetting text style to default: %s' % errmsg) # Now run SET TEXT with the appropriate qualifiers cmdstr = 'SET TEXT' if font: cmdstr += '/FONT=' cmdstr += font else: cmdstr += '/FONT=Arial' if color: cmdstr += '/COLOR=' + str(color) if bold: cmdstr += '/BOLD' if italic: cmdstr += '/ITALIC' (errval, errmsg) = pyferret.run(cmdstr) if errval != pyferret.FERR_OK: raise ValueError('problems setting text style (%s): %s' % (cmdstr, errmsg))
def shadeplot(fvar, region=None, over=False, qual=''): """ Create a colored plot of the specified Ferret variable using the Ferret SHADE command. (Plot coloring grid cells based on the variable value in that cell.) The variable needs to be 2D (or qualifiers need to be added to specify a 2D slice). fvar (string or FerVar): Ferret variable to plot region (FerRegion): space-time region to plot; if None, the full extents of the data will be used over (bool): overlay on an existing plot? qual (string): qualifiers to add to the Ferret SHADE command """ if not isinstance(qual, str): raise ValueError('qual (Ferret qualifiers) must be a string') if isinstance(fvar, str): plotvar = fvar elif isinstance(fvar, pyferret.FerVar): plotvar = fvar._definition else: raise ValueError( 'fvar (Ferret variable to plot) must be a string or FerVar') cmdstr = 'SHADE' if over: cmdstr += '/OVER' if region is not None: if not isinstance(region, pyferret.FerRegion): raise ValueError('region, if given, must be a FerRegion') cmdstr += region._ferretqualifierstr() if qual: cmdstr += qual cmdstr += ' ' cmdstr += plotvar (errval, errmsg) = pyferret.run(cmdstr) if errval != pyferret.FERR_OK: raise ValueError('Ferret shade command (%s) failed: %s' % (cmdstr, errmsg))
def _assigninferret(self, varname, dsetname): ''' Defines this FerVar in Ferret using the given variable name associated with the given dataset name. varname (string): name for the variable in Ferret dsetname (string): name of the dataset to contain the variable Raises a ValueError if there is a problem. ''' if not self._definition: raise ValueError('this FerVar does not contain a definition') if not varname: raise ValueError('variable name to be assigned is not given') if varname.upper() in self._requires: raise ValueError( 'recursive definitions cannot be implemented in Ferret') # Assign the variable in Ferret cmdstr = 'DEFINE VAR' if dsetname: cmdstr += '/D="%s"' % dsetname if self._title: cmdstr += '/TITLE="%s"' % self._title cmdstr += ' %s = %s' % (varname, self._definition) (errval, errmsg) = pyferret.run(cmdstr) if errval != pyferret.FERR_OK: raise ValueError('problems defining %s (%s) in Ferret: %s' % (varname, cmdstr, errmsg)) # Revise the fields in this FerVar to reflect this assignment self._markasknownvar(varname, dsetname, False)
def close(self): ''' Removes (cancels) all the (non-file) variables in Ferret associated with this dataset, then closes (cancels) this dataset in Ferret (which removes the file variables as well). Raises a ValueError if there is a problem. ''' # if the dataset is already closed, ignore this command if self._filename and not self._dsetname: return # remove all the Ferret variables associated with this dataset, # ignoring errors from trying to remove file variables. for name in self._fervars: try: # remove this variable from Ferret self._fervars[name]._removefromferret() except NotImplementedError: pass # remove all the FerVar's from _fervars self._fervars.clear() self._fervarnames = [] # nothing else to do if an anonymous dataset if not self._dsetname: return # now remove the dataset cmdstr = 'CANCEL DATA "%s"' % self._dsetname (errval, errmsg) = pyferret.run(cmdstr) if errval != pyferret.FERR_OK: raise ValueError('unable to remove dataset "%s" in Ferret: %s' % self._dsetname) # mark this dataset as closed self._dsetname = ''
def show(self, brief=True, qual=''): ''' Show the Ferret information about this dataset. This uses the Ferret SHOW DATA command to create and display the information. brief (boolean): if True (default), a brief report is shown; otherwise a full report is shown. qual (string): Ferret qualifiers to add to the SHOW DATA command If this is the anonymous dataset (no dataset name), the Ferret SHOW VAR/USER command is used instead to show all variables created by this anonymous dataset. ''' # if the dataset is closed, ignore this command if self._filename and not self._dsetname: return if not isinstance(qual, str): raise ValueError('qual (Ferret qualifiers) must be a string') if not self._dsetname: cmdstr = 'SHOW VAR/USER' if qual: cmdstr += qual else: cmdstr = 'SHOW DATA' if not brief: cmdstr += '/FULL' if qual: cmdstr += qual cmdstr += ' "' cmdstr += self._dsetname cmdstr += '"' (errval, errmsg) = pyferret.run(cmdstr) if errval != pyferret.FERR_OK: raise ValueError('Ferret command "%s" failed: %s' % (cmdstr, errmsg))
def load_chl(lon, lat, dt): # Load the data set and store as a Python variable (e_v, e_m) = pyferret.run('cancel data /all') (e_v, e_m) = pyferret.run('cancel variables /all') (e_v, e_m) = pyferret.run( 'use /mnt/courses/eos1505/MODIS/MODIS_'+dt+'.cdf') chl_dict = pyferret.getdata('CHL_FILL[x='+str(lon)+', y='+str(lat)+']',False) # Put the data into Python arrays chl = np.squeeze(chl_dict['data']) # Mask out fill values chl[chl < 0] = np.nan ymdhms = np.zeros(np.shape(chl_dict['axis_coords'][3])).astype(int) ymdhms[:,0] = chl_dict['axis_coords'][3][:,2].astype(int) ymdhms[:,1] = chl_dict['axis_coords'][3][:,1].astype(int) ymdhms[:,2] = chl_dict['axis_coords'][3][:,0].astype(int) chl_dates = [datetime.datetime(*dd) for dd in ymdhms] return chl, chl_dates
def saveplot(name, fmt='', xpix=None, ypix=None, xinch=None, yinch=None, qual=''): """ Save the current plot. If format is not given, the format is guessed from the filename extension. name (string): name of the file to contain the plot fmt (string): format of the plot file xpix (int): number of pixels in width of the saved raster (eg, PNG) plot ypix (int): number of pixels in the height of the saved raster (eg, PNG) plot xinch (float): inch width of the saved vector (eg, PDF) plot yinch (float): inch height of the save vector (eg, PDF) plot qual (string): qualifiers to add to the Ferret FRAME command """ if not isinstance(name, str): raise ValueError('name (plot file name) must be a string') cmdstr = 'FRAME/FILE="%s"' % name if not isinstance(fmt, str): raise ValueError('fmt (plot file format) must be a string') if fmt: cmdstr += '/FORMAT=%s' % fmt if xpix is not None: if (not isinstance(xpix, int)) or (xpix <= 0): raise ValueError('xpix must be a positive integer') cmdstr += '/XPIX=' + str(xpix) if ypix is not None: if (not isinstance(ypix, int)) or (ypix <= 0): raise ValueError('ypix must be a positive integer') cmdstr += '/YPIX=' + str(ypix) if (xpix is not None) and (ypix is not None): raise ValueError('xpix and ypix cannot both be given') if xinch is not None: if (not isinstance(xinch, numbers.Real)) or (xinch <= 0.0): raise ValueError('xinch must be a positive number') cmdstr += '/XINCH=' + str(xinch) if yinch is not None: if (not isinstance(yinch, numbers.Real)) or (yinch <= 0.0): raise ValueError('yinch must be a positive number') cmdstr += '/YINCH=' + str(yinch) if (xinch is not None) and (yinch is not None): raise ValueError('xinch and yinch cannot both be given') if not isinstance(qual, str): raise ValueError('qual (Ferret qualifiers) must be a string') if qual: cmdstr += qual (errval, errmsg) = pyferret.run(cmdstr) if errval != pyferret.FERR_OK: raise ValueError('Ferret frame command (%s) failed: %s' % (cmdstr, errmsg))
def __init__(self, filename, title='', qual=''): ''' "Opens" the given NetCDF dataset file in Ferret using the Ferret "USE" command. Creates a FerVar for each data variable in this data file and assigns it as an attribute of this class using the variable name. filename (string): name of the dataset filename or http address title (string): title for the dataset for plots and listing; if not given, the Ferret name for the dataset will be used qual (string): Ferret qualifiers to be used with the "USE" command ''' self._filename = '' self._dsetname = '' self._fervars = {} self._fervarnames = set() if not filename: if qual == _anonymous_dataset_qualifier: # initialize an new anonymous dataset that will either be # pyferret.anondset or will be modified by a subclass (FerAggDSet) return else: raise ValueError( 'pyferret.anondset should be used for the anonymous dataset' ) # tell Ferret to open/use this dataset cmdstr = 'USE' if title: cmdstr += '/TITLE="' + str(title) + '"' if qual: cmdstr += str(qual) cmdstr += ' "' + str(filename) + '"' (errval, errmsg) = pyferret.run(cmdstr) if errval != pyferret.FERR_OK: raise ValueError(errmsg) # record the filename and Ferret dataset name self._filename = filename # need to use the filename as given as the dataset name to avoid possible abiguity self._dsetname = filename # create a FerVar for each variable in this dataset namesdict = pyferret.getstrdata('..varnames') for varname in namesdict['data'].flatten(): if sys.version_info[0] > 2: # For Python3.x, namesdict['data'] is a NumPy array of bytes; convert to unicode varname = str(varname, 'UTF-8') # create a FerVar representing this existing Ferret file variable filevar = pyferret.FerVar() filevar._markasknownvar(varname, self._dsetname, True) # assign this FerVar - uppercase the variable name keys to make case-insensitive self._fervars[varname.upper()] = filevar # keep a original-case version of the name self._fervarnames.add(varname)
def shadeland(res=20, color='gray', over=True, solid=True, X=None, Y=None): """ Shades land masses for the current longitude-latitude plot or the specified X-Y region. res (int): ETOPO dataset resolution (in minutes of a degree) to use; the corresponding ETOPO dataset (eg, etopo20.cdf for 20) must be available. Typically 5, 10, 20, 40, 60, 120 are available from Ferret's standard datasets. color (str): name of the color or color palette to used for land. over (bool): if true, overlay onto the current longitude-latitude plot; if False, create a new plot of the given region solid (bool): if True, shade the land in a single solid color; if False, shade different elevations using the given color palette X (str): longitude limits for the region as low:high If not given and over is False, '0E:360E' is used. if not given and over is True, the full range of the given plot is used. Y (str): latitude limits for the region as low:high If not given and over is False, '90S:90N' is used. If not given and over is True, the full range of the given plot is used. """ cmdstr = 'GO fland' cmdstr += ' ' + str(res) cmdstr += ' ' + str(color) if over: cmdstr += ' OVERLAY' else: cmdstr += ' BASEMAP' if solid: cmdstr += ' SOLID' else: cmdstr += ' DETAILED' if X is not None: cmdstr += ' X=' + str(X) elif not over: # assign the default here even though this matches the script cmdstr += ' X=0E:360E' elif Y is not None: # if Y is given, then have to have an X argument; # needs to be a double wrap for a complete overlay cmdstr += ' X=0E:720E' if Y is not None: cmdstr += ' Y=' + str(Y) elif not over: # assign the default here even though this matches the script cmdstr += ' Y=90S:90N' (errval, errmsg) = pyferret.run(cmdstr) if errval != pyferret.FERR_OK: raise ValueError('Ferret script command (%s) failed: %s' % (cmdstr, errmsg))
def showgrid(self, qual=''): ''' Show the Ferret grid information about this variable. This uses the Ferret SHOW GRID command to create and display the information. qual (string): Ferret qualifiers to add to the SHOW GRID command ''' if not isinstance(qual, str): raise ValueError('qual (Ferret qualifiers) must be a string') cmdstr = 'SHOW GRID' if qual: cmdstr += qual cmdstr += ' ' cmdstr += self.fername() (errval, errmsg) = pyferret.run(cmdstr) if errval != pyferret.FERR_OK: raise ValueError('Ferret command "%s" failed: %s' % (cmdstr, errmsg))
def _removefromferret(self): ''' Removes (cancels) this PyVar in Ferret, then erases _varname. Raises a ValueError if there is a Ferret problem. This normally is not called by the user; instead delete the FerPyVar from the dataset. ''' # ignore if this Ferrer PyVar has already been removed from Ferret if not self._varname: return fername = self.fername() cmdstr = 'CANCEL PYVAR %s' % fername (errval, errmsg) = pyferret.run(cmdstr) if errval != pyferret.FERR_OK: raise ValueError('unable to remove PyVar %s from Ferret: %s' % (fername, errmsg)) self._varname = ''
def showdata(brief=True, qual=''): """ Show the Ferret information about all datasets currently open in Ferret. This uses the Ferret SHOW DATA command to create and display the information. brief (boolean): if True (default), a brief report is shown; otherwise a full report is shown. qual (string): Ferret qualifiers to add to the SHOW DATA command """ if not isinstance(qual, str): raise ValueError('qual (Ferret qualifiers) must be a string') cmdstr = 'SHOW DATA' if not brief: cmdstr += '/FULL' if qual: cmdstr += qual (errval, errmsg) = pyferret.run(cmdstr) if errval != pyferret.FERR_OK: raise ValueError('Ferret command "%s" failed: %s' % (cmdstr, errmsg))
def settitle(self, title): ''' Assigns the title (long descriptive name) for this FerVar. If this variable is defined in Ferret, the title for the Ferret variable is also updated. title (string): title to assign Raises ValueError if title is not a string or if there is a problem updating the title in Ferret ''' if title: if not isinstance(title, str): raise ValueError("title is not a string") self._title = title else: self._title = '' if self._varname: cmdstr = 'SET VAR/TITLE="%s" %s' % (self._title, self.fername()) (errval, errmsg) = pyferret.run(cmdstr) if errval != pyferret.FERR_OK: raise ValueError('problems updating the variable title in Ferret for ' + \ '%s to "%s": %s' % (self.fername(), self._title, errmsg))
def _removefromferret(self): ''' Removes (cancels) this variable in Ferret, then unloads this FerVar and erases _varname. Raises a NotImplementedError is this is a file variable. Raises a ValueError if there is a Ferret problem. This normally is not called by the user; instead delete the FerVar from the dataset. ''' # ignore if this Ferrer variable has already been removed from Ferret if not self._varname: return fername = self.fername() if self._isfilevar: raise NotImplementedError( '%s is a file variable; close the dataset to remove' % fername) cmdstr = 'CANCEL VAR %s' % fername (errval, errmsg) = pyferret.run(cmdstr) if errval != pyferret.FERR_OK: raise ValueError('unable to remove variable %s from Ferret: %s' % (fername, errmsg)) self._varname = '' self.unload()
def fillplot(fvar, region=None, line=False, over=False, pal=None, qual=''): """ Create a color-filled contour plot of the specified Ferret variable using the Ferret FILL command. Drawing of the contour lines themselves is optional. The variable needs to be 2D (or qualifiers need to be added to specify a 2D slice). fvar (string or FerVar): Ferret variable to plot region (FerRegion): space-time region to plot; if None, the full extents of the data will be used line (bool): draw the contour lines? over (bool): overlay on an existing plot? pal (string): color palette to use qual (string): qualifiers to add to the Ferret SHADE command """ if not isinstance(qual, str): raise ValueError('qual (Ferret qualifiers) must be a string') if isinstance(fvar, str): plotvar = fvar elif isinstance(fvar, pyferret.FerVar): plotvar = fvar._definition else: raise ValueError('fvar (Ferret variable to plot) must be a string or FerVar') cmdstr = 'FILL' if line: cmdstr += '/LINE' if over: cmdstr += '/OVER' if region is not None: if not isinstance(region, pyferret.FerRegion): raise ValueError('region, if given, must be a FerRegion') cmdstr += region._ferretqualifierstr(); if pal is not None: cmdstr += '/PALETTE=' + str(pal) if qual: cmdstr += qual cmdstr += ' ' cmdstr += plotvar (errval, errmsg) = pyferret.run(cmdstr) if errval != pyferret.FERR_OK: raise ValueError('Ferret shade command (%s) failed: %s' % (cmdstr, errmsg))
def load_mnc_profile(sgid,dive_number): # Wipe any previously loaded data and variables in # Ferret. These lines allow for multiple reuse of # this function in a given kernel session. (e_v, e_m) = pyferret.run('cancel data /all') (e_v, e_m) = pyferret.run('cancel variables /all') # Set a shorter variable name for number of dives. # If the glider data has climbs and dives, mult # by 2 and subtract 1 to index just the dives. dn = dive_number*2 - 1 # Load the requested data into the notebook (e_v, e_m) = pyferret.run( 'use /mnt/courses/eos1505/sg'+str(sgid)+'/sg'+str(sgid)+'_m03.nc') # Assign subsets of the data in Ferret - we want to pull out # just the data for this particular dive, not the whole mission. (e_v, e_m) = pyferret.run('let temp = theta[l='+str(dn)+']') (e_v, e_m) = pyferret.run('let salt = salinity[l='+str(dn)+']') (e_v, e_m) = pyferret.run('let dens = density[l='+str(dn)+']') (e_v, e_m) = pyferret.run('let dept = ctd_depth[l='+str(dn)+']') # Bring the data from Ferret into the Notebook temp = np.squeeze(pyferret.getdata('temp',False)['data']) salt = np.squeeze(pyferret.getdata('salt',False)['data']) dens = np.squeeze(pyferret.getdata('dens',False)['data']) dept = np.squeeze(pyferret.getdata('dept',False)['data']) # Filter out missing values (usually the placeholder is # a very large negative number, 1e-34) temp[temp<-4.0] = np.nan salt[salt<0] = np.nan dens[dens<900] = np.nan return dept, temp, salt, dens
def ferret_run_code(self, args, code): """ Parameters ---------- args : control arguments for running (py)ferret code : ferret commands to run """ # Temporary directory; create under the current directory # so PDF link files are accessible temp_dir = tempfile.mkdtemp(dir='.', prefix='ipyferret_').replace('\\', '/') # Redirect stdout and stderr to file out_filename = temp_dir + '/output.txt' if not(args.quiet): (errval, errmsg) = pyferret.run('set redirect /clobber /file="%s" stdout' % out_filename) # Filename for saving the final plot (if any) if args.plotname: plot_filename = str(args.plotname) if args.pdf: if not plot_filename.endswith('.pdf'): plot_filename += '.pdf' else: if not plot_filename.endswith('.png'): plot_filename += '.png' elif args.pdf: plot_filename = temp_dir + '/image.pdf' else: plot_filename = temp_dir + '/image.png' # Make it quiet by default (errval, errmsg) = pyferret.run('cancel mode verify') if args.memory: # Reset memory size in megabytes mem_size = float(args.memory) if mem_size > 0.0: (errval, errmsg) = pyferret.run('set memory /size=%f' % (mem_size/8.0)) # Get image size and aspect ratio if args.size: plot_size = args.size.split(',') else: plot_size = _DEFAULT_PLOTSIZE.split(',') plot_width = float(plot_size[0]) plot_height = float(plot_size[1]) plot_aspect = plot_height / plot_width # Get window outline arg if args.outline: window_outline = float(args.outline) else: window_outline = _DEFAULT_OUTLINE # Set window size with the required aspect ratio; # always anti-alias with windows of these sizes canvas_width = math.sqrt(plot_width * plot_height / plot_aspect) if args.bigger: # Double the width and height of the window, but the image will # be saved at the original requested size. # Reducing the raster image when saving it sharpens the image. canvas_width *= 2.0 (errval, errmsg) = pyferret.run('set window /xpixel=%f /aspect=%f /outline=%f 1' % \ (canvas_width, plot_aspect, window_outline)) # Run code pyferret_error = False for input in code: # Ignore blank lines if input: input = unicode_to_str(input) (errval, errmsg) = pyferret.run(input) if errval != pyferret.FERR_OK: errmsg = errmsg.replace('\\', '<br />') publish_display_data({'text/html': '<pre style="background-color:#F79F81; border-radius: 4px 4px 4px 4px; font-size: smaller">' + 'yes? %s\n' % input + '%s' % errmsg + '</pre>' }) pyferret_error = True break # Create the image file; if no final image, no image file will be created. # Any existing image with that filename will be versioned away ('.~n~' appended) if not pyferret_error: if args.pdf: (errval, errmsg) = pyferret.run('frame /xinch=%f /file="%s" /format=PDF' % (plot_width/72.0, plot_filename) ) else: (errval, errmsg) = pyferret.run('frame /xpixel=%f /file="%s" /format=PNG' % (plot_width, plot_filename)) if errval != pyferret.FERR_OK: pyferret_error = True # Close the window (errval, errmsg) = pyferret.run('cancel window 1') # Close the stdout and stderr redirect file if not(args.quiet): (errval, errmsg) = pyferret.run('cancel redirect') #------------------------------- # Publish display_data = [] # Publish captured stdout text, if any if os.path.isfile(out_filename) and (os.path.getsize(out_filename) > 0): try: text_outputs = [] text_outputs.append('<pre style="background-color:#ECF6CE; border-radius: 4px 4px 4px 4px; font-size: smaller">') f = open(out_filename, "r") for line in f: text_outputs.append(line) f.close() text_outputs.append("</pre>") text_output = "".join(text_outputs) display_data.append((_PUBLISH_KEY, {'text/html': text_output})) except: pass # Publish image if present if not pyferret_error: if args.pdf: if os.path.isfile(plot_filename): # Create link to pdf; file visible from cell from files directory text_outputs = [] text_outputs.append('<pre style="background-color:#F2F5A9; border-radius: 4px 4px 4px 4px; font-size: smaller">') text_outputs.append('Message: <a href="files/%s" target="_blank">%s</a> created.' % (plot_filename, plot_filename)) text_outputs.append('</pre>') text_output = "".join(text_outputs) display_data.append((_PUBLISH_KEY, {'text/html': text_output})) # If the user did not provide the PDF filename, # do not delete the temporary directory since the PDF is in there. if args.plotname: rmtree(temp_dir) else: # Delete temporary directory - nothing to preserve rmtree(temp_dir) else: # Display the image in the notebook try: f = open(plot_filename, 'rb') #image = f.read().encode('base64') image = base64.b64encode(f.read()).decode('utf8') f.close() display_data.append((_PUBLISH_KEY, {'text/html': '<div class="myoutput">' + '<img src="data:image/png;base64,%s"/></div>' % image})) except: pass # Delete temporary directory - PNG encoded in the string rmtree(temp_dir) # Error in ferret code - Delete temporary directory else: rmtree(temp_dir) # Publication for source, data in display_data: # http://ipython.readthedocs.io/en/stable/api/generated/IPython.display.html#IPython.display.publish_display_data # --> source unused publish_display_data(data)
def setwindow(num=1, plotasp=None, axisasp=None, color=None, pal=None, thick=None, logo=None, outline=None): """ Assigns the plot window to use for subsequent plotting commands. Also provides assignment of common window plots. Note that plotasp and axisasp cannot both be given. num (int): window number 1-8 to use for plots. plotasp (float): aspect ratio (Y/X) for the plot window. If not given, the current ratio is unchanged. The default ratio on start-up is 0.86 axisasp (float): aspect ratio (Y/X) for the plot axes. If not given, the current ratio is unchanged. The default ratio on start-up is 0.75 color (string, tuple of int): background color for the plot; can be one of the color names 'black', 'blue', 'green', 'lightblue', 'purple', or 'red', or a tuple of int values in [0,100] giving RGB or RGBA values. If not given, the current value is unchanged. The default background color on start-up is opaque white. pal (string): default color palette to use in plots. If not given, thr current value is unchanged. thick (float): line thickness scaling factor for the plot. If not given, the current scaling factor is unchanged. The default line thickness scaling factor on start-up is 1.0 logo (boolean): include the Ferret logo in the plot? If not given, the current value is unchanged. The default on start-up is to include the logo. outline (float): if positive, thickness of polygon outlines; used to fix the 'thin white line' issue in plots. If not given, the current value is unchanged. The default on start-up is zero (no outlines drawn). Raises a ValueError if a problem occurs. """ # create and execute the SET WINDOW command cmdstr = 'SET WINDOW' if (plotasp is not None) and (axisasp is not None): raise ValueError('only one of plotasp and axisasp can be given') if plotasp is not None: if (not isinstance(plotasp, numbers.Real)) or (plotasp <= 0): raise ValueError('plotasp, if given, must be a positive number') cmdstr += '/ASPECT=' + str(plotasp) if axisasp is not None: if (not isinstance(axisasp, numbers.Real)) or (axisasp <= 0): raise ValueError('axisasp, if given, must be a positive number') cmdstr += '/ASPECT=' + str(axisasp) + ':AXIS' if thick is not None: if (not isinstance(thick, numbers.Real)) or (thick <= 0): raise ValueError('thick, if given, must be a positive number') cmdstr += '/THICK=' + str(thick) if outline is not None: if (not isinstance(outline, numbers.Real)) or (outline < 0): raise ValueErrror('outline, if given, must be a non-negative number') cmdstr += '/OUTLINE=' + str(outline) if color is not None: if isinstance(color, str): cmdstr += '/COLOR=' + color elif isinstance(color, tuple): if (len(color) < 3) or (len(color) > 4): raise ValueError('a color tuple must have three or four integer values') cmdstr += '/COLOR=' + str(color) else: raise ValueError('given color %s is not a string or tuple' % str(color)) if (not isinstance(num, numbers.Integral)) or (num <= 0) or (num > 8): raise ValueError('window number %s is not a integer in [1,8]' % str(num)) cmdstr += ' ' + str(num) (errval, errmsg) = pyferret.run(cmdstr) if errval != pyferret.FERR_OK: raise ValueError('Problems executing Ferret command %s: %s' % (cmdstr, errmsg)) if pal is not None: cmdstr = 'PALETTE ' + str(pal) (errval, errmsg) = pyferret.run(cmdstr) if errval != pyferret.FERR_OK: raise ValueError('Problems executing Ferret command %s: %s' % (cmdstr, errmsg)) # create and execute the mode logo command if logo is given if logo is not None: if logo: cmdstr = 'SET MODE LOGO' else: cmdstr = 'CANCEL MODE LOGO' (errval, errmsg) = pyferret.run(cmdstr) if errval != pyferret.FERR_OK: raise ValueError('Problems executing Ferret command %s: %s' % (cmdstr, errmsg))
def load_topo(): # Load the data set and store as a Python variable # Python dictionaries are a type of variable that # stores the data along with its metadata. # # The pyferret.getdata commands are accessing data # by variable name in the given file. If you ever # need to explore the available variables in a # NetCDF file, use the following command at the # *terminal*: # # ncdump -h /mnt/courses/eos2680/ETOPO1/topo_tenthdeg_ice_gline.nc # # and all the information about the NetCDF file # will be displayed. (e_v, e_m) = pyferret.run('cancel data /all') (e_v, e_m) = pyferret.run('cancel variables /all') (error_value, error_message) = pyferret.run( 'use /mnt/courses/eos2680/ETOPO1/topo_tenthdeg_ice_gline.nc') lon_dict = pyferret.getdata('lon1',False) lat_dict = pyferret.getdata('lat1',False) topo_dict = pyferret.getdata('z1',False) # The "keys" are the names of the entries in the # dictionary - its pieces. You can access the values # associated with a dictionary's keys with # dict_name['key_name']. #print(topo_dict.keys()) # Put the data into Python arrays lon = lon_dict['data'] lat = lat_dict['data'] topo = topo_dict['data'] # And you can see the size of the data array # which is a grid in the x, y, directions but # the z (depth), time, and other dimensions # are placeholder dimensions in that they have # only a length of 1. #print('Array size:') #print(np.shape(topo)) # To cut out these singleton dimensions, use # the squeeze command: lon = np.squeeze(lon) lat = np.squeeze(lat) topo = np.squeeze(topo) #print('Array size after squeeze:') #print(np.shape(topo)) # Note that all of the above can be condensed # into one line, but it's much harder to # understand and verify that the code is working # in the condensed version (commented out below). #lon = np.squeeze(pyferret.getdata('lon1',False)['data']) #lat = np.squeeze(pyferret.getdata('lat1',False)['data']) #topo = np.squeeze(pyferret.getdata('z1',False)['data']) # Finally, lon and lat are given as # vectors, for plotting it is easier # to expand them into 2D arrays to # have the same size as topo. [y,x] = np.meshgrid(lat,lon) return x, y, topo
def regrid_once_primitive(var, ref_var, axis, verbose=False, prerun=None, transform='@ave'): ''' A generic function that regrids a variable without the dependence of geodat.nc.Variable Args: var (dict) : arguments for num2fer Required keys: data,coords,dimunits ref_var (dict) : arguments for num2fer. This supplies the grid for regridding Required keys: coords,dimunits axis (str) : the axis for regridding e.g. 'X'/'Y'/'XY'/"YX" verbose (bool) : whether to print progress (default: False) prerun (a list of str) : commands to be run at the start (default: None) transform (str): "@ave" (Conserve area average), "@lin" (Linear interpolation),...see Ferret doc Returns: dict ''' if not PYFERRET_INSTALLED: raise _IMPORT_PYFERRET_ERROR pyferret.start(quiet=True, journal=verbose, verify=False, server=True) # commands to run before regridding if prerun is not None: if type(prerun) is str: pyferret.run(prerun) elif type(prerun) is list: for s in prerun: if type(s) is str: pyferret.run(prerun) else: raise Exception("prerun has to be either a string or "+\ "a list of string") else: raise Exception("prerun has to be either a string or a list of "+\ "string") assert isinstance(axis, str) axis = axis.upper() # Make sure axis is a string denoting X or Y axis #if axis not in ['X', 'Y', 'XY', 'YX']: # raise Exception("Currently axis can only be X/Y/XY") # Construct the source data read by pyferret.putdata source_fer = num2fer(**var) source_fer["name"] = "source" # Fill in unnecessary input for Ferret if "data" not in ref_var: ref_var['data'] = numpy.zeros((1,)*len(ref_var['coords'])) # Construct the destination data read by pyferret.putdata dest_fer = num2fer(**ref_var) dest_fer["name"] = "dest" if verbose: print source_fer print dest_fer pyferret.putdata(source_fer, axis_pos=source_fer['axis_pos']) if verbose: print "Put source variable" pyferret.run('show grid source') pyferret.putdata(dest_fer, axis_pos=dest_fer['axis_pos']) if verbose: print "Put destination variable" pyferret.run('show grid dest') pyfer_command = 'let result = source[g'+axis.lower()+'=dest'+transform+']' pyferret.run(pyfer_command) if verbose: print "Regridded in FERRET" pyferret.run('show grid result') # Get results result_ref = pyferret.getdata('result') if verbose: print "Get data from FERRET" # Convert from ferret data structure to geodat.nc.Variable tmp_result = fer2num(result_ref) if 'varname' in var: tmp_result['varname'] = var['varname'] tmp_caxes = [geodat.units.assign_caxis(dimunit) for dimunit in tmp_result['dimunits']] var_caxes = [geodat.units.assign_caxis(dimunit) for dimunit in var['dimunits']] # Preserve dimension order (Ferret reverts the order) neworder = [tmp_caxes.index(cax) for cax in var_caxes] # Change the dimension order of the result to match with the input tmp_result['coords'] = [tmp_result['coords'][iax] for iax in neworder] tmp_result['dimunits'] = [tmp_result['dimunits'][iax] for iax in neworder] if 'dimnames' in tmp_result: tmp_result['dimnames'] = [tmp_result['dimnames'][iax] for iax in neworder] tmp_result['data'] = tmp_result['data'].transpose(neworder).astype( var['data'].dtype) # Return the input var with the data and dimensions replaced by # the regridded ones var.update(tmp_result) result = var status = pyferret.stop() if verbose: if status: print "PyFerret stopped." else: print "PyFerret failed to stop." return result
def __init__(self, name, dsets, along='T', title='', warn=True, hide=False): ''' Aggregates the given list of datasets along the given axis using the Ferret "DEFINE DATA /AGGREGATE" command. Creates a FerVar for each data variable in common among these datasets, and assigns it as an attribute of this class instance using the variable name. name (string): Ferret name for this aggregated dataset dsets (sequence of strings and/or FerDSets): datasets to aggregate. A string will be interpreted as a filename for creating a FerDSet. along ('T', 'E', 'F'): axis along which to aggregate the datasets title (string): title for the dataset for plots and listing; if not given, the Ferret name for the dataset will be used warn (bool): issue warning messages about variables not in common among all member datasets (either not present or not using the same grid) hide (bool): hide the member datasets in standard Ferret listings such as with pyferret.showdata() ''' # Create an empty dataset with the given Ferret name super(FerAggDSet, self).__init__('', qual=_anonymous_dataset_qualifier) if not isinstance(name, str): raise ValueError('Ferret name for the aggregate dataset must be astring') aggname = name.strip() if not aggname: raise ValueError('Ferret name for the aggregate dataset is blank') self._filename = aggname self._dsetname = aggname # Need to keep the given order of component datasets self._compdsetnames = [ ] # But still use a dictionary with uppercase names for keys self._compdsets = { } if along not in ('T', 'E', 'F'): raise ValueError("along must be one of 'T', 'E', or 'F'") self._along = along self._comphidden = bool(hide) # Create a Ferret string variable containing all the dataset names to be aggregated if not ( isinstance(dsets, tuple) or isinstance(dsets, list) ): raise ValueError('dsets must be a tuple or list of strings and/or FerDSets') filesfile = tempfile.NamedTemporaryFile(mode='w', delete=False, prefix=aggname + '_', suffix='_agg.txt') filesfilename = filesfile.name deletefilesfile = True try: for myitem in dsets: if isinstance(myitem, str): mydset = pyferret.FerDSet(myitem) elif isinstance(myitem, pyferret.FerDSet): mydset = myitem else: raise ValueError('dsets must be a tuple or list of strings and/or FerDSets') if mydset._dsetname.upper() in self._compdsets: raise ValueError('duplicate dataset name ' + mydset._dsetname) print(mydset._dsetname, file=filesfile) self._compdsetnames.append(mydset._dsetname) self._compdsets[mydset._dsetname.upper()] = mydset deletefilesfile = False finally: filesfile.close() if deletefilesfile: os.unlink(filesfilename) filesvarname = aggname + "_datafile_names" cmdstr = 'LET ' + filesvarname + ' = SPAWN("cat \'' + filesfilename + '\'")' (errval, errmsg) = pyferret.run(cmdstr) if errval != pyferret.FERR_OK: os.unlink(filesfilename) raise ValueError(errmsg) # filesfile not read (SPAWN command executed) until filesvarname is needed # Create the DEFINE DATA /AGGREGATE Ferret command, creating # and saving component FerDSets as needed cmdstr = 'DEFINE DATA/AGGREGATE/' + self._along if title: cmdstr += '/TITLE="' + str(title) + '"' if not warn: cmdstr += '/QUIET' if self._comphidden: cmdstr += '/HIDE' cmdstr += ' ' + aggname + ' = ' + filesvarname (errval, errmsg) = pyferret.run(cmdstr) # filesfile now read so can delete it os.unlink(filesfilename) if errval != pyferret.FERR_OK: raise ValueError(errmsg) # create a FerVar for each variable in this dataset namesdict = pyferret.getstrdata('..varnames') for varname in namesdict['data'].flatten(): if sys.version_info[0] > 2: # For Python3.x, namesdict['data'] is a NumPy array of bytes; convert to unicode varname = str(varname, 'UTF-8') # create a FerVar representing this existing Ferret aggregated file variable filevar = pyferret.FerVar() filevar._markasknownvar(varname, self._dsetname, True) # assign this FerVar - uppercase the variable name keys to make case-insensitive self._fervars[varname.upper()] = filevar # keep a original-case version of the name self._fervarnames.add(varname)
def handler_app(environ, start_response): fields = parse_formvars(environ) if environ['REQUEST_METHOD'] == 'GET': try: if fields['SERVICE'] != 'WMS': raise try: FILE = fields['FILE'] except: FILE = None try: COMMAND = fields['COMMAND'] except: COMMAND = None try: VARIABLE = fields['VARIABLE'].replace('%2B', '+') except: VARIABLE = None try: PATTERN = fields['PATTERN'] except: PATTERN = None #--------------------------------------------------------- if fields['REQUEST'] == 'GetVariables': pyferret.run('use ' + FILE) varnamesdict = pyferret.getstrdata('..varnames') variables = varnamesdict['data'].flatten().tolist() #print(json.dumps(variables)) start_response('200 OK', [('content-type', 'application/javascript')]) return iter('newVariables(' + json.dumps(variables) + ')') # return jsonp #--------------------------------------------------------- elif fields['REQUEST'] == 'GetDatasets': tmpname = tempfile.NamedTemporaryFile(suffix='.txt').name tmpname = os.path.basename(tmpname) pyferret.run('set redirect /clobber /file="%s" stdout' % (tmpdir + '/' + tmpname)) pyferret.run('show data') pyferret.run('cancel redirect') if os.path.isfile(tmpdir + '/' + tmpname): ftmp = open(tmpdir + '/' + tmpname, 'rb') txt = ftmp.read() ftmp.close() os.remove(tmpdir + '/' + tmpname) print('GetDatasets: ', os.getpid()) start_response('200 OK', [('content-type', 'text/plain')]) return iter('displayDatasets(' + json.dumps(str(os.getpid()) + '\n\n' + txt) + ')') #--------------------------------------------------------- elif fields['REQUEST'] == 'GetColorBar': pyferret.run('use ' + FILE) tmpname = tempfile.NamedTemporaryFile(suffix='.png').name tmpname = os.path.basename(tmpname) pyferret.run('set window/aspect=1/outline=0') pyferret.run('go margins 2 4 3 3') pyferret.run(COMMAND + '/set_up ' + VARIABLE) pyferret.run( 'ppl shakey 1, 0, 0.15, , 3, 9, 1, `($vp_width)-1`, 1, 1.25 ; ppl shade' ) pyferret.run( 'frame/format=PNG/transparent/xpixels=400/file="' + tmpdir + '/key' + tmpname + '"') im = Image.open(tmpdir + '/key' + tmpname) box = (0, 325, 400, 375) area = im.crop(box) area.save(tmpdir + '/' + tmpname, "PNG") #--------------------------------------------------------- elif fields['REQUEST'] == 'GetMap': pyferret.run('use ' + FILE) tmpname = tempfile.NamedTemporaryFile(suffix='.png').name tmpname = os.path.basename(tmpname) WIDTH = int(fields['WIDTH']) HEIGHT = int(fields['HEIGHT']) # BBOX=xmin,ymin,xmax,ymax BBOX = fields['BBOX'].split(',') HLIM = '/hlim=' + BBOX[0] + ':' + BBOX[2] VLIM = '/vlim=' + BBOX[1] + ':' + BBOX[3] print('GetMap: ', os.getpid()) pyferret.run( 'set window/aspect=1/outline=5' ) # outline=5 is a strange setting but works otherwise get outline around polygons pyferret.run('go margins 0 0 0 0') pyferret.run(COMMAND + '/noaxis/nolab/nokey' + HLIM + VLIM + ' ' + VARIABLE) pyferret.run('frame/format=PNG/transparent/xpixels=' + str(WIDTH) + '/file="' + tmpdir + '/' + tmpname + '"') if os.path.isfile(tmpdir + '/' + tmpname): if PATTERN: img = Image.open(tmpdir + '/' + tmpname) pattern = Image.open(PATTERN) img = Image.composite(img, pattern, pattern) img.save(tmpdir + '/' + tmpname) #--------------------------------------------------------- else: raise if os.path.isfile(tmpdir + '/' + tmpname): ftmp = open(tmpdir + '/' + tmpname, 'rb') img = ftmp.read() ftmp.close() os.remove(tmpdir + '/' + tmpname) start_response( '200 OK', [('content-type', 'image/png')]) # for GetColorBar and GetMap return iter(img) except: return iter('Exception caught')
def ferret_run_code(self, args, code): """ Parameters ---------- args : control arguments for running (py)ferret code : ferret commands to run """ # Temporary directory; create under the current directory # so PDF link files are accessible temp_dir = tempfile.mkdtemp(dir='.', prefix='ipyferret_').replace('\\', '/') # Redirect stdout and stderr to file out_filename = temp_dir + '/output.txt' (errval, errmsg) = pyferret.run('set redirect /clobber /file="%s" stdout' % out_filename) # Filename for saving the final plot (if any) if args.plotname: plot_filename = str(args.plotname) if args.pdf: if not plot_filename.endswith('.pdf'): plot_filename += '.pdf' else: if not plot_filename.endswith('.png'): plot_filename += '.png' elif args.pdf: plot_filename = temp_dir + '/image.pdf' else: plot_filename = temp_dir + '/image.png' # Make it quiet by default (errval, errmsg) = pyferret.run('cancel mode verify') if args.memory: # Reset memory size in megabytes mem_size = float(args.memory) if mem_size > 0.0: (errval, errmsg) = pyferret.run('set memory /size=%f' % (mem_size/8.0)) # Get image size and aspect ratio if args.size: plot_size = args.size.split(',') else: plot_size = _DEFAULT_PLOTSIZE.split(',') plot_width = float(plot_size[0]) plot_height = float(plot_size[1]) plot_aspect = plot_height / plot_width # Set window size with the required aspect ratio; # always anti-alias with windows of these sizes if args.bigger: # Double the canvas size (both width and height) of the standard window # and double the standard line thickness canvas_width = 2.0 * math.sqrt(10.5 * 8.5 / plot_aspect) line_thicken = 2.0 else: # Use a standard-size window with usual line thickness canvas_width = math.sqrt(10.5 * 8.5 / plot_aspect) line_thicken = 1.0 (errval, errmsg) = pyferret.run('set window /xinches=%f /thick=%f /aspect=%f 1' % \ (canvas_width, line_thicken, plot_aspect)) # Run code pyferret_error = False for input in code: # Ignore blank lines if input: input = unicode_to_str(input) (errval, errmsg) = pyferret.run(input) if errval != pyferret.FERR_OK: errmsg = errmsg.replace('\\', '<br />') publish_display_data(_PUBLISH_KEY, {'text/html': '<pre style="background-color:#F79F81; border-radius: 4px 4px 4px 4px; font-size: smaller">' + 'yes? %s\n' % input + '%s' % errmsg + '</pre>' }) pyferret_error = True break # Create the image file; if no final image, no image file will be created. # Any existing image with that filename will be versioned away ('.~n~' appended) if not pyferret_error: if args.pdf: (errval, errmsg) = pyferret.run('frame /xinch=%f /file="%s" /format=PDF' % (plot_width/72.0, plot_filename) ) else: (errval, errmsg) = pyferret.run('frame /xpixel=%f /file="%s" /format=PNG' % (plot_width, plot_filename)) if errval != pyferret.FERR_OK: pyferret_error = True # Close the window (errval, errmsg) = pyferret.run('cancel window 1') # Close the stdout and stderr redirect file (errval, errmsg) = pyferret.run('cancel redirect') #------------------------------- # Publish display_data = [] # Publish captured stdout text, if any if os.path.isfile(out_filename) and (os.path.getsize(out_filename) > 0): try: text_outputs = [] text_outputs.append('<pre style="background-color:#ECF6CE; border-radius: 4px 4px 4px 4px; font-size: smaller">') f = open(out_filename, "r") for line in f: text_outputs.append(line) f.close() text_outputs.append("</pre>") text_output = "".join(text_outputs) display_data.append((_PUBLISH_KEY, {'text/html': text_output})) except: pass # Publish image if present if not pyferret_error: if args.pdf: if os.path.isfile(plot_filename): # Create link to pdf; file visible from cell from files directory text_outputs = [] text_outputs.append('<pre style="background-color:#F2F5A9; border-radius: 4px 4px 4px 4px; font-size: smaller">') text_outputs.append('Message: <a href="files/%s" target="_blank">%s</a> created.' % (plot_filename, plot_filename)) text_outputs.append('</pre>') text_output = "".join(text_outputs) display_data.append((_PUBLISH_KEY, {'text/html': text_output})) # If the user did not provide the PDF filename, # do not delete the temporary directory since the PDF is in there. if args.plotname: rmtree(temp_dir) else: # Delete temporary directory - nothing to preserve rmtree(temp_dir) else: # Display the image in the notebook try: f = open(plot_filename, 'rb') image = f.read().encode('base64') f.close() display_data.append((_PUBLISH_KEY, {'text/html': '<div class="myoutput">' + '<img src="data:image/png;base64,%s"/></div>' % image})) except: pass # Delete temporary directory - PNG encoded in the string rmtree(temp_dir) # Publication for source, data in display_data: publish_display_data(source, data)
def app3z(nc_file='', var_name='tmn', k=1, l=1, outDir=''): # init_ferret import pyferret as pf pf.start(quiet=True, unmapped=True) pf.run('set memory/size=500') pf.run('cancel mode logo') pf.run('cancel mode journal') temp1 = 'use "%s"' % nc_file print(temp1) pf.run(temp1) temp1 = 'show data' print(temp1) pf.run(temp1) #temp1 = 'shade %s[k=%d,l=%d]\ngo land'%(var_name, k, l) temp1 = 'shade %s[l=%d]' % (var_name, l) print(temp1) pf.run(temp1) temp1 = 'go land' print(temp1) pf.run(temp1) t1 = outDir.find('static') outDir1 = outDir[t1:] figFile1 = '%s/plot.png' % outDir1 print(figFile1) figFile0 = '%s/plot.png' % outDir temp1 = 'frame/file="%s"' % figFile0 print(temp1) pf.run(temp1) mess = 'Plot var %s of file:\n%s' % (nc_file, var_name) figFile = 'http://ec2-13-56-153-11.us-west-1.compute.amazonaws.com:5003/%s' % figFile1 return mess, figFile, None
def lineplot(fvar, vs=None, color=None, thick=None, dash=None, title=None, region=None, along=None, over=False, label=True, qual=''): """ Create a line plot of the given value, or the given value versus another value (if vs is given), possibly colored by another value (if color is a FerVar). To create a line plot with symbols, use the pointplot command with the line option set to True. fvar (string or FerVar): Ferret variable to plot vs (string or FerVar): if given, plot the above variable versus this variables color: line color or variable used to determine line color; if None: Ferret default color used, color name (string): name of color to use, color tuple (3 or 4-tupe of [0,100] int values): RGB or RGBA of color to use, FerVar or variable name string: color according to the value of this variable Note: color name strings are limited to (case insensitive) 'black', 'red', 'green', 'blue', 'lightblue', 'purple' other strings are assumed to be variable names thick (float): line thickness scaling factor dash (4-tuple of float): draws the line as a dashed line where the four values are the first drawn stroke length, first undrawn stroke length, second drawn stroke length, second undrawn stroke length of two dashes title (string): title for the plot; if not given, Ferret's default title is used region (FerRegion): space-time region to plot; if None, the full extents of the data will be used along (string; one of 'X','Y','Z','T','E','F', or lowercase): make a set of line plots from two-dimensional data with this axis as the horizontal axis. over (bool): overlay onto an existing plot label (bool): if False, suppress all plot labels qual (string): qualifiers to add to the Ferret PLOT/LINE command """ if not isinstance(qual, str): raise ValueError('qual (Ferret qualifiers) must be a string') if isinstance(fvar, str): plotvar = fvar elif isinstance(fvar, pyferret.FerVar): plotvar = fvar._definition else: raise ValueError('fvar (Ferret variable to plot) must be a string or FerVar') cmdstr = 'PLOT/LINE' if vs is not None: cmdstr += '/VS' plotvar += ',' if isinstance(vs, str): plotvar += vs elif isinstance(vs, pyferret.FerVar): plotvar += vs._definition else: raise ValueError('vs (second Ferret variable to plot) must be a string or FerVar') if color is not None: if isinstance(color, tuple): cmdstr += '/COLOR=' + str(color) elif isinstance(color, pyferret.FerVar): cmdstr += '/RIBBON' plotvar += ',' + color._definition elif isinstance(color, str): if color.upper() in ('BLACK','RED','GREEN','BLUE','LIGHTBLUE','PURPLE'): cmdstr += '/COLOR=' + color else: cmdstr += '/RIBBON' plotvar += ',' + color else: raise ValueError('color must be a tuple, string, or FerVar') if thick is not None: if (not isinstance(thick, numbers.Real)) or (thick <= 0): raise ValueError('thick must be a positive number') cmdstr += '/THICK=' + str(thick) if dash is not None: if (not isinstance(dash, tuple)) or (len(dash) != 4): raise ValueError('dash must be a tuple of four floats'); cmdstr += '/DASH=' + str(dash) if title is not None: if not isinstance(title, str): raise ValueError('title must be a string') cmdstr += '/TITLE="' + title + '"' if along is not None: axisnames = ('X','Y','Z','T','E','F','x','y','z','t','e','f') if not along in axisnames: raise ValueError('along must be one of ' + str(axisnames)) cmdstr += '/ALONG=' + along.upper() if over: cmdstr += '/OVER' if region is not None: if not isinstance(region, pyferret.FerRegion): raise ValueError('region must be a FerRegion') cmdstr += region._ferretqualifierstr(); if not label: cmdstr += '/NOLABEL' if qual: cmdstr += qual cmdstr += ' ' cmdstr += plotvar (errval, errmsg) = pyferret.run(cmdstr) if errval != pyferret.FERR_OK: raise ValueError('Ferret plot command (%s) failed: %s' % (cmdstr, errmsg))
def pointplot(fvar, vs=None, color=None, sym=None, symsize=None, thick=None, line=False, title=None, region=None, over=False, label=True, qual=''): """ Create a point plot of the given value, or the given value versus another value (if vs is given), possibly colored by another value (if color is a FerVar). To create a line plot with symbols, use the pointplot command with the line option set to True. fvar (string or FerVar): Ferret variable to plot vs (string or FerVar): if given, plot the above variable versus this variables color: line color or variable used to determine line color; if None: Ferret default color used, color name (string): name of color to use, color tuple (3 or 4-tupe of [0,100] int values): RGB or RGBA of color to use, FerVar or variable name string: color according to the value of this variable Note: color name strings are limited to (case insensitive) 'black', 'red', 'green', 'blue', 'lightblue', 'purple' other strings are assumed to be variable names sym (int): Ferret symbol number of the symbol to draw for the points. If not given, Ferret selects an appropriate symbol. symsize (float): size of the symbol in inches. If not given, Ferret select an appropriate size. thick (float): line thickness scaling factor when drawing symbols and lines line (bool): if True, draw a line between symbols/points title (string): title for the plot; if not given, Ferret's default title is used region (FerRegion): space-time region to plot; if None, the full extents of the data will be used over (bool): overlay onto an existing plot label (bool): if False, suppress all plot labels qual (string): qualifiers to add to the Ferret PLOT/LINE command """ if not isinstance(qual, str): raise ValueError('qual (Ferret qualifiers) must be a string') if isinstance(fvar, str): plotvar = fvar elif isinstance(fvar, pyferret.FerVar): plotvar = fvar._definition else: raise ValueError('fvar (Ferret variable to plot) must be a string or FerVar') cmdstr = 'PLOT' if vs is not None: cmdstr += '/VS' plotvar += ',' if isinstance(vs, str): plotvar += vs elif isinstance(vs, pyferret.FerVar): plotvar += vs._definition else: raise ValueError('vs (second Ferret variable to plot) must be a string or FerVar') if color is not None: if isinstance(color, tuple): cmdstr += '/COLOR=' + str(color) elif isinstance(color, pyferret.FerVar): cmdstr += '/RIBBON' plotvar += ',' + color._definition elif isinstance(color, str): if color.upper() in ('BLACK','RED','GREEN','BLUE','LIGHTBLUE','PURPLE'): cmdstr += '/COLOR=' + color else: cmdstr += '/RIBBON' plotvar += ',' + color else: raise ValueError('color must be a tuple, string, or FerVar') # always draw the symbols cmdstr += '/SYMBOL' if sym is not None: if (not isinstance(sym, numbers.Integral)) or (sym < 0) or (sym > 88): raise ValueError('sym is not a valid Ferret symbol number') if sym == 0: cmdstr += '=DOT' else: cmdstr += '=' + str(sym) if symsize is not None: if (not isinstance(symsize, numbers.Real)) or (symsize <= 0): raise ValueError('symsize must be a positive number') cmdstr += '/SIZE=' + str(symsize) if thick is not None: if (not isinstance(thick, numbers.Real)) or (thick <= 0): raise ValueError('thick must be a positive number') cmdstr += '/THICK=' + str(thick) if line: cmdstr += '/LINE' if title is not None: if not isinstance(title, str): raise ValueError('title must be a string') cmdstr += '/TITLE="' + title + '"' if over: cmdstr += '/OVER' if region is not None: if not isinstance(region, pyferret.FerRegion): raise ValueError('region, if given, must be a FerRegion') cmdstr += region._ferretqualifierstr(); if not label: cmdstr += '/NOLABEL' if qual: cmdstr += qual cmdstr += ' ' cmdstr += plotvar (errval, errmsg) = pyferret.run(cmdstr) if errval != pyferret.FERR_OK: raise ValueError('Ferret plot command (%s) failed: %s' % (cmdstr, errmsg))
def handler_app(environ, start_response): fields = parse_formvars(environ) if environ['REQUEST_METHOD'] == 'GET': try: if fields['SERVICE'] != 'WMS': raise #FILE = fields['FILE'] COMMAND = fields['COMMAND'] VARIABLE = fields['VARIABLE'].replace('%2B','+') #pyferret.run('use ' + FILE) #pyferret.run('show data') pyferret.run('go ' + envScript) # load the environment (dataset to open + variables definition) try: PATTERN = fields['PATTERN'] except: PATTERN = None tmpname = tempfile.NamedTemporaryFile(suffix='.png').name tmpname = os.path.basename(tmpname) #--------------------------------------------------------- if fields['REQUEST'] == 'GetColorBar': pyferret.run('set window/aspect=1/outline=0') pyferret.run('go margins 2 4 3 3') pyferret.run(COMMAND + '/set_up ' + VARIABLE) pyferret.run('ppl shakey 1, 0, 0.15, , 3, 9, 1, `($vp_width)-1`, 1, 1.25 ; ppl shade') pyferret.run('frame/format=PNG/transparent/xpixels=400/file="' + tmpdir + '/key' + tmpname + '"') im = Image.open(tmpdir + '/key' + tmpname) box = (0, 325, 400, 375) area = im.crop(box) area.save(tmpdir + '/' + tmpname, "PNG") #--------------------------------------------------------- elif fields['REQUEST'] == 'GetMap': WIDTH = int(fields['WIDTH']) HEIGHT = int(fields['HEIGHT']) # BBOX=xmin,ymin,xmax,ymax BBOX = fields['BBOX'].split(',') HLIM = '/hlim=' + BBOX[0] + ':' + BBOX[2] VLIM = '/vlim=' + BBOX[1] + ':' + BBOX[3] pyferret.run('set window/aspect=1/outline=5') # outline=5 is a strange setting but works otherwise get outline around polygons pyferret.run('go margins 0 0 0 0') pyferret.run(COMMAND + '/noaxis/nolab/nokey' + HLIM + VLIM + ' ' + VARIABLE) pyferret.run('frame/format=PNG/transparent/xpixels=' + str(WIDTH) + '/file="' + tmpdir + '/' + tmpname + '"') if os.path.isfile(tmpdir + '/' + tmpname): if PATTERN: img = Image.open(tmpdir + '/' + tmpname) pattern = Image.open(PATTERN) img = Image.composite(img, pattern, pattern) img.save(tmpdir + '/' + tmpname) #--------------------------------------------------------- else: raise if os.path.isfile(tmpdir + '/' + tmpname): ftmp = open(tmpdir + '/' + tmpname, 'rb') img = ftmp.read() ftmp.close() os.remove(tmpdir + '/' + tmpname) start_response('200 OK', [('content-type', 'image/png')]) return iter(img) except: return iter('Exception caught')
def __init__(self, name, dsets, along='T', title='', warn=True, hide=False): ''' Aggregates the given list of datasets along the given axis using the Ferret "DEFINE DATA /AGGREGATE" command. Creates a FerVar for each data variable in common among these datasets, and assigns it as an attribute of this class instance using the variable name. name (string): Ferret name for this aggregated dataset dsets (sequence of strings and/or FerDSets): datasets to aggregate. A string will be interpreted as a filename for creating a FerDSet. along ('T', 'E', 'F'): axis along which to aggregate the datasets title (string): title for the dataset for plots and listing; if not given, the Ferret name for the dataset will be used warn (bool): issue warning messages about variables not in common among all member datasets (either not present or not using the same grid) hide (bool): hide the member datasets in standard Ferret listings such as with pyferret.showdata() ''' # Create an empty dataset with the given Ferret name super(FerAggDSet, self).__init__('', qual=_anonymous_dataset_qualifier) if not isinstance(name, str): raise ValueError( 'Ferret name for the aggregate dataset must be astring') aggname = name.strip() if not aggname: raise ValueError('Ferret name for the aggregate dataset is blank') self._filename = aggname self._dsetname = aggname # Need to keep the given order of component datasets self._compdsetnames = [] # But still use a dictionary with uppercase names for keys self._compdsets = {} # Create the DEFINE DATA /AGGREGATE Ferret command, creating # and saving component FerDSets as needed if along not in ('T', 'E', 'F'): raise ValueError("along must be one of 'T', 'E', or 'F'") self._along = along self._comphidden = bool(hide) cmdstr = 'DEFINE DATA/AGGREGATE/' + self._along if title: cmdstr += '/TITLE="' + str(title) + '"' if not warn: cmdstr += '/QUIET' if self._comphidden: cmdstr += '/HIDE' cmdstr += ' ' + aggname + ' = ' firstone = True if not (isinstance(dsets, tuple) or isinstance(dsets, list)): raise ValueError( 'dsets must be a tuple or list of strings and/or FerDSets') for myitem in dsets: if isinstance(myitem, str): mydset = pyferret.FerDSet(myitem) elif isinstance(myitem, pyferret.FerDSet): mydset = myitem else: raise ValueError( 'dsets must be a tuple or list of strings and/or FerDSets') if mydset._dsetname.upper() in self._compdsets: raise ValueError('duplicate dataset name ' + mydset._dsetname) if not firstone: cmdstr += ', ' else: firstone = False cmdstr += mydset._dsetname self._compdsetnames.append(mydset._dsetname) self._compdsets[mydset._dsetname.upper()] = mydset (errval, errmsg) = pyferret.run(cmdstr) if errval != pyferret.FERR_OK: raise ValueError(errmsg) # create a FerVar for each variable in this dataset namesdict = pyferret.getstrdata('..varnames') for varname in namesdict['data'].flatten(): # create a FerVar representing this existing Ferret aggregated file variable filevar = pyferret.FerVar() filevar._markasknownvar(varname, self._dsetname, True) # assign this FerVar - uppercase the variable name keys to make case-insensitive self._fervars[varname.upper()] = filevar # keep a original-case version of the name self._fervarnames.add(varname)
def app3(nc_file='', var_name=None, k=1, l=1, outDir=''): # checkNc import checkNc2 dict1 = {} dict1['fileName'] = nc_file dict1['source'] = 'online' dict1['message'] = '' ok1 = checkNc2.checkNc(nc_file, dict1, allowOverwrite=0) mes1 = dict1['message'] mes1 += '\n\n' + dict1['check'] print(ok1) print('dict1.key:') for kk in dict1.keys(): print(kk) varList = dict1['varList'] var_name1 = None if var_name is None: for v in varList: d2 = dict1['varDict'][v]['dim2'] if (len(d2) > 1) and (len(d2) < 5): if (d2[-1] == 'lon') and (d2[-2] == 'lat'): var_name1 = v nD = len(d2) else: var_name1 = var_name try: d2 = dict1['varDict'][var_name]['dim2'] nD = len(d2) except: text1 = 'Variable %s does not exist in the file.' % var_name print(text1) mes1 += '\n%s' % text1 if var_name1 is None: mes1 += '\n\n## Cannot figure out which variable to plot.##' # plotting k = int(k) l = int(l) # use_ferret if 1: # init_ferret import pyferret as pf pf.start(quiet=True, unmapped=True) pf.run('set memory/size=1000') pf.run('cancel mode logo') pf.run('cancel mode journal') temp1 = 'use "%s"' % nc_file print(temp1) pf.run(temp1) temp1 = 'show data' print(temp1) pf.run(temp1) if nD == 2: temp1 = 'shade %s' % (var_name1) elif nD == 3: temp1 = 'shade %s[l=%d]' % (var_name1, l) elif nD == 4: temp1 = 'shade %s[k=%d, l=%d]' % (var_name1, k, l) print(temp1) pf.run(temp1) temp1 = 'go land' print(temp1) pf.run(temp1) t1 = outDir.find('static') outDir1 = outDir[t1:] figFile1 = '%s/plot.png' % outDir1 print(figFile1) figFile0 = '%s/plot.png' % outDir temp1 = 'frame/file="%s"' % figFile0 print(temp1) pf.run(temp1) if 0: # use basemap from netCDF4 import Dataset import matplotlib as mpl mpl.use('Agg') # for interactive. Work on svm3 import matplotlib.pylab as Mat from mpl_toolkits.basemap import Basemap mpl.rcParams['image.cmap'] = 'jet' nc = Dataset(nc_file) ncVar = nc.variables[var_name1] dims1 = ncVar.dimensions print(dims1) print(ncVar.shape) if 0: if len(dims1) == 3: data1 = ncVar[k - 1, ::-1, :] elif len(dims1) == 4: data1 = ncVar[k - 1, l - 1, ::-1, :] elif len(dims1) == 2: data1 = ncVar[::-1, :] if 1: if len(dims1) == 3: data1 = ncVar[k - 1, :, :] elif len(dims1) == 4: data1 = ncVar[k - 1, l - 1, :, :] elif len(dims1) == 2: data1 = ncVar[:, :] lon2 = nc.variables[dims1[-1]][:] lat2 = nc.variables[dims1[-2]][:] m = Basemap(lon2[0], lat2[0], lon2[-1], lat2[-1], resolution='c', suppress_ticks=False) #m.pcolor(lon2, lat2, pattern1[i, ::-1, :], vmin=min2, vmax=max2, shading='flat') #data1 = data1[::-1, :] m.pcolor(lon2, lat2, data1) m.drawcoastlines(color=(.7, .7, .7)) m.colorbar() #Mat.title('EOF %d'%(i+1)) figFile0 = '%s/plot.png' % outDir Mat.savefig(figFile0, dpi=100) #figFile = 'http://localhost:5003/%s'%figFile0 #figFile = 'http://ec2-13-56-67-192.us-west-1.compute.amazonaws.com:8080/%s'%figFile0 # for ec20 t1 = outDir.find('static') outDir1 = outDir[t1:] figFile1 = '%s/plot.png' % outDir1 print(figFile1) figFile = 'http://ec2-13-56-153-11.us-west-1.compute.amazonaws.com:5003/%s' % figFile1 return mes1, figFile, None