Package trunk :: Package BIP :: Package Viz :: Module realtime
[hide private]

Source Code for Module trunk.BIP.Viz.realtime

  1  __author__="fccoelho@gmail.com" 
  2  __date__ ="$26/02/2009 10:44:29$" 
  3  __docformat__ = "restructuredtext en" 
  4  import Gnuplot 
  5  import numpy 
  6  import pylab as P 
  7  from SimpleXMLRPCServer import SimpleXMLRPCServer 
  8  from multiprocessing import Process 
  9   
 10  Gnuplot.GnuplotOpts.prefer_inline_data = 1 
 11  Gnuplot.GnuplotOpts.prefer_fifo_data = 0 
 12   
 13   
 14  __ports_used = [] 
 15   
16 -class RTplot:
17 ''' 18 Real time plotting class based on Gnuplot 19 '''
20 - def __init__(self, persist=0,debug=0):
21 self.gp = Gnuplot.Gnuplot(persist = persist, debug=debug) 22 self.plots = []
23
24 - def clearFig(self):
25 ''' 26 Clears the figure. 27 ''' 28 self.plots = []
29 #self.gp.reset()
30 - def close_plot(self):
31 self.gp.close()
32
33 - def scatter(self,x,y,names=[],title='',style='points', jitter = True):
34 """ 35 Makes scatter plots from numpy arrays. 36 if arrays are multidimensional, multiple scatter plots will be generated, pairing rows. 37 """ 38 if jitter: 39 jt = numpy.random.normal(1, 1e-4, 1)[0] 40 else: 41 jt = 1 42 if isinstance(x, numpy.ndarray): 43 if not isinstance(y, numpy.ndarray): 44 raise TypeError("If x is a numpy array, y must also be an array.") 45 if x.shape != y.shape: 46 raise ValueError("x, %s and y, %s arrays must have the same shape."%(x.shape,y.shape)) 47 if names: 48 if len(names) != x.shape[0]: 49 raise ValueError("names list must have exactly %s items, but has %s."%(x.shape[0],len(names))) 50 else: 51 x = numpy.array(x) 52 y = numpy.array(y) 53 54 55 self.gp('set title "%s"'%title) 56 if not names: 57 names = ['s%s'%i for i in range(x.shape[0])] 58 if len(x.shape) > 1 and len(x.shape) <= 2: 59 i = 0 60 for n in range(x.shape[0]): 61 self.plots.append(Gnuplot.PlotItems.Data(x[n]*jt,y[n]*jt,title=names[i],with_=style)) 62 i += 1 63 self.gp.plot(*tuple(self.plots)) 64 elif len(x.shape) >2: 65 pass 66 else: 67 #print data 68 self.plots.append(Gnuplot.PlotItems.Data(x*jt,y*jt,title=names[0],with_=style)) 69 self.gp.plot(*tuple(self.plots))
70
71 - def plotlines(self, data, x=None, names=[],title='',style='lines', multiplot=0):
72 ''' 73 Create a single/multiple line plot from a numpy array or record array. 74 75 :Parameters: 76 - `data`: must be a numpy array or a list of lists,or record array, with series as rows 77 - `x`: x values for the series: numpy array 78 - `names`: is a list of strings to serve as legend labels 79 - `title`: Figure Title. 80 - `style`: plot styles from gnuplot: lines, boxes, points, linespoints, etc. 81 - `multiplot`: Whether to make multiple subplots 82 ''' 83 84 if multiplot: 85 sq = numpy.sqrt(len(data)) 86 r= numpy.floor(sq);c=numpy.ceil(sq) 87 if len(data) == 3: 88 r=3;c=1 89 self.gp('set multiplot layout %s,%s title "%s"'%(r, c, title)) 90 else: 91 self.gp('set title "%s"'%title) 92 93 if isinstance (data, list): 94 data = numpy.array(data) 95 if isinstance(data,numpy.core.records.recarray): 96 return self._linesFromRA(data,x, style) 97 if len(data.shape) > 1 and len(data.shape) <= 2: 98 i = 0 99 for row in data: 100 if x== None: 101 x = numpy.arange(len(row)) 102 if names: 103 self.plots.append(Gnuplot.PlotItems.Data(x, row,title=names[i], with_=style)) 104 else: 105 self.plots.append(Gnuplot.PlotItems.Data(x, row, with_=style)) 106 i += 1 107 if not multiplot: 108 self.gp.plot(*tuple(self.plots)) 109 else: 110 [self.gp.plot(pl) for pl in self.plots] 111 elif len(data.shape) >2: 112 pass 113 else: 114 # print data 115 if x==None: 116 x = numpy.arange(len(data)) 117 self.plots.append(Gnuplot.PlotItems.Data(x,data,title=names[0],with_=style)) 118 if not multiplot: 119 self.gp.plot(*tuple(self.plots)) 120 else: 121 [self.gp.plot(pl) for pl in self.plots]
122
123 - def _linesFromRA(self,data,x, style):
124 ''' 125 Record-array specific code 126 ''' 127 for n in data.dtype.names: 128 if len(data.shape) > 1 and len(data.shape) <= 2: 129 i = 0 130 for row in data[n]: 131 if x == None: 132 x = numpy.arange(len(row)) 133 self.plots.append(Gnuplot.PlotItems.Data(x, row,title=n+':%s'%i,with_=style)) 134 i += 1 135 elif len(data.shape) >2: 136 pass 137 # TODO: figure out what to do with higher dimensional data 138 else: 139 self.plots.append(Gnuplot.PlotItems.Data(x, data[n],title=n,with_=style)) 140 self.gp.plot(*tuple(self.plots))
141
142 - def plothist(self,data, title='', names=[], multiplot=0):
143 ''' 144 Create a sinlge/multiple Histogram plot from a numpy array or record array. 145 146 :Parameters: 147 - `data`: must be a numpy array or record array, with series as rows 148 - `names`: is a list of strings to serve as legend labels 149 ''' 150 if multiplot: 151 sq = numpy.sqrt(len(data)) 152 r= numpy.floor(sq);c=numpy.ceil(sq) 153 if len(data) == 3: 154 r=3;c=1 155 self.gp('set multiplot layout %s,%s title "%s"'%(r, c, title)) 156 else: 157 self.gp('set title "%s"'%title) 158 self.gp('set style data boxes') 159 160 if isinstance (data, list): 161 data = numpy.array(data) 162 if isinstance(data,numpy.core.records.recarray): 163 return self._histFromRA(data) 164 if not names: 165 names = ['s%s'%i for i in range(data.shape[0])] 166 if len(data.shape) > 1 and len(data.shape) <= 2: 167 for n,row in enumerate(data): 168 m,bins = numpy.histogram(row,normed=True,bins=50) 169 d = zip(bins[:-1],m) 170 self.plots.append(Gnuplot.PlotItems.Data(d,title=names[n])) 171 [self.gp.plot(pl) for pl in self.plots] 172 elif len(data.shape) >2: 173 pass 174 else: 175 m,bins = numpy.histogram(data,normed=True,bins=50) 176 d = zip(bins[:-1],m) 177 self.plots.append(Gnuplot.PlotItems.Data(d,title=names[0])) 178 [self.gp.plot(pl) for pl in self.plots]
179
180 - def _histFromRA(self,data):
181 ''' 182 Record-array specific code 183 ''' 184 for n in data.dtype.names: 185 if len(data.shape) > 1 and len(data.shape) <= 2: 186 i = 0 187 for row in data[n]: 188 m,bins = numpy.histogram(row,normed=True,bins=50) 189 d = zip(bins[:-1],m) 190 self.plots.append(Gnuplot.PlotItems.Data(d,title=n+':%s'%i)) 191 i += 1 192 elif len(data.shape) > 2: 193 pass 194 else: 195 m,bins = numpy.histogram(data[n],normed=True,bins=50) 196 d = zip(bins[:-1],m) 197 self.plots.append(Gnuplot.PlotItems.Data(d,title=n)) 198 self.gp.plot(*tuple(self.plots))
199
200 -class RTpyplot:
201 """ 202 Creates an animated plot based on pylab 203 """
204 - def __init__(self, nseries=1, leng =10, names=['l'], title = ""):
205 self.nseries = nseries 206 self.leng = leng 207 self.names = names 208 self.title = title 209 self.lines = [] 210 self.started = False
211
212 - def _setup(self):
213 self.ax = P.subplot(111) 214 self.canvas = self.ax.figure.canvas 215 for i in range(self.nseries): 216 line, = P.plot(numpy.arange(self.leng), [1]*self.leng,label=self.names[i], title=self.title, animated=True) 217 self.lines.append(line) 218 P.legend(loc=0) 219 P.grid() 220 P.show() 221 self.started = True
222 - def plotlines(self, data):
223 if not self.started: 224 self._setup() 225 nlines = data.shape[0] 226 assert nlines == self.nseries 227 for i, d in enumerate(data): 228 background = self.canvas.copy_from_bbox(self.ax.bbox) 229 self.lines[i].set_ydata(d) 230 self.ax.draw_artist(self.lines[i]) 231 self.canvas.blit(self.ax.bbox)
232 233
234 -def start_server(server):
235 server.register_instance(RTplot(persist=0)) 236 server.register_introspection_functions() 237 server.serve_forever()
238 239
240 -def rpc_plot(port=None):
241 """ 242 XML RPC plot server factory function 243 returns port if server successfully started or 0 244 """ 245 if port == None: 246 po = 10001 247 while 1: 248 if po not in __ports_used:break 249 po += 1 250 port = po 251 try: 252 server = SimpleXMLRPCServer(("localhost", port),logRequests=False, allow_none=True) 253 server.register_introspection_functions() 254 p = Process(target=start_server, args=(server, )) 255 p.daemon = True 256 p.start() 257 except: 258 return 0 259 __ports_used.append(port) 260 return port
261 262 263 #p = Process(target=start_server) 264 #p.daemon = True 265 #p.start() 266 if __name__ == "__main__": 267 gp = RTplot() 268 gp.plotlines([range(10), range(10)], range(10, 20),['a', 'b'], 'multi', 'lines', 1 ) 269