Package reflectometry :: Package reduction :: Module cmapmenu

Source Code for Module reflectometry.reduction.cmapmenu

  1  # This program is public domain 
  2  """ 
  3  Defines CMapMenu, a wx submenu containing colormaps. 
  4   
  5  === Example === 
  6   
  7  The following defines a context menu with mapper:: 
  8   
  9      import wx 
 10      import cmapmenu 
 11   
 12      ... 
 13      def onContextMenu(self,event): 
 14          popup = wx.Menu() 
 15          item = popup.Append(wx.ID_ANY,'&Save image', 'Save image as PNG') 
 16          wx.EVT_MENU(self, item.GetId(), self.onSaveImage) 
 17          item = popup.Append(wx.ID_ANY,'&Grid on/off', 'Toggle grid lines') 
 18          wx.EVT_MENU(self, item.GetId(), self.onGridToggle) 
 19          item = popup.AppendMenu(wx.ID_ANY, "Colourmaps", 
 20                                  CMapMenu(self, self.mapper, self.canvas)) 
 21   
 22  The assumption is that mapper and canvas are attributes of the panel for 
 23  which the context menu is defined.  When the new colour map is selected, 
 24  the mapper will be reset and the figure redrawn. 
 25   
 26  Sometimes you will want to do more than just update the mapper for the 
 27  current canvas.  You may for example want to record the new colormap name 
 28  in the application settings file so that it will be there when the 
 29  application is reloaded.  To do this, call CMapMenu(callback=self.OnColormap). 
 30  This will call the method OnColormap with the parameter name giving the 
 31  name of the colormap. 
 32  """ 
 33  __all__ = ['CMapMenu'] 
 34   
 35  import sys 
 36  import wx 
 37  import numpy 
 38  from matplotlib import cm 
 39   
