Package topo :: Package command :: Module pylabplots
[hide private]
[frames] | no frames]

Source Code for Module topo.command.pylabplots

   1  """ 
   2  Line-based and matrix-based plotting commands using MatPlotLib. 
   3   
   4  Before importing this file, you will probably want to do something 
   5  like: 
   6   
   7    from matplotlib import rcParams 
   8    rcParams['backend']='TkAgg' 
   9   
  10  to select a backend, or else select an appropriate one in your 
  11  matplotlib.rc file (if any).  There are many backends available for 
  12  different GUI or non-GUI uses. 
  13   
  14  $Id: pylabplots.py 10921 2010-02-16 18:46:32Z antolikjan $ 
  15  """ 
  16  __version__='$Revision: 10921 $' 
  17   
  18  import re 
  19  import os 
  20  import copy 
  21  import errno 
  22   
  23  try: 
  24      import matplotlib 
  25      import pylab 
  26  except ImportError: 
  27      print "Warning: Could not import matplotlib; pylab plots will not work." 
  28   
  29  import numpy 
  30  from math import pi 
  31  # JABALERT: Import all of these from numpy instead? 
  32  from numpy.oldnumeric import arange, sqrt, array, floor, transpose, argmax, argmin, cos, sin, log10, Float 
  33  from numpy import outer,arange,ones,zeros 
  34   
  35  from numpy.fft.fftpack import fft2 
  36  from numpy.fft.helper import fftshift 
  37  from numpy import abs 
  38   
  39  import topo 
  40  from topo.base.sheetview import SheetView 
  41  from topo.base.arrayutil import octave_output, centroid, wrap 
  42  from topo.base.sheet import Sheet 
  43  from topo.base.arrayutil import wrap 
  44  from topo.misc.filepath import normalize_path 
  45  from topo.misc.util import frange 
  46  import topo.analysis.vision 
  47  from topo.plotting.plot import make_template_plot, Plot 
  48  import param 
  49  from param import ParameterizedFunction 
  50  from param.parameterized import ParamOverrides 
  51  from topo.pattern.basic import SineGrating, RawRectangle, OrientationContrast 
  52  from topo.plotting.plotgroup import create_plotgroup, plotgroups 
  53  from topo.base.cf import CFSheet 
  54   
  55  from topo.analysis.featureresponses import Feature, PatternPresenter, FeatureCurves 
  56  from topo.analysis.featureresponses import SinusoidalMeasureResponseCommand, PositionMeasurementCommand, SingleInputResponseCommand, FeatureCurveCommand, UnitCurveCommand 
  57   
  58   
  59   
