def __init__(self): """ Initialisation """ debugMsg("Called Renderer.__init__()") BaseRenderer.__init__(self) # initialisation of base class # initialise some attributes self.renderWindowWidth = 640 self.renderWindowHeight = 480 self.name = _rendererName # the namespace to run the exec code self.renderDict = {} # initialise the evalstack self._evalStack = "" # keep the initial setup of the module for later reuse self._initStack = "" # initialise the renderer module self.addToInitStack("# Renderer.__init__()") self.addToInitStack("import plplot") # we now need the Numeric package so can handle arrays better self.addToInitStack("from Numeric import *")
def render(self): """ Does JpegImage object specific (pre)rendering stuff """ debugMsg("Called JpegImage.render()") return
def __init__(self, scene): """ Initialisation of LinePlot class @param scene: The scene with which to associate the plot @type scene: Scene object """ debugMsg("Called LinePlot.__init__()") Plot.__init__(self, scene) # initialisation of base class self.renderer = scene.renderer self.title = None self.xlabel = None self.ylabel = None self.zlabel = None self.linestyle = None # pyvisi-defined linestyle self._linestyle = None # renderer-specific linestyle # is the LinePlot data offset (vertically) from each other? self.offset = False # now add the object to the scene scene.add(self)
def render(self): """ Does ContourPlot object specific rendering stuff """ debugMsg("Called ContourPlot.render()") self.renderer.runString("# ContourPlot.render()") self.renderer.runString("_gnuplot('set contour base')") self.renderer.runString("_gnuplot('set view 0, 0, 1, 1')") self.renderer.runString("_gnuplot('set nosurface')") # gnuplot 3.7 # if a title is set, put it here if self.title is not None: evalString = "_gnuplot.title(\'%s\')" % self.title self.renderer.runString(evalString) # if an xlabel is set, add it if self.xlabel is not None: evalString = "_gnuplot.xlabel(\'%s\')" % self.xlabel self.renderer.runString(evalString) # if a ylabel is set, add it if self.ylabel is not None: evalString = "_gnuplot.ylabel(\'%s\')" % self.ylabel self.renderer.runString(evalString) self.renderer.runString("_gnuplot('set pm3d')") # set up the evalString to use for plotting evalString = "_gnuplot.splot(_data)" self.renderer.runString(evalString) return
def getLineStyle(self): """ Gets the current linestyle of the LinePlot @return: the linestyle as a string """ debugMsg("Called LinePlot.getLineStyle()") return self.linestyle
def __init__(self): """ The init function """ debugMsg("Called Scene.__init__()") BaseScene.__init__(self) self.renderer = Renderer() self.objectList = []
def load(self, fname): """ Loads image data from file. @param fname: The filename from which to load image data @type fname: string """ debugMsg("Called Image.load()") fileCheck(fname) return
def setTitle(self, title): """ Set the plot title @param title: the string holding the title to the plot @type title: string """ debugMsg("Called Plot.setTitle()") self.title = title return
def __init__(self, scene=None): """ Initialises the Image class object @param scene: The Scene object to add to @type scene: Scene object """ debugMsg("Called Image.__init__()") Item.__init__(self) if scene is not None: self.renderer = scene.renderer
def setYLabel(self, label): """ Set the label of the y-axis @param label: the string holding the label of the y-axis @type label: string """ debugMsg("Called Plot.setYLabel()") self.ylabel = label return
def save(self, fname, format): """ Save the scene to a file Possible formats are: - Jpeg - Postscript - PNG - PBM @param fname: Name of output file @type fname: string @param format: Graphics format of output file @type format: Image object """ debugMsg("Called Scene.save()") self.renderer.runString("# Scene.save()") # if the format is passed in as a string or object, react # appropriately import types if type(format) is types.StringType: fmt = format.lower() else: fmt = format.format # set the output format if fmt == "ps": self.renderer.runString(\ "plplot.plsdev(\"psc\")") elif fmt == "png": self.renderer.runString(\ "plplot.plsdev(\"png\")") elif fmt == "pbm": self.renderer.runString(\ "plplot.plsdev(\"pbm\")") elif fmt == "jpeg" or fmt == "jpg": self.renderer.runString(\ "plplot.plsdev(\"jpeg\")") else: raise ValueError, "Unknown graphics format. I got: %s" % \ fmt # set the output filename evalString = "plplot.plsfnam(\"%s\")" % fname self.renderer.runString(evalString) # now render the whole shebang (again) self.render(save=True) return
def place(self, obj): """ Place an object within a scene @param obj: The object to place within the scene @type obj: object """ debugMsg("Called Scene.place()") if obj is None: raise ValueError, "You must specify an object to add" return
def setLineStyle(self, linestyle): """ Sets the linestyle of the LinePlot Linestyles may be either a word in the Gnuplot style, or a symbol shortcut in the Matlab style. Some of the options do not have a Matlab equivalent but do have a Gnuplot equivalent, or vice versa. What this method does, is take the linestyles possible as defined by PyVisi, and then does some conversion as best it can to get the relevant output from (in this case) plplot. Possible linestyles are: 1. lines ('-') 2. points ('o') 3. linespoints ('-o') 4. dots ('.') 5. dotted (':') 6. dashes ('--') 7. dotdashes ('-.') @param linestyle: the style to use for the lines @type linestyle: string """ debugMsg("Called LinePlot.setLineStyle()") # now implement the gnuplot-specific way to do this if linestyle == 'lines' or linestyle == '-': self._linestyle = 'lines' elif linestyle == 'points' or linestyle == 'o': self._linestyle = 'points' elif linestyle == 'linespoints' or linestyle == '-o': self._linestyle = 'linespoints' elif linestyle == 'dots' or linestyle == '.': self._linestyle = 'dots' elif linestyle == 'dotted' or linestyle == ':': print "linestyle = %s" % linestyle raise NotImplementedError, \ "Sorry, haven't implemented this style yet." elif linestyle == 'dashes' or linestyle == '--': print "linestyle = %s" % linestyle raise NotImplementedError, \ "Sorry, haven't implemented this style yet." elif linestyle == 'dotdashes' or linestyle == '-.': print "linestyle = %s" % linestyle raise NotImplementedError, \ "Sorry, haven't implemented this style yet." else: raise ValueError, "Unknown linestyle! I got \'%s\'" % linestyle return
def __init__(self, scene=None): """ Initialises the PdfImage class object This object is B{only} used for generating pdf output @param scene: The Scene object to add to @type scene: Scene object """ debugMsg("Called PdfImage.__init__()") Image.__init__(self) if scene is not None: self.renderer = scene.renderer self.format = "pdf"
def setData(self, *dataList, **options): """ Set data to Plot @param dataList: the data to set to the plot @type dataList: tuple @param options: dictionary of extra options @type options: dict """ debugMsg("Called Plot.setData()") if dataList is None: raise ValueError, "You must specify a data list" return
def add(self, obj): """ Add a new item to the scene @param obj: The object to add to the scene @type obj: object """ debugMsg("Called Scene.add()") # make sure there is an object passed in if obj is None: raise ValueError, "You must specify an object to add" self.renderer.runString("# Scene.add()") self.objectList.append(obj) return
def load(self, fname): """ Loads jpeg image data from file. NOT supported by this renderer module @param fname: The filename from which to load jpeg image data @type fname: string """ debugMsg("Called JpegImage.load()") fileCheck(fname) # this ability not handled by this renderer module unsupportedError() return
def __init__(self, scene): """ Initialisation of abstract plot class @param scene: The scene with which to associate the plot @type scene: Scene object """ debugMsg("Called Plot.__init__()") Item.__init__(self) # initialisation of base class self.title = None self.xlabel = None self.ylabel = None self.zlabel = None if scene is None: raise ValueError, "You must specify a scene object"
def render(self): """ Does LinePlot object specific rendering stuff """ debugMsg("Called LinePlot.render()") self.renderer.runString("# LinePlot.render()") # initialise plplot self.renderer.runString("plplot.plinit()") # set up the viewport for plotting evalString = "plplot.plenv(_xMin,_xMax,_yMin,_yMax, 0, 1)" self.renderer.runString(evalString) # set up the evalString to use for plotting for i in range(self.renderer.numDataObjects): evalString = "plplot.plline(_x, _y%d)" % i self.renderer.runString(evalString) # if a title is not set, set it to a null string # (this will help keep plplot happy) if self.title is None: self.title = "" # if an xlabel is not set, set it to a null string if self.xlabel is None: self.xlabel = "" # if a ylabel is not set, set it to a null string if self.ylabel is None: self.ylabel = "" # put the labels (if any) on the graph. evalString = "plplot.pllab(\"%s\", \"%s\", \"%s\")" % \ (self.xlabel, self.ylabel, self.title) self.renderer.runString(evalString) # finish stuff off self.renderer.runString("plplot.plend()") return
def __init__(self, scene): """ Initialisation of the ContourPlot class @param scene: The scene with which to associate the plot @type scene: Scene object """ debugMsg("Called ContourPlot.__init__()") Plot.__init__(self) # initialisation of base class self.renderer = scene.renderer self.title = None self.xlabel = None self.ylabel = None self.zlabel = None self.linestyle = None # pyvisi-defined linestyle self._linestyle = None # renderer-specific linestyle # now add the object to the scene scene.add(self)
def setLabel(self, axis, label): """ Set the label of a given axis @param axis: string (Axis object maybe??) of the axis (e.g. x, y, z) @param label: string of the label to set for the axis @type label: string """ debugMsg("Called Plot.setLabel()") # string-wise implementation (really budget implementation too) if axis == 'x' or axis == 'X': self.xlabel = label elif axis == 'y' or axis == 'Y': self.ylabel = label elif axis == 'z' or axis == 'Z': self.zlabel = label else: raise ValueError, "axis must be x or y or z" return
def setBackgroundColor(self, *color): """ Sets the background color of the Scene @param color: The color to set the background to. Can be RGB or CMYK @type color: tuple """ debugMsg("Called Scene.setBackgroundColor()") # pity this code doesn't work.... # need to check on the values given in the *color array. # if they're greater than 1, scale so that the largest is 1 #maxColor = None #for i in range(len(color)): #if color[i] > 1: #maxColor = color[i] #print maxColor # ## if a maximum colour is found, then scale the colours #if maxColor is not None: #for i in range(len(color)): #color[i] = color[i]/maxColor # if color is of length 3, then we have rgb # if length is 4 then cmyk # if length is 1 then greyscale # otherwise barf if len(color) == 3: # ok, using rgb # probably should use a Color object or something # this will do in the meantime pass else: raise ValueError, "Sorry, only RGB color is supported at present" return
def __init__(self): """ Initialisation of the text object """ debugMsg("Called Text.__init__()") Item.__init__(self) # initialisation of base class
def getBackgroundColor(self): """ Gets the current background color setting of the Scene """ debugMsg("Called Scene.getBackgroundColor()") return
def __init__(self): """ Initialisation """ debugMsg("Called Item.__init__()") BaseItem.__init__(self)
def __init__(self): """ Initialisation of the plane object """ debugMsg("Called Plane.__init__()") Item.__init__(self) # initialisation of base class
def setData(self, *dataList, **options): """ Sets the data to the given plot object. @param dataList: list of data objects to plot @type dataList: tuple @param options: keyword options @type options: dict """ debugMsg("Called setData() in LinePlot()") self.renderer.runString("# LinePlot.setData()") # grab the options if any if options.has_key('offset'): self.offset = options['offset'] else: self.offset = False # do some sanity checking on the data for i in range(len(dataList)): if len(dataList[0]) != len(dataList[i]): raise ValueError, "Input vectors must all be the same length" # this is a really dodgy way to get the data into the renderer # I really have to find a better, more elegant way to do this # if have more than one array to plot, the first one is the x data if len(dataList) > 1: xData = dataList[0] ## pass around the x data self.renderer.renderDict['_x'] = copy.deepcopy(xData) # don't need the first element of the dataList, so get rid of it dataList = dataList[1:] # if only have one array input, then autogenerate xData elif len(dataList) == 1: xData = range(1, len(dataList[0])+1) if len(xData) != len(dataList[0]): errorString = "Autogenerated xData array length not " errorString += "equal to input array length" raise ValueError, errorString ## pass around the x data self.renderer.renderDict['_x'] = copy.deepcopy(xData) # range over the data, printing what the expansion of the array is # and regenerate the data within the eval for i in range(len(dataList)): yDataVar = "_y%d" % i data = dataList[i] # check that the data here is a 1-D array if len(data.shape) != 1: raise ValueError, "Can only handle 1D arrays at present" self.renderer.renderDict[yDataVar] = copy.deepcopy(data) # if offset is true, then shift the data up accordingly if self.offset: # concatenate the data evalString = "_yAll = concatenate([" for i in range(len(dataList)-1): evalString += "_y%d," % i evalString += "_y%d])" % int(len(dataList)-1) self.renderer.runString(evalString) # find its min and max self.renderer.runString("_yMin = min(_yAll)") self.renderer.runString("_yMax = max(_yAll)") # keep the data apart a bit with a constant self.renderer.runString("_const = 0.1*(_yMax - _yMin)") # shift the data up self.renderer.runString("_shift = _yMax - _yMin + _const") for i in range(len(dataList)): evalString = "_y%d = _y%d + %d*_shift" % (i, i, i) self.renderer.runString(evalString) # determine the min and max of the x and y data evalString = "_xMin = min(_x)\n" evalString += "_xMax = max(_x)" self.renderer.runString(evalString) if self.offset: ### don't need to recalculate _yMin and _yMax # but do need to take into account the shift evalString = "_yMax = _yMax + %d*_shift" % len(dataList) self.renderer.runString(evalString) pass else: ### but if not offset, do have to # concatenate the data evalString = "_yAll = concatenate([" for i in range(len(dataList)-1): evalString += "_y%d," % i evalString += "_y%d])" % int(len(dataList)-1) self.renderer.runString(evalString) # calculate the min and max evalString = "_yMin = min(_yAll)\n" evalString += "_yMax = max(_yAll)" self.renderer.runString(evalString) # return the number of data objects to plot self.renderer.numDataObjects = len(dataList) return
def render(self, pause=False, interactive=False, save=False): """ Render (or re-render) the scene Render the scene, either to screen, or to a buffer waiting for a save @param pause: Flag to wait at end of script evaluation for user input @type pause: boolean @param interactive: Whether or not to have interactive use of the output (not available in all renderer modules) @type interactive: boolean """ debugMsg("Called Scene.render()") renderer = self.renderer # plplot doesn't support interactive stuff (I think) if interactive: print "PLPlot does not support scene interaction" print "Setting interactive to false" interactive = False renderer.runString("# Scene.render()") if not save: # so that renderering goes to the window by default renderer.runString("plplot.plsdev(\"xwin\")") # get object added to the scene to render itself for obj in self.objectList: obj.render() # add some code to pause after rendering if asked to if pause: renderer.runString("raw_input(\"Press enter to continue\")") # prepend the init stack to the eval stack self.renderer._evalStack = self.renderer._initStack + \ self.renderer._evalStack # optionally print out the evaluation stack to make sure we're doing # the right thing debugMsg("Here is the evaluation stack") debugMsg(60*"#") debugMsg(renderer.getEvalStack()) debugMsg(60*"#") # execute the eval stack evalStack = renderer.getEvalStack() exec evalStack in self.renderer.renderDict # flush the evaluation stack debugMsg("Flusing evaluation stack") renderer.resetEvalStack() return
def __init__(self): """ Initialisation of the camera object """ debugMsg("Called Camera.__init__()") Item.__init__(self) # initialisation of base class
def __init__(self): """ Initialises the axes object """ debugMsg("Called Axes.__init__()") Plot.__init__(self) # initialisation of base class