40 -def colorbar_bitmap(colormap,length,thickness=10,orientation='horizontal'):
41 """ 42 Convert a colormap to a bitmap showing a colorbar for the colormap. 43 44 Orientation can be vertical or horizontal (only looks at the first letter). 45 """ 46 # Make an RGBA array from the colormap, either horizontally or vertically. 47 V = colormap(numpy.linspace(0,1,length),bytes=True) 48 if orientation[0].lower() == 'h': 49 V = numpy.tile(V,(thickness,1)) 50 bitmap = wx.BitmapFromBufferRGBA(length,thickness,V) 51 elif orientation[0].lower() == 'v': 52 V = numpy.tile(V,(1,thickness)) 53 bitmap = wx.BitmapFromBufferRGBA(thickness,length,V) 54 else: 55 raise ValueError,"expected orientation [V]ertical or [H]orizontal" 56 return bitmap
57
58 -def all_colormaps():
59 """ 60 Iterate over the available colormaps 61 """ 62 maps = [name 63 for name in cm.datad.keys() 64 if not name.endswith("_r")] 65 maps.sort() 66 return maps
67
68 -def grouped_colormaps():
69 """ 70 Colormaps grouped by source. 71 """ 72 mlab = ['autumn','winter','spring','summer', 73 'gray','bone','copper','pink', 74 'cool','hot', 75 'hsv','jet','spectral', 76 #'binary', # Seems to be a reverse of gray 77 'prism','flag'] 78 mlab_r = [m+'_r' for m in mlab] 79 brewer = ['Accent','Dark2', 80 'Spectral', 81 'Paired', 82 'Blues','Greens','Greys','Oranges','Purples','Reds', 83 'Pastel1','Pastel2', 84 'Set1','Set2','Set3', 85 'BrBG','BuGn','BuPu','GnBu', 86 'OrRd', 87 'PiYG','PRGn','PuBu','PuBuGn', 88 'PuOr','PuRd', 89 'RdBu','RdGy','RdPu', 90 'RdYlBu','RdYlGn', 91 'YlGn','YlGnBu','YlOrBr','YlOrRd', 92 ] 93 brewer_r = [m+'_r' for m in brewer] 94 gist = ['gist_ncar','gist_rainbow', 95 'gist_stern','gist_earth', 96 'gist_gray','gist_heat', 97 #'gist_yarg', # Seems to be a reverse of gray 98 ] 99 gist_r = [m+'_r' for m in gist] 100 101 return gist + [None] + mlab + [None] + brewer
102
103 -def event_callback(callback, **kw):
104 """ 105 Add keyword arguments to the event callback. 106 """ 107 return lambda evt: callback(evt,**kw)
108 -class CMapMenu(wx.Menu):
109 """ 110 Menu tree binding to a list of colormaps. 111 """
112 - def __init__(self, window, 113 mapper=None, canvas=None, callback=None):
114 """ 115 Define a context menu for selecting colormaps. 116 117 Need a window to use as the event handler. 118 If mapper is defined, it will be updated with the new colormap. 119 If canvas is defined, it will update on idle. 120 """ 121 wx.Menu.__init__(self) 122 123 # OS X needs 16x16 icons; Windows and Linux can be longer 124 bar_length = 32 if not sys.platform in ['darwin'] else 16 125 bar_height = 16 126 self.mapper,self.canvas,self.callback = mapper,canvas,callback 127 self.selected = None 128 self.mapid = {} 129 for name in grouped_colormaps(): 130 if name is None: 131 self.AppendSeparator() 132 else: 133 item = wx.MenuItem(self, wx.ID_ANY, name) 134 map = cm.get_cmap(name) 135 icon = colorbar_bitmap(map,bar_length,thickness=bar_height) 136 item.SetBitmap(icon) 137 self.AppendItem(item) 138 window.Bind(wx.EVT_MENU, 139 event_callback(self._OnSelect, name=name), 140 id=item.GetId())
141
142 - def _OnSelect(self, event, name=None):
143 """ 144 When selected, record the name, update the mapper and invoke the 145 callback. 146 """ 147 self.selected = name 148 if self.mapper: 149 self.mapper.set_cmap(cm.get_cmap(name)) 150 if self.canvas: 151 self.canvas.draw_idle() 152 if self.callback: 153 self.callback(name)
154
155 -def demo():
156 157 class ChangeCM(object): 158 def __init__(self,im): 159 self.im = im
160 def __call__(self, m): 161 self.im.set_cmap(m.get_cmap()) 162 self.im.set_clim(m.get_clim()) 163 #self.im.update_bruteforce(m) 164 165 from matplotlib.image import FigureImage 166 from matplotlib.figure import Figure 167 from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as Canvas 168 class Frame(wx.Frame): 169 def __init__(self): 170 wx.Frame.__init__(self, parent=None, title="Colourmap Selection") 171 172 self.figure = Figure(dpi=80, figsize=(2,2)) 173 self.canvas = Canvas(self, -1, self.figure) 174 self.axes = self.figure.gca() 175 x = y = numpy.linspace(-3,3,80) 176 X,Y = numpy.meshgrid(x,y) 177 V = numpy.sin(Y**2+X**2) 178 self.mapper = FigureImage(self.figure) 179 im = self.axes.pcolor(x,y,V,shading='flat') 180 try: 181 cb = self.mapper.callbacksSM.connect('changed', ChangeCM(im)) 182 except AttributeError: # Using 0.91 style 183 self.mapper.add_observer(im) 184 #self.figure.colorbar(self.mapper) 185 186 sizer = wx.BoxSizer(wx.VERTICAL) 187 sizer.Add(self.canvas,1,wx.EXPAND) 188 self.SetSizer(sizer) 189 190 self.canvas.Bind(wx.EVT_RIGHT_DOWN, self.OnContext) 191 192 193 def OnContext(self, evt): 194 popup = wx.Menu() 195 item = popup.Append(wx.ID_ANY,'&Grid on/off', 'Toggle grid lines') 196 wx.EVT_MENU(self, item.GetId(), self.OnGridToggle) 197 cmapmenu = CMapMenu(self, callback = self.OnColormap, 198 mapper=self.mapper, canvas=self.canvas) 199 item = popup.AppendMenu(wx.ID_ANY, "Colourmaps", cmapmenu) 200 self.PopupMenu(popup, evt.GetPositionTuple()) 201 def OnColormap(self, name): 202 print "Selected colormap",name 203 def OnGridToggle(self, event): 204 self.axes.grid() 205 self.canvas.draw_idle() 206 207 app = wx.App(redirect=False) 208 Frame().Show() 209 app.MainLoop() 210 211 212 if __name__ == "__main__": demo() 213