# -*- pyton-mode -*- # # pysga.py # # Written by Chris Kuklewicz # # This is designed to encapsulate the functions exposed by # Scigraphica to its python terminal. # # Some constants. May need to be moved to a separate file once this becomes # a large list. TRUE=1 FALSE=0 SG_PLOT_2D=0 SG_PLOT_3D=1 SG_PLOT_POLAR=2 GTK_PLOT_AXIS_BOTTOM=0 GTK_PLOT_AXIS_TOP=2 GTK_PLOT_AXIS_RIGHT=3 GTK_PLOT_AXIS_LEFT=1 import sg from sg import * # Scigraphica often considers columns to be objects # Columns even get their own names # There is currently less need for an SGrow object worksheets={} class SGcolumn: """This represents a specific named column of a worksheet in Scigraphica. """ def __init__(self,sheetName,columnName): self.name=sheetName self.col=columnName def get_values(self): "Calls col. Returns an array of the values in this column (doubles)." return col(self.col,self.name) def set_all(self,theValues): """Calls set_column to set all the values at once. Takes an object that can be a value, sequence, or array. """ return set_column(self.col,theValues,self.name) def value(self,aRow): "Calls get_cell_value, Takes a row (int) and returns a double." return get_cell_value(self.name,self.col,aRow) def set_value(self,aRow,theValue): "Calls set_cell_value, Takes a row (int) and value (double)." return set_cell_value(self.name,self.col,aRow,theValue) def text(self,aRow): "Calls get_cell_text. Takes a row (int) and returns a string." return get_cell_text(self.name,self.col,aRow) def set_text(self,aRow,theText): "Calls set_cell_text. Takes a row (int) and text (string)." return set_cell_text(self.name,self.col,aRow,theText) def set_name(self,newName): """Calls set_column_name. Takes the new name (string). This SGcolumn object will be updated to still point at same column. """ self.col=newName return set_column_name(self.name,self.col,newName) def set_expression(self,newExp,fromRow,toRow): """Calls set_column_values. Takes an expression to evaluate, and optional start and stop row numbers (int >=1). The expression can return a value, sequence, or array. """ return set_column_values(self.name,self.col,newExp,fromRow,toRow) def get_expression(self): """Returns the expression for this column, None if not set.""" return get_column_exp(self.col,self.name) def get_precision(self): """Returns the display precision for this column.""" return get_column_precision(self.col,self.name) def set_type(self,newType): """Calls set_column_type. Takes the type as an integer. Type is 0=SG_TYPE_NUMBER 1=SG_TYPE_TEXT 2=SG_TYPE_DATE 3=SG_TYPE_TIME """ return set_column_type(self.name,self.col,newType) def set_numbers(self,internal,format,precision): "Calls set_column_numbers. Takes 3 integer arguments: internal, format, precision." return set_column_numbers(self.name,self.col,internal,format,precision) def column_names(self): "Returns a list of column names in this worksheet." return column_names(self.name) # All worksheets get a name class SGworksheet: """This represents a specific named worksheet in Scigraphica. Upon creation it will call new_worksheet. All data is being stored in Scigraphica. """ def __init__(self,sheetName): "Call new_worksheet - returns a new object if a sheet with that "\ "name alrady exists, but does not create a new sheet in that case." # GOTCHA : should use a way to test if sheet already exists self.name=sheetName new_worksheet(self.name) def column(self,columnName): "Return a SGcolumn object that refers to the named column." return SGcolumn(self.name,columnName) def remove(self): "Call remove_worksheet - kind of a destructor." return remove_workseet(self.name) def rename(self,newName): "Call rename_worksheet." self.name=newName return rename_worksheet(self.name,newName) def cell(self,aRow,aColumn): "Calls cell to get the value. aRow and/or aColumn can be names." return cell(aRow,aColumn,self.name) def col(self,aColumn): "Calls col to get the values. aColumn can be a name." return col(aColumn,self.name) def row(self,aRow): "Callc row to get the values. aRow can be a name." return row(aRow,self.name) def setcell(self,aRow,aColumn,anObject): "Calls setcell. aRow and/or aColumn can be names." return setcell(aRow,aColumn,anObject,self.name) def setcol(self,aColumn,anObject): "Calls setcol. aColumn can be a name." return setcol(aColumn,anObject,self.name) def clearcol(self,aColumn): "Calls clear_column. aColumn can be a name." return clear_column(aColumn,self.name) def setrow(self,aRow,anObject): "Calls setrow. aRow can be a name." return setrow(aRow,anObject,self.name) def update(self): "Recalculates formulas" return update_worksheet(self.name) def setarray(self,anArray,aRow=0,aColumn=0): "Set sheet from 2D Numeric array."\ "This is equivalent to setcell(0,0,anArray,sheetname)." return setcell(aRow,aColumn,anArray,self.name) def row0(self): "Gets the index of the first row selected." return get_selection(self.name)['row0'] def rowi(self): "Gets the index of the last row selected." return get_selection(self.name)['rowi'] def col0(self): "Gets the index of the first column selected." return get_selection(self.name)['col0'] def coli(self): "Gets the index of the last column selected." return get_selection(self.name)['coli'] def selection(self): "Returns a list of indices denoting the reactangle of the sheet's"\ "selection area: [row0,col0,rowi,coli]" temp=get_selection(self.name) return [temp["row0"],temp["col0"],temp["rowi"],temp["coli"]] def add_columns(self,num): sg.add_columns(num,self.name) # TODO: Things that would be good to add in the future # def array(self): "Get sheet as 2D Numeric array" # An axis can be x, y, or z. Number those as 1, 2, and 3 class SGaxis: """Pass 1, 2, or 3 to init for x, y, or z axis. Note that only 3D Plot layers have a z axis. """ def __init__(self,plotName,layerIndex,xyz): self.name=plotName self.index=layerIndex self.axis=xyz def set_range(self,newMin,newMax): "Takes newMin (double) and newMax (double)" if (1==self.axis): return set_xrange(self.name,self.index,newMin,newMax) elif (2==self.axis): return set_yrange(self.name,self.index,newMin,newMax) elif (3==self.axis): return set_zrange(self.name,self.index,newMin,newMax) def set_ticks(self,newMajor,newMinor): "Takes newMajor (double) and newMinor (int)" if (1==self.axis): return set_xticks(self.name,self.index,newMajor,newMinor) elif (2==self.axis): return set_yticks(self.name,self.index,newMajor,newMinor) elif (3==self.axis): return set_zticks(self.name,self.index,newMajor,newMinor) def set_title(self,newTitle): "Takes the newTitle (string)" if (1==self.axis): set_axis_text_properties(self.name,self.index,GTK_PLOT_AXIS_TOP,title=newTitle) set_axis_text_properties(self.name,self.index,GTK_PLOT_AXIS_BOTTOM,title=newTitle) elif (2==self.axis): set_axis_text_properties(self.name,self.index,GTK_PLOT_AXIS_LEFT,title=newTitle) set_axis_text_properties(self.name,self.index,GTK_PLOT_AXIS_RIGHT,title=newTitle) elif (3==self.axis): return set_ztitle(self.name,self.index,newTitle) def show_titles(self,first=TRUE,second=TRUE): "Takes the newTitle (string)" print "layer index=",self.index if (1==self.axis): set_axis_text_properties(self.name,self.index,GTK_PLOT_AXIS_BOTTOM,show_title=first) set_axis_text_properties(self.name,self.index,GTK_PLOT_AXIS_TOP,show_title=second) elif (2==self.axis): set_axis_text_properties(self.name,self.index,GTK_PLOT_AXIS_LEFT,show_title=first) set_axis_text_properties(self.name,self.index,GTK_PLOT_AXIS_RIGHT,show_title=second) def show_labels(self,first=TRUE,second=TRUE): "Takes the newTitle (string)" if (1==self.axis): set_axis_text_properties(self.name,self.index,GTK_PLOT_AXIS_BOTTOM,show_labels=first) set_axis_text_properties(self.name,self.index,GTK_PLOT_AXIS_TOP,show_labels=second) elif (2==self.axis): set_axis_text_properties(self.name,self.index,GTK_PLOT_AXIS_LEFT,show_labels=first) set_axis_text_properties(self.name,self.index,GTK_PLOT_AXIS_RIGHT,show_labels=second) def label_digits(self,first=TRUE,second=TRUE): "Takes the newTitle (string)" if (1==self.axis): set_axis_text_properties(self.name,self.index,GTK_PLOT_AXIS_BOTTOM,label_prec=first) set_axis_text_properties(self.name,self.index,GTK_PLOT_AXIS_TOP,label_prec=second) elif (2==self.axis): set_axis_text_properties(self.name,self.index,GTK_PLOT_AXIS_LEFT,label_prec=first) set_axis_text_properties(self.name,self.index,GTK_PLOT_AXIS_RIGHT,label_prec=second) def label_style(self,first=TRUE,second=TRUE): "Takes the newTitle (string)" if (1==self.axis): set_axis_text_properties(self.name,self.index,GTK_PLOT_AXIS_BOTTOM,label_style=first) set_axis_text_properties(self.name,self.index,GTK_PLOT_AXIS_TOP,label_style=second) elif (2==self.axis): set_axis_text_properties(self.name,self.index,GTK_PLOT_AXIS_LEFT,label_style=first) set_axis_text_properties(self.name,self.index,GTK_PLOT_AXIS_RIGHT,label_style=second) def label_pos(self,offset=0.,justify_axis=0.5,angle=-999,justify=2): "Takes the newTitle (string)" if (1==self.axis): if angle==-999: angle=0. set_axis_label_pos(self.name,self.index,GTK_PLOT_AXIS_BOTTOM,offset,justify_axis,angle,justify) set_axis_label_pos(self.name,self.index,GTK_PLOT_AXIS_TOP,offset,justify_axis,angle,justify) elif (2==self.axis): if angle==-999: angle=90. set_axis_label_pos(self.name,self.index,GTK_PLOT_AXIS_LEFT,offset,justify_axis,angle,justify) set_axis_label_pos(self.name,self.index,GTK_PLOT_AXIS_RIGHT,offset,justify_axis,angle,justify) def show_grid(self): if (1==self.axis): return show_xgrids(self.name,self.index) elif (2==self.axis): return show_ygrids(self.name,self.index) elif (3==self.axis): return show_zgrids(self.name,self.index) def hide_grid(self): if (1==self.axis): return hide_xgrids(self.name,self.index) elif (2==self.axis): return hide_ygrids(self.name,self.index) elif (3==self.axis): return hide_zgrids(self.name,self.index) # TODO: add way to enable autoscaling an axis # Layers in a Plot have numbers instead of names. # This seems somehow inconsistant with the column / sheet scheme. class SGlayer: def __init__(self,plotName,layerIndex): self.name=plotName self.index=layerIndex def remove(self): "Erase this layer and its contents" return remove_layer(self.name,self.index) def clear(self): "Erase the plot contents of this layer" return clear_layer(self.name,self.index) def move(self,newX,newY): "Takes the new absolute X (double) and Y (double)" return move_layer(self.name,self.index,newX,newY) def resize(self,newW,newH): "Takes the new absolute width (double) and height (double)" return resize_layer(self.name,self.index,newW,newH) def show_legend(self): "Display the legend box for this layer" return show_legends(self.name,self.index) def hide_legend(self): "Hide the legend box for this layer" return hide_legends(self.name,self.index) def move_legend(self,newX,newY): "Takes the new absolute X (double) and Y (double)" return move_legends(self.name,self.index,newX,newY) def axis(self,xyz): "Takes 1 or 2 or 3 to get the x or y or z axis." return SGaxis(self.name,self.index,xyz) def xaxis(self): "Return an object that represents the xaxis of this layer" return SGaxis(self.name,self.index,1) def yaxis(self): "Return an object that represents the yaxis of this layer" return SGaxis(self.name,self.index,2) def zaxis(self): "Return an object that represents the zaxis of this layer" return SGaxis(self.name,self.index,3) def plot_expression(self,newExp): "Takes an expression of 'x' to plot (string)" return plot_exp(self.name,self.index,newExp) def plot_python(self): "XXX Not yet implimented" pass def plot_columns(self): "XXX Not yet implimented" pass def plot_expression_xy(self,expX,expY): "Takes expressions for 'x' and 'y' to plot in this layer" return plot_exp_xy(self.name,self.index,expX,expY) def plot_expression_xy_bars(self,expX,expY,width): "Takes expressions for 'x' and 'y' to plot in this layer as vertical" "bars" return plot_exp_xy_bars(self.name,self.index,expX,expY,width) def set_symbol(self,symbolNumber): "Set default symbol, by number, for plotting in this layer" return set_symbol(self.name,self.index,symbolNumber) def set_symbol_style(self,symbolStyle): "Set default symbol style, by number, for plotting in this layer" return set_symbol_style(self.name,self.index,symbolStyle) def set_symbol_color(self,symbolColor): "Set default symbol color, for plotting in this layer" return set_symbol_color(self.name,self.index,symbolColor) def set_line_style(self,lineStyle): "Set default line style, by number, for plotting in this layer" return set_line_style(self.name,self.index,lineStyle) def set_line_color(self,lineColor): "Set default line color, for plotting in this layer" return set_line_color(self.name,self.index,lineColor) def set_connector(self,plotConnector): "Set default connector for plotting in this layer" return set_connector(self.name,self.index,plotConnector) def is_active(self): "Returns TRUE if this layer is the active layer, FALSE if not" if plot_active_layer(self.name)==self.index: return TRUE else: return FALSE def datasets(self): "Returns a list of datasets in this layer" return plot_layer_datasets(self.name,self.index) def refresh(self): "Redraws the layers in this plot" return plot_layer_refresh(self.name,self.index) def autoscale(self): "Autoscales this layer" return plot_layer_autoscale(self.name,self.index) # Plots all have a unique name class SGplot: def __init__(self,layerType=0,plotName=None): "layerType 0 is SG_PLOT_2D, 1 is SG_PLOT_3D, 2 is SG_PLOT_POLAR.\n" if plotName==None: self.name=sg.active_plot() else: self.name=plotName sg.new_plot(layerType,self.name) def remove(self): return remove_plot(self.name) def clear(self): return clear_plot(self.name) def rename(self,newName): "Takes the new name (string). This object will still refer the same plot" self.name=newName return rename_plot(self.name,newName) def new_layer(self,layerType): # TODO: This should return an index to the new layer or an SGlayer "Takes a layer type (integer), where 0 is SG_PLOT_2D, 1 is SG_PLOT_3D, 2 is SG_PLOT_POLAR.\n" return new_layer(self.name,layerType) def layer(self,layerIndex): "Returns an object which refers to a particular layer number" return SGlayer(self.name,layerIndex) def layers(self): "Returns the number of layers in the plot" return plot_layers(self.name) def active_layer(self): "Returns the number of the active layer in the plot" return plot_active_layer(self.name) def refresh_canvas(self): "Redraws the current canvas" return plot_refresh_canvas(self.name) def freeze(self): "Suspends visual updates to the plot" return plot_freeze_canvas(self.name) def thaw(self): "Resumes visual updates to the plot" return plot_thaw_canvas(self.name) # Configuration object class SGconfig: "A configuration object, determined by an object and a group name.\n" "Create a new object using the object and group names, as well as two\n" "callable objects:\n" "def : to set the default value.\n" "commit: to register any side-effects required by a change in the configuration\n" " object value.\n" def __init__(self,name,group,default,commit): self.name=name self.group=group config_register(name,group,default,commit) def value(self): "Returns the configuration object value" return config_get_value(self.name,self.group) def set(self,value,overwrite=TRUE): "Sets the value of the configuration object. Takes the value as an argument." config_set_value(self.name,self.group,value,overwrite) def set_default(self): "Calls the function that sets the default value" config_exec_default(self.name,self.group) def commit(self): "Calls the function that activates any side-effects the configuration object" "might have." config_exec_commit(self.name,self.group) def set_commit(self,value): "Sets the object value, and calls the function that activates any side-effects\n" "the configuration object might have." config_set_value(self.name,self.group,value) config_exec_commit(self.name,self.group) # Simple example. Plotting expressions: # from pysga import * # k=SGplot(0,'K-Plot') # l=k.layer(1) # l.plot_expression('x*(x-10.0)') # l.xaxis().set_range(0,10) # l.xaxis().set_ticks(1,0) # l.yaxis().set_range(0,30) # l.yaxis().set_ticks(6,1) # Another example. Plotting columns: # from pysga import * # w=SGworksheet('W1') # w.setcol('A',range(0,10)) # w.setcol('B',w.col('A')**2) # p=SGplot(0,'Columns') # l=p.layer(1) # l.set_symbol_style(1) # l.set_symbol_color("blue") # l.set_line_style(1) # l.set_line_color("red") # l.plot_expression_xy("col('A','W1')","col('B','W1')")