Package topo :: Package plotting :: Module plotfilesaver
[hide private]
[frames] | no frames]

Source Code for Module topo.plotting.plotfilesaver

  1  """ 
  2  File saving routines for plots. 
  3   
  4  Typically called using save_plotgroup in commands/analysis.py, but these 
  5  objects can also be instantiated explicitly, to save a series of plots. 
  6   
  7  $Id: plotfilesaver.py 11314 2010-07-27 17:18:52Z ceball $ 
  8  """ 
  9  __version__='$Revision: 11314 $' 
 10   
 11  import Image 
 12  import numpy 
 13   
 14  import param 
 15  from param import normalize_path 
 16   
 17  import topo 
 18   
 19   
 20  # Consider using PIL's ImageFont module 
 21   
22 -class PlotGroupSaver(param.Parameterized):
23 """ 24 Allows a PlotGroup to be saved as a set of bitmap files on disk. 25 """ 26 file_format = param.String(default="png",doc=""" 27 Bitmap image file format to use.""") 28 29 filename_prefix = param.String(default="",doc=""" 30 Optional prefix that can be used in the filename_format command 31 to disambiguate different simulations or conditions.""") 32 33 filename_suffix = param.String(default="",doc=""" 34 Optional suffix that can be used in the filename_format command 35 to disambiguate different simulations or conditions.""") 36 37 filename_format = param.String(default= 38 "%(filename_prefix)s%(basename)s_%(plot_label)s%(filename_suffix)s.%(file_format)s",doc=""" 39 Format string to use for generating filenames for plots. This 40 string will be evaluated in the context of a dictionary that 41 defines various items commonly used when generating filenames, 42 including:: 43 44 basename: the default sim.basename(), usually name+time() 45 time: the current simulation time (topo.sim.time()) 46 sim_name: the name of the current simulation (topo.sim.name) 47 plot_label: the label specfied in the PlotGroup for this plot 48 file_format: the bitmap image file format for this type of plot 49 plotgroup_name: the name of this PlotGroup 50 """) 51 # Should move this out of plotfilesaver to get the same filenames in the GUI. 52 # Should also allow each template in topo/command/analysis.py to have a nice 53 # short filename format, perhaps as an option. 54
55 - def __init__(self,plotgroup,**params):
56 super(PlotGroupSaver,self).__init__(**params) 57 self.plotgroup = plotgroup
58 59
60 - def strip(self,filename):
61 """Strip inappropriate characters from a filename.""" 62 return filename\ 63 .replace('\n','_')\ 64 .replace('\t','_')\ 65 .replace(' ','_')\ 66 .replace('&','And')
67 68
69 - def filename(self,label,**params):
70 """Calculate a specific filename from the filename_format.""" 71 vars = dict(self.get_param_values()) 72 vars.update(self.__dict__) 73 vars['basename']= topo.sim.basename() 74 vars['sim_name']= topo.sim.name 75 vars['time']=topo.sim.time() 76 vars['plot_label']=label 77 vars['plotgroup_name']=self.plotgroup.name 78 vars.update(params) 79 80 return self.strip(self.filename_format % vars)
81 82
83 - def save_to_disk(self,**params):
84 for p,l in zip(self.plotgroup.plots,self.plotgroup.labels): 85 p.bitmap.image.save(normalize_path(self.filename(l,**params)))
86 87 88 89 90 91 92 # Could move this elsewhere if it will be useful. 93 # 94 # Adapted from: 95 # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/412982
96 -def make_contact_sheet(imgs, (marl,mart,marr,marb), padding):
97 """ 98 Make a contact sheet (image grid) from a 2D array of PIL images:: 99 100 imgs 2D array of images 101 102 marl The left margin in pixels 103 mart The top margin in pixels 104 marr The right margin in pixels 105 marb The bottom margin in pixels 106 107 padding The padding between images in pixels 108 109 Returns a PIL image object. 110 """ 111 # should make sure imgs is numpy array 112 113 # CB: *** should do this in numpy without the conversion to list and back! *** 114 nrows,ncols = imgs.shape 115 i_widths = numpy.array([i.size[0] for i in imgs.ravel()]).reshape(nrows,ncols) 116 i_heights = numpy.array([i.size[1] for i in imgs.ravel()]).reshape(nrows,ncols) 117 118 col_widths = i_widths.max(axis=0) 119 row_heights = i_heights.max(axis=1) 120 121 marw = marl+marr 122 marh = mart+ marb 123 124 padw = (ncols-1)*padding 125 padh = (nrows-1)*padding 126 127 isize = (col_widths.sum()+marw+padw, row_heights.sum()+marh+padh) 128 129 # Create the new image. The background doesn't have to be white. 130 white = (255,255,255) 131 inew = Image.new('RGB',isize,white) 132 133 # CB: should be replaced with a more numpy technique. 134 for irow in range(nrows): 135 for icol in range(ncols): 136 # if different widths in a col, or different heights in a 137 # row, each image will currently just go at top left 138 # defined by largest in col/row (should be centered 139 # instead) 140 left = marl+col_widths[0:icol].sum()+icol*padding 141 right = left+i_widths[irow,icol] 142 upper = mart+row_heights[0:irow].sum()+irow*padding 143 lower = upper+i_heights[irow,icol] 144 inew.paste(imgs[irow,icol],(left,upper,right,lower)) 145 return inew
146 147 148 149
150 -class CFProjectionPlotGroupSaver(PlotGroupSaver):
151 """ 152 Allows a CFProjectionPlotGroup to be saved as a bitmap file, 153 concatenating all the CF plots into a single image. 154 """
155 - def save_to_disk(self,**params):
156 imgs = numpy.array([p.bitmap.image 157 for p in self.plotgroup.plots], 158 dtype=object).reshape( 159 self.plotgroup.proj_plotting_shape) 160 img = make_contact_sheet(imgs, (3,3,3,3), 3) 161 img.save(normalize_path(self.filename( 162 self.plotgroup.sheet.name+"_"+ 163 self.plotgroup.projection.name,**params)))
164