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

Source Code for Module topo.command.pylabplot

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