data_display.py
Go to the documentation of this file.
00001 import numpy as np
00002 import matplotlib.pyplot as pb
00003 import matplotlib.patches as patches
00004 import matplotlib.transforms as transforms
00005 import hrl_lib.util as ut
00006 
00007 LIGHTBLUE = '#33CCFF'
00008 DARKBLUE = '#008AB8'
00009 LIME = '#CCFF33'
00010 GREY = '#E0E0E0'
00011 
00012 ##
00013 # gets a random color string
00014 # @return a random color string of format #XXXXXX
00015 def random_color():
00016     r = '%02X'%np.random.randint(0, 255)
00017     g = '%02X'%np.random.randint(0, 255)
00018     b = '%02X'%np.random.randint(0, 255)
00019     c = '#' + r + g + b
00020     return c
00021 
00022 ##
00023 # Selection rectangle for TimeSeriesDisplay
00024 class SelectRect:
00025     def __init__(self, x_start, x_end, axes_objects, color='#FFCC33', alpha=.3):
00026         self.rects = []
00027         for axes_object in axes_objects:
00028             trans = transforms.blended_transform_factory(axes_object.transData, 
00029                                                         axes_object.transAxes)
00030             rect = patches.Rectangle((x_start, 0), width=(x_end-x_start), 
00031                                         height=1, transform=trans, color=color, alpha=alpha)
00032             axes_object.add_patch(rect)
00033             self.rects.append(rect)
00034 
00035         self.x_start = x_start
00036         self.x_end = x_end
00037         self.name = None
00038 
00039     def set_color(self, color):
00040         for r in self.rects:
00041             r.set_color(color)
00042 
00043     def set_start(self, x):
00044         self.x_start = x
00045         for rect in self.rects:
00046             rect.set_x(self.x_start)
00047             rect.set_width(self.x_end - self.x_start)
00048 
00049     def set_end(self, x):
00050         self.x_end = x
00051         for rect in self.rects:
00052             rect.set_width(self.x_end - self.x_start)
00053 
00054     def get_start(self):
00055         return self.x_start
00056 
00057     def get_end(self):
00058         return self.x_end
00059 
00060     def set_name(self, n):
00061         self.name = n
00062 
00063     def get_name(self):
00064         return self.name
00065 
00066 ##
00067 # plot lists of time series
00068 # allow saving & annotation
00069 class TimeSeriesDisplay:
00070     #, lists_of_time_series, rows, columns
00071     def __init__(self, list_of_time_series, labels, limits=None, color='b', save='segments.pkl', name="", marker=''):
00072         #Display
00073         self.figure = pb.figure()
00074         self.figure.set_facecolor('w')
00075         self.axes = []
00076 
00077         #pdb.set_trace()
00078         time_idxes = [t for t, d in list_of_time_series]
00079         min_time = np.min(np.concatenate(time_idxes))
00080         max_time = np.max(np.concatenate(time_idxes))
00081 
00082         for idx, time_series in enumerate(list_of_time_series):
00083             tlist, ylist = time_series
00084             #print len(tlist), len(ylist)
00085             axis = pb.subplot(len(list_of_time_series), 1, idx+1)
00086             print labels[idx], len(tlist), len(ylist)
00087             lines = pb.plot(tlist, ylist, marker+'-', color=color)
00088             pb.xlim(min_time, max_time)
00089             if limits != None and limits[idx] != None:
00090                 ymin, ymax = limits[idx] 
00091                 pb.ylim(ymin, ymax)
00092             pb.ylabel(labels[idx])
00093             #pdb.set_trace()
00094             self.axes.append(axis)
00095 
00096         #Interaction
00097         pb.suptitle(name)
00098         self.figure.canvas.mpl_connect('button_press_event', self.button_press_handler)
00099         self.figure.canvas.mpl_connect('key_press_event', self.key_press_handler)
00100 
00101         self.save_filename = save
00102         self.mode = 'EDIT' #or INTERACT
00103         self.state = 'START'
00104         self.rects = []
00105         self.x = None
00106         self.active_idx = None
00107         self.ACTIVE_COLOR = LIME
00108         self.INACTIVE_COLOR = GREY
00109 
00110         self.load_state()
00111 
00112     def _set_active(self, idx):
00113         for r in self.rects:
00114             r.set_color(self.INACTIVE_COLOR)
00115 
00116         self.active_idx = idx % len(self.rects)
00117         self.rects[self.active_idx].set_color(self.ACTIVE_COLOR)
00118         print 'TimeSeriesDisplay._set_active(): selected', self.rects[self.active_idx].get_name()
00119 
00120     def _inactivate_current_rect(self):
00121         if self.active_idx != None:
00122             self.rects[self.active_idx].set_color(self.INACTIVE_COLOR)
00123 
00124     def key_press_handler(self, event):
00125         #print event.key
00126         if self.mode == 'EDIT':
00127             if event.key == 'escape':
00128                 self.state = 'START'
00129                 self._inactivate_current_rect()
00130 
00131             elif event.key == 'right':
00132                 if self.active_idx != None:
00133                     self._set_active(self.active_idx + 1)
00134                     self.state = 'TWO_POINTS'
00135 
00136             elif event.key == 'left':
00137                 if self.active_idx != None:
00138                     self._set_active(self.active_idx - 1)
00139                     self.state = 'TWO_POINTS'
00140 
00141             elif event.key == ' ':
00142                 if self.active_idx != None:
00143                     print 'Current name is', self.rects[self.active_idx].get_name(), '. Enter a new name:'
00144                     n = raw_input()
00145                     self.rects[self.active_idx].set_name(n)
00146 
00147             elif event.key == 'w':
00148                 if len(self.rects) > 0:
00149                     self.save_state()
00150         elif event.key == 'e':
00151             if self.mode == 'EDIT':
00152                 self.mode = 'INTERACT'
00153             else:
00154                 self.mode = 'EDIT'
00155             print self.mode
00156 
00157         self.figure.canvas.draw()
00158         #print event.key
00159 
00160     def load_state(self):
00161         try:
00162             rects = ut.load_pickle(self.save_filename)
00163             srects = []
00164             for r in rects:
00165                 start, end, name = r
00166                 srect = SelectRect(start, end, self.axes)
00167                 srect.set_name(name)
00168                 srects.append(srect)
00169             self.rects = srects
00170             self._set_active(0)
00171             self.state = 'TWO_POINTS'
00172             self.figure.canvas.draw()
00173         except IOError, e:
00174             print 'INFO: was not able to load', self.save_filename
00175 
00176     def save_state(self):
00177         segments = []
00178         for r in self.rects:
00179             segments.append([r.get_start(), r.get_end(), r.get_name()])
00180         ut.save_pickle(segments, self.save_filename)
00181         print 'saved state to', self.save_filename
00182 
00183     def button_press_handler(self, event):
00184         #print 'in state', self.state
00185         #print event.button
00186         #print 'dfd'
00187         if self.mode == 'EDIT':
00188             #print 'dfd', event.button, event.xdata.__class__, self.state
00189             if event.button == 1 and event.xdata != None:
00190                 if self.state == 'ONE_POINT': 
00191                     sm = min(self.x, event.xdata)
00192                     sx = max(self.x, event.xdata)
00193                     active_rect = SelectRect(sm, sx, self.axes)
00194                     self.rects.append(active_rect)
00195                     self._set_active(len(self.rects) - 1)
00196                     self.state = 'TWO_POINTS'
00197 
00198                 elif self.state == 'TWO_POINTS':
00199                     if event.xdata > self.rects[self.active_idx].get_end():
00200                         self.rects[self.active_idx].set_end(event.xdata)
00201                     elif event.xdata < self.rects[self.active_idx].get_start():
00202                         self.rects[self.active_idx].set_start(event.xdata)
00203                     else:
00204                         dend   = abs(event.xdata - self.rects[self.active_idx].get_end())
00205                         dstart = abs(event.xdata - self.rects[self.active_idx].get_start())
00206                         if dstart < dend:
00207                             self.rects[self.active_idx].set_start(event.xdata)
00208                         else:
00209                             self.rects[self.active_idx].set_end(event.xdata)
00210 
00211             elif event.button == 3 and event.xdata != None:
00212                 if self.state == 'START':
00213                     self.x = event.xdata
00214                     self.state = 'ONE_POINT'
00215 
00216                 elif self.state == 'TWO_POINTS':
00217                     self.x = event.xdata
00218                     self.state = 'ONE_POINT'
00219                     self._inactivate_current_rect()
00220         
00221         #print 'out state', self.state
00222         self.figure.canvas.draw()


hrl_lib
Author(s): Cressel Anderson, Travis Deyle, Advait Jain, Hai Nguyen, Advisor: Prof. Charlie Kemp, Lab: Healthcare Robotics Lab at Georgia Tech
autogenerated on Wed Nov 27 2013 11:34:06