• Main Page
  • Namespaces
  • Classes
  • Files
  • File List

/home/mark/model/software/ScrumPy/ScrumPy/Data/Plotter.py

00001 import os, sys, types
00002 
00003 from Util import Kali
00004 
00005 def EnQuote(s):
00006     return s.join(("'", "'"))
00007 
00008 def EnDQuote(s):
00009     return s.join(('"', '"'))
00010 
00011 try:
00012    from wxGUI.Plotter import Plotter as wxPlotter
00013 except:
00014     wxPlotter = Kali.Kali
00015 
00016 
00017 
00018 class Data:
00019     """ base class to hold data sent to a plotter """
00020 
00021     def __init__(self, data,  options={}):
00022         """ pre: data is list of equal length lists of ints or floats """
00023 
00024         self.Options = dict(options)
00025         self.ValidOptions = {}
00026         self.UpdateData(data)
00027 
00028     def UpdateData(self, data):
00029         self.data = data
00030 
00031 
00032     def CheckOption(self,  key, val=None):
00033 
00034         rv = len(self.ValidOptions) ==0 # ie we have set some valid
00035         if self.ValidOptions.has_key(key):
00036             if val in self.ValidOptions[key] or val == None:  # val == None => only check key
00037                 rv =True
00038             else:
00039                 print "Invalid value", str(val),  "for option",  key
00040         else:
00041             print "no such option -",  key
00042 
00043         return rv
00044 
00045 
00046     def SetOption(self, key, val):
00047 
00048         #if self.CheckOption(key, val):
00049         self.Options[key] = val
00050 
00051 
00052     def GetOptions(self):
00053         pass
00054 
00055     def GetData(self):
00056         pass
00057 
00058 
00059 class PlotterBase(dict):
00060 
00061     pass
00062 
00063 
00064 
00065 class wxData: #(Data):
00066 
00067     DefaultOpts = {
00068           "Style":"line",      # or "marker"
00069           "Substyle":"SOLID",
00070           "colour" : "BLACK",
00071           "width"  :2,
00072           "marker"  :"circle",    # only for style marker
00073           "Title"    : ""
00074        }
00075 
00076 
00077     def __init__(self,  data):
00078 
00079         if len(data)==1:
00080             self.y = data[0]
00081             self.x = range(len(self.y))
00082         else:
00083             self.x = data[0]
00084             self.y = data[1]
00085 
00086         self.Options = wxData.DefaultOpts
00087 
00088 
00089 
00090     def GetData(self):
00091         return self.x, self.y
00092 
00093 
00094     def GetOptions(self):
00095         return self.Options
00096 
00097 
00098 
00099 class wxPlotter(wxPlotter):
00100 
00101     def AddData(self, name, data):
00102 
00103         opts = dict(data.Options)
00104         style = opts["Style"]
00105         opts["style"] = opts["Substyle"]
00106         opts["Name"] = opts["Title"]
00107         del opts["Substyle"],  opts["Style"],  opts["Title"]
00108         if opts["Name"] == "":
00109             opts["Name"] = name
00110 
00111         if style == "line":
00112             if opts.has_key("marker"):
00113                 del opts["marker"]
00114             self.AddLinePlotItem(data.x, data.y,  **opts)
00115         else:
00116             self.AddMarkerPlotItem(data.x, data.y,  **opts)
00117 
00118 
00119 
00120 
00121 
00122 
00123 
00124 
00125 
00126 
00127 
00128 
00129 
00130 
00131 def ValidNum(x):
00132     try:
00133         return str(float(x)) != "nan"
00134     except:
00135         return False
00136 
00137 
00138 
00139 
00140 
00141 class GPData(Data):
00142     """ data for gnuplot """
00143 
00144     DefaultOpts ={
00145         "Style": 'linesp',
00146         "PType": '',
00147         "Colour": '',
00148         "Title": ''
00149     }
00150 
00151     def Sanitise(self, data):
00152 
00153         xdat,  ydat = data[0], data[1]
00154 
00155         checkx = map(ValidNum, xdat)
00156         while False in checkx:
00157             idx = checkx.index(False)
00158             for l in checkx,  xdat,  ydat:
00159                 del l[idx]
00160 
00161         checky = map(ValidNum, ydat)
00162         while False in checky:
00163             idx = checky.index(False)
00164             for l in checky,  xdat,  ydat:
00165                 del l[idx]
00166                 
00167     def UpdateData(self,data):
00168         self.Sanitise(data)
00169         self.data = data
00170 
00171 
00172 
00173 
00174 
00175     def __init__(self, data):
00176         self.Sanitise(data)
00177         Data.__init__(self, data)
00178         self.ValidOptions = dict(self.DefaultOpts) #  ?? why ? - surely CheckOptions ?
00179         self.Options.update(self.DefaultOpts)
00180 
00181 
00182     def GetData(self):
00183 
00184         lend = len(self.data[0])
00185         lines = []
00186         for n in range(lend):
00187             lines.append(" ".join(map(str,map(lambda l:l[n], self.data))))
00188 
00189         return "\n".join(lines)+"\ne\n"
00190 
00191 
00192     def GetOptions(self):
00193         return " ".join((
00194             "'-'",
00195             "t"+EnDQuote(self.Options["Title"]),
00196             "with ", self.Options["Style"],
00197             str(self.Options["Colour"]),
00198             str(self.Options["PType"])
00199         ))
00200 
00201 
00202 
00203 
00204 
00205 
00206 class GPPlotter(PlotterBase):
00207 
00208     gp_cmd = os.popen("which gnuplot").read()
00209     default_term = "wxt"
00210     plot_cmd = "plot "
00211 
00212     Options = {
00213         "Logx": "unset log x",
00214         "Logy": "unset log y",
00215         "xrange": "set xra [:]",
00216         "yrange" : "set yra [:]",
00217         "term": "set term " + default_term,
00218         "out" : "set out "
00219     }
00220 
00221     def __init__(self):
00222         if self.gp_cmd == "":
00223             print >>sys.stderr, "!! Can't locate gnuplot binary\n!! Plotting not available\n"
00224             self._gp2 = self._gp = Kali.Kali()
00225         else:
00226             self._gp2 = self._gp = os.popen(self.gp_cmd,"w")
00227         self.PlotNames = []
00228 
00229 
00230     def ToGP(self, string):
00231         self._gp.write(string+"\n")
00232         self._gp.flush()
00233 
00234 
00235     def GetOptions(self):
00236 
00237        return "\n".join(["set auto"]+self.Options.values())+"\n"
00238 
00239 
00240     def SetMissing(self, MissStr = '"nan"'):
00241 
00242         self.ToGP('set datafile missing '+ MissStr)
00243 
00244 
00245     def AddData(self, name, data, style="linespoints"):
00246 
00247         if not self.has_key(name):
00248             self[name] = GPData(data)
00249             self.PlotNames.append(name)
00250 
00251         self[name].Options["Title"] = name
00252         self[name].Options["Style"] = style
00253 
00254 
00255     def RemoveData(self, name):
00256 
00257         if self.has_key(name):
00258             del self[name]
00259             self.PlotNames.remove(name)
00260 
00261 
00262 
00263     def AutoName(self):
00264 
00265         for k in self.keys():
00266             self[k].Options["Title"] =k
00267 
00268 
00269 
00270     def PlotStr(self, Names=[]):
00271 
00272         if len(Names)==0:
00273             Names = self.PlotNames
00274 
00275         preamble = self.GetOptions()+self.plot_cmd+",".join(map(lambda n: self[n].GetOptions(), Names))
00276         data = "\n".join(map(lambda n:self[n].GetData(), Names))
00277 
00278         self.ToGP(preamble+"\n"+data)
00279         return preamble+"\n"+data
00280 
00281 
00282     def Plot(self,Names=""):
00283 
00284         self.ToGP(self.PlotStr(Names))
00285 
00286 
00287     def Replot(self):
00288         self.Plot(self.PlotNames)
00289 
00290     def SavePlot(self,filename):
00291         """ save the current plot in gp format to filename """
00292 
00293         print >>open(filename,"w"), self.PlotStr()
00294 
00295 
00296 
00297     def SetRange(self, Axis="x",  lo="", hi=""):
00298         """default args are auto scale (lo,hi)"""
00299 
00300         optk = Axis.lower()+"range"
00301         lo= str(lo)
00302         hi = str(hi)
00303         self.Options[optk] = "".join(("set ",  optk,  "[", lo, ":", hi, "]"))
00304 
00305 
00306     def SetLog(self, Axis="x", On=True):
00307 
00308         Axis = Axis.lower()
00309         optk = "Log" + Axis
00310         if On:
00311             cmd = "set"
00312         else:
00313             cmd = "unset"
00314 
00315         self.Options[optk] = " ".join((cmd, "log", Axis ))
00316 
00317 
00318     def SaveData(self, FName, Names=""):
00319 
00320         open(FName,"w").write(self.PlotStr(Names))
00321 
00322 
00323     def SaveGraphic(self, file, format, opts):
00324 
00325         term = self.Options["term"]
00326         out = self.Options["out"]
00327         self.Options["term"] = " ".join(("set term", format, opts))
00328         self.Options["out"] = "set out "+EnQuote(file)
00329         self.Replot()
00330         self.Options["term"] = term
00331         self.Options["out"] = out
00332 
00333 
00334     def SavePS(self,  file,  opts = "enhanced eps colour solid linewidth 2"):
00335 
00336        self.SaveGraphic(file, "post", opts)
00337 
00338 
00339     def SaveSVG(self, file, opts = "enhanced linewidth 2"):
00340 
00341         self.SaveGraphic(file, "svg", opts)
00342 
00343 
00344 Plotter = GPPlotter
00345 Plotdata = GPData

Generated on Tue Sep 4 2012 15:38:01 for ScrumPy by  doxygen 1.7.1