60 -class PylabPlotCommand(ParameterizedFunction):
61 """Parameterized command for plotting using Matplotlib/Pylab.""" 62 63 file_dpi = param.Number( 64 default=100.0,bounds=(0,None),softbounds=(0,1000),doc=""" 65 Default DPI when rendering to a bitmap. 66 The nominal size * the dpi gives the final image size in pixels. 67 E.g.: 4"x4" image * 80 dpi ==> 320x320 pixel image.""") 68 69 file_format = param.String(default="png",doc=""" 70 Which image format to use when saving images. 71 The output can be png, ps, pdf, svg, or any other format 72 supported by Matplotlib.""") 73 74 # JABALERT: Should replace this with a filename_format and 75 # associated parameters, as in PlotGroupSaver. 76 # Also should probably allow interactive display to be controlled 77 # separately from the filename, to make things work more similarly 78 # with and without a GUI. 79 filename = param.String(default=None,doc=""" 80 Optional base of the filename to use when saving images; 81 if None the plot will be displayed interactively. 82 83 The actual name is constructed from the filename base plus the 84 suffix plus the current simulator time plus the file_format.""") 85 86 filename_suffix = param.String(default="",doc=""" 87 Optional suffix to be used for disambiguation of the filename.""") 88 89 title = param.String(default=None,doc=""" 90 Optional title to be used when displaying the plot interactively.""") 91 92 __abstract = True 93 94
95 - def _set_windowtitle(self,title):
96 """ 97 Helper function to set the title (if not None) of this PyLab plot window. 98 """ 99 100 # At the moment, PyLab does not offer a window-manager-independent 101 # means for controlling the window title, so what we do is to try 102 # what should work with Tkinter, and then suppress all errors. That 103 # way we should be ok when rendering to a file-based backend, but 104 # will get nice titles in Tk windows. If other toolkits are in use, 105 # the title can be set here using a similar try/except mechanism, or 106 # else there can be a switch based on the backend type. 107 if title is not None: 108 try: 109 manager = pylab.get_current_fig_manager() 110 manager.window.title(title) 111 except: 112 pass
113 114
115 - def _generate_figure(self,p):
116 """ 117 Helper function to display a figure on screen or save to a file. 118 119 p should be a ParamOverrides instance containing the current 120 set of parameters. 121 """ 122 123 pylab.show._needmain=False 124 if p.filename is not None: 125 # JABALERT: need to reformat this as for other plots 126 fullname=p.filename+p.filename_suffix+str(topo.sim.time())+"."+p.file_format 127 pylab.savefig(normalize_path(fullname), dpi=p.file_dpi) 128 else: 129 self._set_windowtitle(p.title) 130 pylab.show()
131 132 133
134 -class vectorplot(PylabPlotCommand):
135 """ 136 Simple line plotting for any vector or list of numbers. 137 138 Intended for interactive debugging or analyzing from the command 139 prompt. See MatPlotLib's pylab functions to create more elaborate 140 or customized plots; this is just a simple example. 141 142 An optional string can be supplied as a title for the figure, if 143 desired. At present, this is only used for the window, not the 144 actual body of the figure (and will thus not appear when the 145 figure is saved). 146 147 The style argument allows different line/linespoints style for 148 the plot: 'r-' for red solid line, 'bx' for blue x-marks, etc. 149 See http://matplotlib.sourceforge.net/matplotlib.pylab.html#-plot 150 for more possibilities. 151 152 The label argument can be used to identify the line in a figure legend. 153 154 Ordinarily, the x value for each point on the line is the index of 155 that point in the vec array, but a explicit list of xvalues can be 156 supplied; it should be the same length as vec. 157 158 Execution of multiple vectorplot() commands with different styles 159 will result in all those styles overlaid on a single plot window. 160 """ 161 162 # JABALERT: All but the first two arguments should probably be Parameters
163 - def __call__(self,vec,xvalues=None,style='-',label=None,**params):
164 p=ParamOverrides(self,params) 165 166 if xvalues is not None: 167 pylab.plot(xvalues, vec, style, label=label) 168 else: 169 pylab.plot(vec, style, label=label) 170 171 pylab.grid(True) 172 self._generate_figure(p)
173 174 175
176 -class matrixplot(PylabPlotCommand):
177 """ 178 Simple plotting for any matrix as a bitmap with axes. 179 180 Like MatLab's imagesc, scales the values to fit in the range 0 to 1.0. 181 Intended for interactive debugging or analyzing from the command 182 prompt. See MatPlotLib's pylab functions to create more elaborate 183 or customized plots; this is just a simple example. 184 """ 185 186 plot_type = param.Callable(default=pylab.gray,doc=""" 187 Matplotlib command to generate the plot, e.g. pylab.gray or pylab.hsv.""") 188 189 # JABALERT: All but the first two should probably be Parameters
190 - def __call__(self,mat,aspect=None,colorbar=True,**params):
191 p=ParamOverrides(self,params) 192 193 p.plot_type() 194 pylab.figure(figsize=(5,5)) 195 pylab.imshow(mat,interpolation='nearest',aspect=aspect) 196 if colorbar and (mat.min()!= mat.max()): pylab.colorbar() 197 self._generate_figure(p)
198 199
200 -class matrixplot3d(PylabPlotCommand):
201 """ 202 Simple plotting for any matrix as a 3D wireframe with axes. 203 204 Uses Matplotlib's beta-quality features for 3D plotting. These 205 usually work fine for wireframe plots, although they don't always 206 format the axis labels properly, and do not support removal of 207 hidden lines. Note that often the plot can be rotated within the 208 window to make such problems go away, and then the best result can 209 be saved if needed. 210 211 Other than the default "wireframe", the type can be "contour" to 212 get a contour plot, or "surface" to get a solid surface plot, but 213 surface plots currently fail in many cases, e.g. for small 214 matrices. 215 216 If you have trouble, you can try matrixplot3d_gnuplot instead. 217 """ 218 219 # JABALERT: All but the first two arguments should probably be Parameters
220 - def __call__(self,mat,type="wireframe",**params):
221 p=ParamOverrides(self,params) 222 223 from mpl_toolkits.mplot3d import axes3d 224 225 fig = pylab.figure() 226 ax = axes3d.Axes3D(fig) 227 228 # Construct matrices for r and c values 229 rn,cn = mat.shape 230 c = outer(ones(rn),arange(cn*1.0)) 231 r = outer(arange(rn*1.0),ones(cn)) 232 233 if type=="wireframe": 234 ax.plot_wireframe(r,c,mat) 235 elif type=="surface": 236 # Sometimes fails for no obvious reason 237 ax.plot_surface(r,c,mat) 238 elif type=="contour": 239 # Works but not usually very useful 240 ax.contour3D(r,c,mat) 241 else: 242 raise ValueError("Unknown plot type "+str(type)) 243 244 ax.set_xlabel('R') 245 ax.set_ylabel('C') 246 ax.set_zlabel('Value') 247 248 self._generate_figure(p)
249 250 251
252 -def matrixplot3d_gnuplot(mat,title=None,outputfilename="tmp.ps"):
253 """ 254 Simple plotting for any matrix as a 3D surface with axes. 255 256 Currently requires the gnuplot-py package to be installed, plus 257 the external gnuplot program; likely to be removed once Matplotlib 258 supports 3D plots better. 259 260 Unlikely to work on non-UNIX systems. 261 262 Should return when it completes, but for some reason the Topographica 263 prompt is not available until this command finishes. 264 """ 265 import Gnuplot 266 import Numeric # ERRORALERT 267 from os import system 268 269 psviewer="gv" # Should be a parameter, or handled better somehow 270 g = Gnuplot.Gnuplot(debug=0) #debug=1: output commands to stderr 271 r,c = mat.shape 272 x = arange(r*1.0) 273 y = arange(c*1.0) 274 # The .tolist() command is necessary to avoid bug in gnuplot-py, 275 # which will otherwise convert a 2D float array into integers (!) 276 m = numpy.asarray(mat,dtype="float32").tolist() 277 #g("set parametric") 278 g("set data style lines") 279 g("set hidden3d") 280 g("set xlabel 'R'") 281 g("set ylabel 'C'") 282 g("set zlabel 'Value'") 283 if title: g.title(title) 284 285 if outputfilename: 286 g("set terminal postscript eps color solid 'Times-Roman' 14") 287 g("set output '"+outputfilename+"'") 288 g.splot(Gnuplot.GridData(m,x,y, binary=1)) 289 #g.hardcopy(outputfilename, enhanced=1, color=1) 290 system(psviewer+" "+outputfilename+" &") 291 292 else: 293 g.splot(Gnuplot.GridData(m,x,y, binary=1)) 294 raw_input('Please press return to continue...\n')
295 296 297
298 -class histogramplot(PylabPlotCommand):
299 """ 300 Compute and plot the histogram of the supplied data. 301 302 See help(pylab.hist) for help on the histogram function itself. 303 304 If given, colors is an iterable collection of matplotlib.colors 305 (see help (matplotlib.colors) ) specifying the bar colors. 306 307 Example use: 308 histogramplot([1,1,1,2,2,3,4,5],title='hist',colors='rgb',bins=3,normed=1) 309 """ 310 311 # JABALERT: All but the first two arguments should probably be Parameters
312 - def __call__(self,data,colors=None,**params):
313 p=ParamOverrides(self,params,allow_extra_keywords=True) 314 315 pylab.figure(figsize=(4,2)) 316 n,bins,bars = pylab.hist(data,**(p.extra_keywords())) 317 318 # if len(bars)!=len(colors), any extra bars won't have their 319 # colors changed, or any extra colors will be ignored. 320 if colors: [bar.set_fc(color) for bar,color in zip(bars,colors)] 321 322 self._generate_figure(p)
323 324 325
326 -class gradientplot(matrixplot):
327 """ 328 Compute and show the gradient plot of the supplied data. 329 Translated from Octave code originally written by Yoonsuck Choe. 330 331 If the data is specified to be cyclic, negative differences will 332 be wrapped into the range specified (1.0 by default). 333 """ 334 335 # JABALERT: All but the first two arguments should probably be Parameters
336 - def __call__(self,data,cyclic=True,cyclic_range=1.0,**params):
337 p=ParamOverrides(self,params) 338 339 r,c = data.shape 340 dx = numpy.diff(data,1,axis=1)[0:r-1,0:c-1] 341 dy = numpy.diff(data,1,axis=0)[0:r-1,0:c-1] 342 343 if cyclic: # Wrap into the specified range 344 # Convert negative differences to an equivalent positive value 345 dx = wrap(0,cyclic_range,dx) 346 dy = wrap(0,cyclic_range,dy) 347 # 348 # Make it increase as gradient reaches the halfway point, 349 # and decrease from there 350 dx = 0.5*cyclic_range-abs(dx-0.5*cyclic_range) 351 dy = 0.5*cyclic_range-abs(dy-0.5*cyclic_range) 352 353 super(gradientplot,self).__call__(sqrt(dx*dx+dy*dy),**p)
354 355 356
357 -class fftplot(matrixplot):
358 """ 359 Compute and show the 2D Fast Fourier Transform (FFT) of the supplied data. 360 361 Example:: fftplot(topo.sim["V1"].sheet_views["OrientationPreference"].view()[0],filename="out") 362 """ 363
364 - def __call__(self,data,**params):
365 p=ParamOverrides(self,params) 366 fft_plot=1-abs(fftshift(fft2(data-0.5, s=None, axes=(-2,-1)))) 367 super(fftplot,self).__call__(fft_plot,**p)
368 369 370
371 -class activityplot(PylabPlotCommand):
372 """ 373 Plots the activity in a sheet. 374 375 Gets plot's extent from sheet.bounds.aarect(). Adds a title and 376 allows the selection of a colormap. If activity is not given, 377 the sheet's current activity is used. 378 """ 379 380 # JABALERT: All but the first two arguments should probably be Parameters 381 # Not sure what this command is for or if anyone is using it.
382 - def __call__(self,sheet,activity=None,cmap=None,**params):
383 p=ParamOverrides(self,params) 384 385 l,b,r,t = sheet.bounds.aarect().lbrt() 386 if activity is None: 387 activity = sheet.activity 388 if cmap is None: 389 cmap=pylab.cm.Greys 390 pylab.imshow(activity, extent=(l,r,b,t),cmap=cmap) 391 392 self._generate_figure(p)
393 394 395
396 -class topographic_grid(PylabPlotCommand):
397 """ 398 By default, plot the XPreference and YPreference preferences for all 399 Sheets for which they are defined, using MatPlotLib. 400 401 If sheet_views other than XPreference and YPreference are desired, 402 the names of these can be passed in as arguments. 403 """ 404 405 xsheet_view_name = param.String(default='XPreference',doc=""" 406 Name of the SheetView holding the X position locations.""") 407 408 ysheet_view_name = param.String(default='YPreference',doc=""" 409 Name of the SheetView holding the Y position locations.""") 410 411 axis = param.Parameter(default=[-0.5,0.5,-0.5,0.5],doc=""" 412 Four-element list of the plot bounds, i.e. [xmin, xmax, ymin, ymax].""") 413
414 - def __call__(self,**params):
415 p=ParamOverrides(self,params) 416 417 for sheet in topo.sim.objects(Sheet).values(): 418 if ((p.xsheet_view_name in sheet.sheet_views) and 419 (p.ysheet_view_name in sheet.sheet_views)): 420 421 x = sheet.sheet_views[p.xsheet_view_name].view()[0] 422 y = sheet.sheet_views[p.ysheet_view_name].view()[0] 423 424 pylab.figure(figsize=(5,5)) 425 426 # This one-liner works in Octave, but in matplotlib it 427 # results in lines that are all connected across rows and columns, 428 # so here we plot each line separately: 429 # pylab.plot(x,y,"k-",transpose(x),transpose(y),"k-") 430 # Here, the "k-" means plot in black using solid lines; 431 # see matplotlib for more info. 432 isint=pylab.isinteractive() # Temporarily make non-interactive for plotting 433 pylab.ioff() 434 for r,c in zip(y,x): 435 pylab.plot(c,r,"k-") 436 for r,c in zip(transpose(y),transpose(x)): 437 pylab.plot(c,r,"k-") 438 439 pylab.xlabel('x') 440 pylab.ylabel('y') 441 # Currently sets the input range arbitrarily; should presumably figure out 442 # what the actual possible range is for this simulation (which would presumably 443 # be the maximum size of any GeneratorSheet?). 444 pylab.axis(p.axis) 445 p.title='Topographic mapping to '+sheet.name+' at time '+topo.sim.timestr() 446 447 if isint: pylab.ion() 448 p.filename_suffix="_"+sheet.name 449 self._generate_figure(p)
450 451
452 -class overlaid_plots(PylabPlotCommand):
453 """ 454 Use matplotlib to make a plot combining a bitmap and line-based overlays. 455 """ 456 457 plot_template = param.List(default=[{'Hue':'OrientationPreference'}],doc=""" 458 Template for the underlying bitmap plot.""") 459 460 overlay = param.List(default=[('contours','OcularPreference',0.5,'black'), 461 ('arrows','DirectionPreference','DirectionSelectivity','white')],doc=""" 462 List of overlaid plots, where each list item may be a 4-tuple 463 specifying either a contour line or a field of arrows:: 464 465 ('contours',map-name,contour-value,line-color) 466 467 ('arrows',arrow-location-map-name,arrow-size-map-name,arrow-color) 468 469 Any number or combination of contours and arrows may be supplied.""") 470 471 normalize = param.Boolean(default='Individually',doc=""" 472 Type of normalization, if any, to use. Options include 'None', 473 'Individually', and 'AllTogether'. See 474 topo.plotting.plotgroup.TemplatePlotGroup.normalize for more 475 details.""") 476 477
478 - def __call__(self,**params):
479 p=ParamOverrides(self,params) 480 481 for template in p.plot_template: 482 483 for sheet in topo.sim.objects(Sheet).values(): 484 name=template.keys().pop(0) 485 plot=make_template_plot(template,sheet.sheet_views,sheet.xdensity,sheet.bounds,p.normalize,name=template[name]) 486 if plot: 487 bitmap=plot.bitmap 488 pylab.figure(figsize=(5,5)) 489 isint=pylab.isinteractive() # Temporarily make non-interactive for plotting 490 pylab.ioff() # Turn interactive mode off 491 492 pylab.imshow(bitmap.image,origin='lower',interpolation='nearest') 493 pylab.axis('off') 494 495 for (t,pref,sel,c) in p.overlay: 496 v = pylab.flipud(sheet.sheet_views[pref].view()[0]) 497 498 if (t=='contours'): 499 pylab.contour(v,[sel,sel],colors=c,linewidths=2) 500 501 if (t=='arrows'): 502 s = pylab.flipud(sheet.sheet_views[sel].view()[0]) 503 scale=int(pylab.ceil(log10(len(v)))) 504 X=pylab.array([x for x in xrange(len(v)/scale)]) 505 v_sc=pylab.zeros((len(v)/scale,len(v)/scale)) 506 s_sc=pylab.zeros((len(v)/scale,len(v)/scale)) 507 for i in X: 508 for j in X: 509 v_sc[i][j]=v[scale*i][scale*j] 510 s_sc[i][j]=s[scale*i][scale*j] 511 pylab.quiver(scale*X,scale*X,-cos(2*pi*v_sc)*s_sc,-sin(2*pi*v_sc)*s_sc,color=c,edgecolors=c,minshaft=3,linewidths=1) 512 513 p.title='%s overlaid with %s at time %s' %(plot.name,pref,topo.sim.timestr()) 514 if isint: pylab.ion() 515 p.filename_suffix="_"+sheet.name 516 self._generate_figure(p)
517 518 519
520 -class tuning_curve(PylabPlotCommand):
521 """ 522 Plot a tuning curve for a feature, such as orientation, contrast, or size. 523 524 The curve datapoints are collected from the curve_dict for 525 the units at the specified coordinates in the specified sheet 526 (where the units and sheet may be set by a GUI, using 527 topo.analysis.featureresponses.UnitCurveCommand.sheet and 528 topo.analysis.featureresponses.UnitCurveCommand.coords, 529 or by hand). 530 """ 531 532 coords = param.List(default=[(0,0)],doc=""" 533 List of coordinates of units to measure.""") 534 535 sheet = param.ObjectSelector( 536 default=None,doc=""" 537 Name of the sheet to use in measurements.""") 538 539 x_axis = param.String(default="",doc=""" 540 Feature to plot on the x axis of the tuning curve""") 541 542 # Can we list some alternatives here, if there are any 543 # useful ones? 544 plot_type = param.Callable(default=pylab.plot,doc=""" 545 Matplotlib command to generate the plot.""") 546 547 unit = param.String(default="",doc=""" 548 String to use in labels to specify the units in which curves are plotted.""") 549 550 __abstract = True 551 552
553 - def _format_x_tick_label(self,x):
554 return "%3.1f" % x
555
556 - def _rotate(self, seq, n=1):
557 n = n % len(seq) # n=hop interval 558 return seq[n:] + seq[:n]
559
560 - def _curve_values(self, i_value, j_value, curve):
561 """Return the x, y, and x ticks values for the specified curve from the curve_dict""" 562 x_values=sorted(curve.keys()) 563 y_values=[curve[key].view()[0][i_value,j_value] for key in x_values] 564 return x_values,y_values,x_values
565
566 - def _reduce_ticks(self,ticks):
567 x = []; 568 y= []; 569 num_ticks = 5; 570 y.append(ticks[0]) 571 x.append(0) 572 for i in xrange(0,num_ticks): 573 y.append(y[-1]+numpy.pi/(num_ticks+1)); 574 x.append(x[-1]+numpy.pi/(num_ticks+1)); 575 y.append(y[-1]+numpy.pi/(num_ticks+1)); 576 x.append(3.14) 577 return (x,y)
578 579
580 - def __call__(self,**params):
581 p=ParamOverrides(self,params) 582 sheet = p.sheet 583 for coordinate in p.coords: 584 i_value,j_value=sheet.sheet2matrixidx(coordinate[0],coordinate[1]) 585 586 f = pylab.figure(figsize=(7,7)) 587 isint=pylab.isinteractive() 588 pylab.ioff() 589 590 pylab.ylabel('Response',fontsize='large') 591 pylab.xlabel('%s (%s)' % (p.x_axis.capitalize(),p.unit),fontsize='large') 592 pylab.title('Sheet %s, coordinate(x,y)=(%0.3f,%0.3f) at time %s' % 593 (sheet.name,coordinate[0],coordinate[1],topo.sim.timestr())) 594 p.title='%s: %s Tuning Curve' % (topo.sim.name,p.x_axis.capitalize()) 595 596 self.first_curve=True 597 for curve_label in sorted(sheet.curve_dict[p.x_axis].keys()): 598 x_values,y_values,ticks=self._curve_values(i_value,j_value,sheet.curve_dict[p.x_axis][curve_label]) 599 600 x_tick_values,ticks = self._reduce_ticks(ticks) 601 labels = [self._format_x_tick_label(x) for x in ticks] 602 pylab.xticks(x_tick_values, labels,fontsize='large') 603 pylab.yticks(fontsize='large') 604 p.plot_type(x_values, y_values, label=curve_label,lw=3.0) 605 self.first_curve=False 606 607 if isint: pylab.ion() 608 pylab.legend(loc=2) 609 self._generate_figure(p)
610 611 612
613 -class cyclic_tuning_curve(tuning_curve):
614 """ 615 Same as tuning_curve, but rotates the curve so that minimum y 616 values are at the minimum x value to make the plots easier to 617 interpret. Such rotation is valid only for periodic quantities 618 like orientation or direction, and only if the correct period 619 is set. 620 621 At present, the y_values and labels are rotated by an amount 622 determined by the minmum y_value for the first curve plotted 623 (usually the lowest contrast curve). 624 """ 625 626 cyclic_range = param.Number(default=pi,bounds=(0,None),softbounds=(0,10),doc=""" 627 Range of the cyclic quantity (e.g. pi for the orientation of 628 a symmetric stimulus, or 2*pi for motion direction or the 629 orientation of a non-symmetric stimulus).""") 630 631 unit = param.String(default="degrees",doc=""" 632 String to use in labels to specify the units in which curves are plotted.""") 633 634 635 # This implementation should work for quantities periodic with 636 # some multiple of pi that we want to express in degrees, but it 637 # will need to be reimplemented in a subclass to work with other 638 # cyclic quantities.
639 - def _format_x_tick_label(self,x):
640 return str(int(180*x/pi))
641 642
643 - def _curve_values(self, i_value, j_value, curve):
644 """ 645 Return the x, y, and x ticks values for the specified curve from the curve_dict. 646 647 With the current implementation, there may be cases (i.e., 648 when the lowest contrast curve gives a lot of zero y_values) 649 in which the maximum is not in the center. This may 650 eventually be changed so that the preferred orientation is in 651 the center. 652 """ 653 if self.first_curve==True: 654 x_values= sorted(curve.keys()) 655 y_values=[curve[key].view()[0][i_value,j_value] for key in x_values] 656 657 min_arg=argmin(y_values) 658 x_min=x_values[min_arg] 659 y_min=y_values[min_arg] 660 y_values=self._rotate(y_values, n=min_arg) 661 self.ticks=self._rotate(x_values, n=min_arg) 662 self.ticks+=[x_min] 663 x_max=min(x_values)+self.cyclic_range 664 x_values.append(x_max) 665 y_values.append(y_min) 666 667 self.x_values=x_values 668 else: 669 y_values=[curve[key].view()[0][i_value,j_value] for key in self.ticks] 670 671 return self.x_values,y_values,self.ticks
672 673 674
675 -def plot_cfproj_mapping(dest,proj='Afferent',style='b-'):
676 """ 677 Given a CF sheet receiving a CFProjection, plot 678 the mapping of the dests CF centers on the src sheet. 679 """ 680 if isinstance(dest,str): 681 from topo import sim 682 dest = sim[dest] 683 plot_coord_mapping(dest.projections()[proj].coord_mapper, 684 dest,style=style)
685 686 687 # JABALERT: not sure whether this is currently used
688 -def plot_coord_mapping(mapper,sheet,style='b-'):
689 """ 690 Plot a coordinate mapping for a sheet. 691 692 Given a CoordinateMapperFn (as for a CFProjection) and a sheet 693 of the projection, plot a grid showing where the sheet's units 694 are mapped. 695 """ 696 697 from pylab import plot,hold,ishold 698 699 xs = sheet.sheet_rows() 700 ys = sheet.sheet_cols() 701 702 hold_on = ishold() 703 if not hold_on: 704 plot() 705 hold(True) 706 707 for y in ys: 708 pts = [mapper(x,y) for x in xs] 709 plot([u for u,v in pts], 710 [v for u,v in pts], 711 style) 712 713 for x in xs: 714 pts = [mapper(x,y) for y in ys] 715 plot([u for u,v in pts], 716 [v for u,v in pts], 717 style) 718 719 hold(hold_on)
720 721 722 # JABALERT: Untested as of Mon Nov 10 12:59:54 GMT 2008
723 -class plot_tracked_attributes(PylabPlotCommand):
724 """ 725 Plots parameter values associated with an AttributeTrackingTF. 726 Example call: 727 VT=AttributeTrackingTF(function=HE, debug_params=['a', 'b',], units=[(0,0),(1,1)], step=1) 728 plot_tracked_attributes(VT,0,10000,attrib_names=['a'],units=[(0,0)], filename='V1') 729 """ 730 731 # JABALERT: These parameters need to be documented. 732 raw = param.Boolean(default=False) 733 734 attrib_names = param.List(default=[]) 735 736 ylabel = param.String(default="") 737 738 # Should be renamed to coords to match other commands 739 units = param.List(default=[]) 740 741 ybounds = param.Parameter(default=(None,None)) 742 743 744 # JABALERT: All but the first two arguments should probably be Parameters
745 - def __call__(self,output_fn,init_time=0,final_time=None,**params):
746 p=ParamOverrides(self,params) 747 748 if final_time is None: 749 final_time=topo.sim.time() 750 751 attrs = p.attrib_names if len(p.attrib_names)>0 else output_fn.attrib_names 752 for a in attrs: 753 pylab.figure(figsize=(6,4)) 754 isint=pylab.isinteractive() 755 pylab.ioff() 756 pylab.grid(True) 757 ylabel=p.ylabel 758 pylab.ylabel(a+" "+ylabel) 759 pylab.xlabel('Iteration Number') 760 761 coords = p.units if len(p.units)>0 else output_fn.units 762 for coord in coords: 763 y_data=[y for (x,y) in output_fn.values[a][coord]] 764 x_data=[x for (x,y) in output_fn.values[a][coord]] 765 if p.raw==True: 766 plot_data=zip(x_data,y_data) 767 pylab.save(normalize_path(p.filename+a+'(%.2f, %.2f)' %(coord[0], coord[1])),plot_data,fmt='%.6f', delimiter=',') 768 769 770 pylab.plot(x_data,y_data, label='Unit (%.2f, %.2f)' %(coord[0], coord[1])) 771 (ymin,ymax)=p.ybounds 772 pylab.axis(xmin=init_time,xmax=final_time,ymin=ymin,ymax=ymax) 773 774 if isint: pylab.ion() 775 pylab.legend(loc=0) 776 p.title=topo.sim.