# -*- pyton-mode -*-
#
# pysga.py
#
# Written by Chris Kuklewicz <chrisk@mit.edu>
#
# 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')")
syntax highlighted by Code2HTML, v. 0.9.1