Package Vision :: Module matplotlibNodes
[hide private]
[frames] | no frames]

Source Code for Module Vision.matplotlibNodes

   1  ######################################################################### 
   2  # 
   3  # Date: Dec 2004 Authors: Michel Sanner 
   4  # 
   5  #    sanner@scripps.edu 
   6  # 
   7  #       The Scripps Research Institute (TSRI) 
   8  #       Molecular Graphics Lab 
   9  #       La Jolla, CA 92037, USA 
  10  # 
  11  # Copyright: Michel Sanner, and TSRI 
  12  # 
  13  ######################################################################### 
  14   
  15  # latest working version of matplotlib is 0.87.7 using numpy 1.0.3 
  16  # latest working version of matplotlib is 0.87.6 using Numeric 23.8 
  17  # (matplotlib 0.87.7 has a small bug using Numeric 23.8) 
  18  # there are multiple bugs in matplotlib when using Numeric 24.2 
  19   
  20  #TODO: 
  21  # - add and verify controls such as size, labels, legends etc 
  22  # - maybe encapsulate all these common options into a single node 
  23  # - alpha values per axis 
  24  # - use axes rather than subplot 
  25  # 
  26   
  27  from mglutil.util.callback import CallBackFunction 
  28  from NetworkEditor.widgets import TkPortWidget, PortWidget 
  29  import Pmw,math,os 
  30  from matplotlib.colors import cnames 
  31  from matplotlib.lines import Line2D,lineStyles,TICKLEFT, TICKRIGHT, TICKUP, TICKDOWN 
  32  from matplotlib.transforms import Value 
  33  from matplotlib import rcParams 
  34  from mglutil.gui.BasicWidgets.Tk.thumbwheel import ThumbWheel 
  35  from Numeric import array 
  36  """ 
  37  This module implements Vision nodes exposing matplotlib functionatility. 
  38   
  39  MPLBaseNE: 
  40  --------- 
  41  The class provides a base class for all nodes exposing matplotlib functionality 
  42   
  43  its purpose is to to create the attributes described below and implement 
  44  methods shared by all nodes. 
  45   
  46  Attributes: 
  47      self.figure = None:  # node's figure object 
  48      # This attribute always points to the matplotlib Figure object which has 
  49      # a FigureCanvasTkAgg object in its .canvas attribute 
  50   
  51      # self.canvas FigureCanvasTkAgg 
  52   
  53      self.axes = None 
  54      # This attribute points to the matplotlib Axes instance used by this node 
  55   
  56      self.axes.figure # figure in which the axes is currently drawn 
  57   
  58  Methods:         
  59      def createFigure(self, master=None, width=None, height=None, dpi=None, 
  60                       facecolor=None, edgecolor=None, frameon=None, 
  61                       packOpts=None, toolbar=True): 
  62   
  63      # This method is used by all nodes if they need to create a Figure object 
  64      # from the matplotlib library and a FigureCanvasTkAgg object for this 
  65      # figure. 
  66   
  67      def setFigure(self, figure): 
  68      # This method place the node's axes object into the right Figure 
  69              
  70   
  71      def beforeRemovingFromNetwork(self): 
  72      # this method is called when a node is deleted from a network.  Its job is 
  73      # to delete FigureCanvasTkAgg and Axes when appropriate. 
  74       
  75   
  76  MPLFigure: 
  77  ----------- 
  78  The MPLFigure node allows the creation of a plotting area in which one 
  79  or more Axes can be added, where an Axes is a 2D graphical representation 
  80  of a data set (i.e. 2D plot).  A 'master' can be apecified to embed the figure 
  81  in other panels.  This node provides control over parameter that apply to the 
  82  MPLFigure such, width, height, dpi, etc. 
  83   
  84   
  85  Plotting Node: 
  86  ------------- 
  87  Plotting nodes such as Histogram, Plot, Scatter, Pie, etc. take adtasets and 
  88  render them as 2D plots.  They alwas own the axes. 
  89  If the data to be rendered is the only input to these nodes, they will create 
  90  a default Figure, add a default Plot2D to this figure, and draw the data in 
  91  this default 2D plot. 
  92  """ 
  93   
  94  from Vision import UserLibBuild 
  95  from NetworkEditor.items import NetworkNode 
  96   
  97  import Tkinter 
  98  import matplotlib 
  99  import types 
 100  import weakref 
 101   
 102   
 103  # make sure Tk is used as a backend 
 104  matplotlib.use('TkAgg') 
 105   
 106  from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg 
 107  from matplotlib.backends.backend_tkagg import NavigationToolbar2TkAgg 
 108  from matplotlib.figure import Figure as OriginalFigure 
 109  from matplotlib.axes import Axes, Subplot, PolarSubplot, PolarAxes 
 110  from matplotlib.pylab import * 
 111  from Vision.colours import get_colours 
 112  from Vision.posnegFill import posNegFill 
 113  from matplotlib import numerix 
 114  from matplotlib.artist import setp 
 115  ## 
 116  ##  QUESTIONS 
 117  ##  Does this have to be Tk specific or could I use FigureCanvasAgg 
 118  ##  !FigureCanvasAgg is OK 
 119   
 120  ##  Should I use FigureManagerBase rather than FigureCanvasAgg ? 
 121  ##  ! FigureCanvas Agg is OK 
 122   
 123  ##  how to destroy a figure ? 
 124  ##  ! seems to work 
 125   
 126  ##  figure should have a set_dpi method 
 127  ##  ! use figure.dpi.set() for now but might become API later 
 128   
 129  ##  how to remove the tool bar ? 
 130  ##  ! John added a note about this 
 131   
 132  ##  What option in a Figure can beset without destroying the Figure 
 133  ##    and which ones are constructor only options ? 
 134  ##  ! nothing should require rebuilding a Figure 
 135   
 136  ##  Why does add_axes return the axis that already exists if the values for 
 137  ##    building the Axes object are the same ? either this has to change or 
 138  ##    adding an instance of an Axes should be fixed (prefered) 
 139  ##  !John made a note to add an argument to matplotlib 
 140   
 141  ##  Pie seems to have a problem when shadow is on ! 
 142  ##  !Find out the problem, because shadows are on even when check button is off 
 143  ##  !for ce aspect ratio to square 
 144   
 145  ##  Plot lineStyle, color, linewidth etc should be set by a set node that uses 
 146  ##    introspection on the patch? to find otu what can be set ?? 
 147  ## !Use ObjectInspector 
 148   
 149  ## why is figimage not an axes method ? 
 150  ## !use imshow 
 151   
 152  from matplotlib.cbook import iterable, popd 
 153  try: 
 154      from matplotlib.dates import DayLocator, HourLocator, \ 
 155       drange, date2num, timezone 
 156  except: 
 157      pass 
 158  try: 
 159      from pytz import common_timezones 
 160  except: 
 161      common_timezones=[] 
 162  #global variables 
 163  locations={'best' : 0, 
 164            'upper right'  : 1,  
 165            'upper left'   : 2, 
 166            'lower left'   : 3, 
 167            'lower right'  : 4, 
 168            'right'        : 5, 
 169            'center left'  : 6, 
 170            'center right' : 7, 
 171            'lower center' : 8, 
 172            'upper center' : 9, 
 173            'center'       : 10,} 
 174  colors={ 
 175          'blue' : 'b', 
 176          'green' : 'g', 
 177          'red' : 'r', 
 178          'cyan' : 'c', 
 179          'magenta' :'m', 
 180          'yellow' :'y', 
 181          'black': 'k', 
 182          'white' : 'w', 
 183          }           
 184   
 185  markers= { 
 186                  'square'         :  's', 
 187                  'circle'         :  'o', 
 188                  'triangle up'    :  '^', 
 189                  'triangle right' :  '>', 
 190                  'triangle down'  :  'v', 
 191                  'triangle left'  :  '<', 
 192                  'diamond'        :  'd', 
 193                  'pentagram'      :  'p', 
 194                  'hexagon'        :  'h', 
 195                  'octagon'        :  '8', 
 196                  } 
 197    
 198  cmaps=['autumn','bone', 'cool','copper','flag','gray','hot','hsv','jet','pink', 'prism', 'spring', 'summer', 'winter'] 
 199   
200 -def get_styles():
201 styles={} 202 for ls in Line2D._lineStyles.keys(): 203 styles[Line2D._lineStyles[ls][6:]]=ls 204 for ls in Line2D._markers.keys(): 205 styles[Line2D._markers[ls][6:]]=ls 206 #these styles are not recognized 207 if styles.has_key('steps'): 208 del styles['steps'] 209 for s in styles.keys(): 210 if s =="nothing": 211 del styles['nothing'] 212 if s[:4]=='tick': 213 del styles[s] 214 return styles
215
216 -class Figure(OriginalFigure):
217 218 # sub class Figure to override add_axes
219 - def add_axes(self, *args, **kwargs):
220 """hack to circumvent the issue of not adding an axes if the constructor 221 params have already been seen""" 222 223 if kwargs.has_key('force'): 224 force = kwargs['force'] 225 del kwargs['force'] 226 else: 227 force = False 228 229 if iterable(args[0]): 230 key = tuple(args[0]), tuple(kwargs.items()) 231 else: 232 key = args[0], tuple(kwargs.items()) 233 234 if not force and self._seen.has_key(key): 235 ax = self._seen[key] 236 self.sca(ax) 237 return ax 238 239 if not len(args): return 240 if isinstance(args[0], Axes): 241 a = args[0] 242 # this is too early, if done here bbox is 0->1 243 #a.set_figure(self) 244 a.figure = self 245 else: 246 rect = args[0] 247 ispolar = popd(kwargs, 'polar', False) 248 249 if ispolar: 250 a = PolarAxes(self, rect, **kwargs) 251 else: 252 a = Axes(self, rect, **kwargs) 253 254 self.axes.append(a) 255 self._axstack.push(a) 256 self.sca(a) 257 self._seen[key] = a 258 return a
259 260 261
262 -class MPLBaseNE(NetworkNode):
263 """Base class for node wrapping the maptlotlib objects 264 265 """
266 - def __init__(self, name='MPLBase', **kw):
267 kw['name'] = name 268 apply( NetworkNode.__init__, (self,), kw ) 269 270 self.figure = None # matplotlib Figure instance belonging to this node 271 self.axes = None # matplotlib Axes instance 272 273 # this is true for Figures who create the Tk Toplevel 274 # or plotting nodes that have no figure parent node 275 # it is used to decide when the Toplevel should be destroyed 276 self.ownsMaster = False
277 278
279 - def setDrawArea(self, kw):
280 ax = self.axes 281 #ax.clear() 282 if kw.has_key('left'): 283 rect = [kw['left'], kw['bottom'], kw['width'], kw['height']] 284 ax.set_position(rect) 285 if kw.has_key('frameon'): 286 ax.set_frame_on(kw['frameon']) 287 288 if kw.has_key("title"): 289 if type(kw['title'])==types.StringType: 290 ax.set_title(kw['title']) 291 else: 292 print 'Set title as Object' 293 if kw.has_key("xlabel"): 294 ax.set_xlabel(kw['xlabel']) 295 if kw.has_key("ylabel"): 296 ax.set_ylabel(kw['ylabel']) 297 if kw.has_key("xlimit"): 298 if kw['xlimit']!='': 299 ax.set_xlim(eval(kw['xlimit'])) 300 if kw.has_key("ylimit"): 301 if kw['ylimit']!='': 302 ax.set_ylim(eval(kw['ylimit'])) 303 if kw.has_key("xticklabels"): 304 if not kw['xticklabels']: 305 ax.set_xticklabels([]) 306 if kw.has_key("yticklabels"): 307 if not kw['yticklabels']: 308 ax.set_yticklabels([]) 309 if kw.has_key("axison"): 310 if kw['axison']: 311 ax.set_axis_on() 312 else: 313 ax.set_axis_off() 314 if kw.has_key("autoscaleon"): 315 if kw['autoscaleon']: 316 ax.set_autoscale_on(True) 317 else: 318 ax.set_autoscale_on(False) 319 if kw.has_key("adjustable"): 320 ax.set_adjustable(kw['adjustable']) 321 if kw.has_key("aspect"): 322 ax.set_aspect(kw['aspect']) 323 if kw.has_key("anchor"): 324 ax.set_anchor(kw['anchor']) 325 326 if kw.has_key("axisbelow"): 327 if kw['axisbelow']==1: 328 val=True 329 else: 330 val=False 331 rcParams['axes.axisbelow']=val 332 ax.set_axisbelow(val) 333 #grid properties 334 if kw.has_key("gridOn"): 335 if kw['gridOn']==1: 336 ax._gridOn=True 337 val=True 338 if kw.has_key('gridcolor'): 339 gcolor=kw['gridcolor'] 340 else: 341 gcolor=rcParams['grid.color'] 342 if kw.has_key('gridlinestyle'): 343 glinestyle=kw['gridlinestyle'] 344 else: 345 glinestyle=rcParams['grid.linestyle'] 346 if kw.has_key('gridlinewidth'): 347 glinewidth=kw['gridlinewidth'] 348 else: 349 glinewidth=rcParams['grid.linewidth'] 350 if kw.has_key('whichgrid'): 351 whichgrid=kw['whichgrid'] 352 else: 353 whichgrid='major' 354 ax.grid(val,color=gcolor, linestyle=glinestyle, linewidth=glinewidth,which=whichgrid) 355 else: 356 val=False 357 ax.grid(val) 358 359 if kw.has_key("facecolor"): 360 ax.set_axis_bgcolor(kw['facecolor']) 361 if kw.has_key("edgecolor"): 362 ax.axesFrame.set_color(kw['edgecolor']) 363 if kw.has_key('zoomx'): 364 #Zoom in on the x xaxis numsteps (plus for zoom in, minus for zoom out) 365 ax.zoomx(kw['zoomx']) 366 367 if kw.has_key('zoomy'): 368 #Zoom in on the x xaxis numsteps (plus for zoom in, minus for zoom out) 369 ax.zoomy(kw['zoomy']) 370 371 if kw.has_key("xtick.color"): 372 for i in ax.xaxis.get_ticklabels(): 373 i.set_color(kw['xtick.color']) 374 if kw.has_key("ytick.color"): 375 for i in ax.yaxis.get_ticklabels(): 376 i.set_color(kw['ytick.color']) 377 378 if kw.has_key('xtick.labelrotation'): 379 for i in ax.xaxis.get_ticklabels(): 380 i.set_rotation(float(kw['xtick.labelrotation'])) 381 if kw.has_key('ytick.labelrotation'): 382 for i in ax.yaxis.get_ticklabels(): 383 i.set_rotation(float(kw['ytick.labelrotation'])) 384 if kw.has_key("xtick.labelsize"): 385 for i in ax.xaxis.get_ticklabels(): 386 i.set_size(float(kw['xtick.labelsize'])) 387 if kw.has_key("ytick.labelsize"): 388 for i in ax.yaxis.get_ticklabels(): 389 i.set_size(float(kw['ytick.labelsize'])) 390 if kw.has_key("linewidth"): 391 ax.axesFrame.set_linewidth(float(kw['linewidth'])) 392 393 #marker 394 if kw.has_key("markeredgewidth"): 395 for i in ax.get_xticklines(): 396 i.set_markeredgewidth(kw['markeredgewidth']) 397 for i in ax.get_yticklines(): 398 i.set_markeredgewidth(kw['markeredgewidth']) 399 400 if kw.has_key("markeredgecolor"): 401 for i in ax.get_xticklines(): 402 i.set_markeredgecolor(kw['markeredgecolor']) 403 for i in ax.get_yticklines(): 404 i.set_markeredgecolor(kw['markeredgecolor']) 405 406 if kw.has_key("markerfacecolor"): 407 for i in ax.get_xticklines(): 408 i.set_markerfacecolor(kw['markerfacecolor']) 409 for i in ax.get_yticklines(): 410 i.set_markerfacecolor(kw['markerfacecolor']) 411 412 #figure_patch properties 413 if kw.has_key("figpatch_linewidth"): 414 ax.figure.figurePatch.set_linewidth(kw['figpatch_linewidth']) 415 if kw.has_key("figpatch_facecolor"): 416 ax.figure.figurePatch.set_facecolor(kw['figpatch_facecolor']) 417 if kw.has_key("figpatch_edgecolor"): 418 ax.figure.figurePatch.set_edgecolor(kw['figpatch_edgecolor']) 419 if kw.has_key("figpatch_antialiased"): 420 ax.figure.figurePatch.set_antialiased(kw['figpatch_antialiased']) 421 422 #Text properties 423 if kw.has_key('text'): 424 for i in kw['text']: 425 if type(i)==types.DictType: 426 tlab=i['textlabel'] 427 posx=i['posx'] 428 posy=i['posy'] 429 horizontalalignment=i['horizontalalignment'] 430 verticalalignment=i['verticalalignment'] 431 rotation=i['rotation'] 432 ax.text(x=posx,y=posy,s=tlab,horizontalalignment=horizontalalignment,verticalalignment=verticalalignment,rotation=rotation,transform = ax.transAxes) 433 if kw.has_key("text.color"): 434 for t in ax.texts: 435 t.set_color(kw['text.color']) 436 if kw.has_key("text.usetex"): 437 rcParams['text.usetex']=kw['text.usetex'] 438 if kw.has_key("text.dvipnghack"): 439 rcParams['text.dvipnghack']=kw['text.dvipnghack'] 440 if kw.has_key("text.fontstyle"): 441 for t in ax.texts: 442 t.set_fontstyle(kw['text.fontstyle']) 443 if kw.has_key("text.fontangle"): 444 for t in ax.texts: 445 t.set_fontangle(kw['text.fontangle']) 446 if kw.has_key("text.fontvariant"): 447 for t in ax.texts: 448 t.set_fontvariant(kw['text.fontvariant']) 449 if kw.has_key("text.fontweight"): 450 for t in ax.texts: 451 t.set_fontweight(kw['text.fontweight']) 452 if kw.has_key("text.fontsize"): 453 for t in ax.texts: 454 t.set_fontsize(kw['text.fontsize']) 455 456 #Font 457 if kw.has_key("Font.fontfamily"): 458 for t in ax.texts: 459 t.set_family(kw['Font.fontfamily']) 460 if kw.has_key("Font.fontstyle"): 461 for t in ax.texts: 462 t.set_fontstyle(kw['Font.fontstyle']) 463 if kw.has_key("Font.fontangle"): 464 for t in ax.texts: 465 t.set_fontangle(kw['Font.fontangle']) 466 if kw.has_key("Font.fontvariant"): 467 for t in ax.texts: 468 t.set_fontvariant(kw['Font.fontvariant']) 469 if kw.has_key("Font.fontweight"): 470 for t in ax.texts: 471 t.set_fontweight(kw['Font.fontweight']) 472 if kw.has_key("Font.fontsize"): 473 for t in ax.texts: 474 t.set_fontsize(kw['Font.fontsize']) 475 476 #Legend Properties 477 if kw.has_key('legendlabel'): 478 if ',' in kw['legendlabel']: 479 x=kw['legendlabel'].split(",") 480 else: 481 x=(kw['legendlabel'],) 482 if kw.has_key('legend.isaxes'): 483 isaxes=kw['legend.isaxes'] 484 else: 485 isaxes=rcParams['legend.isaxes'] 486 487 if kw.has_key('legend.numpoints'): 488 numpoints=kw['legend.numpoints'] 489 else: 490 numpoints=rcParams['legend.numpoints'] 491 492 if kw.has_key('legend.pad'): 493 pad=kw['legend.pad'] 494 else: 495 pad=rcParams['legend.pad'] 496 497 if kw.has_key('legend.markerscale'): 498 markerscale=kw['legend.markerscale'] 499 else: 500 markerscale=rcParams['legend.markerscale'] 501 if kw.has_key('legend.labelsep'): 502 labelsep=kw['legend.labelsep'] 503 else: 504 labelsep=rcParams['legend.labelsep'] 505 if kw.has_key('legend.handlelen'): 506 handlelen=kw['legend.handlelen'] 507 else: 508 handlelen=rcParams['legend.handlelen'] 509 if kw.has_key('legend.handletextsep'): 510 handletextsep=kw['legend.handletextsep'] 511 else: 512 handletextsep=rcParams['legend.handletextsep'] 513 if kw.has_key('legend.axespad'): 514 axespad=kw['legend.axespad'] 515 else: 516 axespad=rcParams['legend.axespad'] 517 if kw.has_key('legend.shadow'): 518 shadow=kw['legend.shadow'] 519 else: 520 shadow=rcParams['legend.shadow'] 521 leg=self.axes.legend(tuple(x),loc=kw['legendlocation'],isaxes=isaxes,numpoints=numpoints,pad=pad,labelsep=labelsep,handlelen=handlelen,handletextsep=handletextsep,axespad=axespad,shadow=shadow,markerscale=markerscale) 522 if kw.has_key('legend.fontsize'): 523 setp(ax.get_legend().get_texts(),fontsize=kw['legend.fontsize']) 524 525 #Tick Options 526 if kw.has_key('xtick.major.pad'): 527 for i in ax.xaxis.majorTicks: 528 i.set_pad(kw['xtick.major.pad']) 529 if kw.has_key('xtick.minor.pad'): 530 for i in ax.xaxis.minorTicks: 531 i.set_pad(kw['xtick.minor.pad']) 532 if kw.has_key('ytick.major.pad'): 533 for i in ax.yaxis.majorTicks: 534 i.set_pad(kw['ytick.major.pad']) 535 if kw.has_key('ytick.minor.pad'): 536 for i in ax.yaxis.minorTicks: 537 i.set_pad(kw['ytick.minor.pad']) 538 if kw.has_key('xtick.major.size'): 539 rcParams['xtick.major.size']=kw['xtick.major.size'] 540 if kw.has_key('xtick.minor.size'): 541 rcParams['xtick.minor.size']=kw['xtick.minor.size'] 542 if kw.has_key('xtick.direction'): 543 rcParams['xtick.direction']=kw['xtick.direction'] 544 if kw.has_key('ytick.major.size'): 545 rcParams['ytick.major.size']=kw['ytick.major.size'] 546 if kw.has_key('ytick.minor.size'): 547 rcParams['ytick.minor.size']=kw['ytick.minor.size'] 548 if kw.has_key('ytick.direction'): 549 rcParams['ytick.direction']=kw['ytick.direction']
550 551 552
553 - def beforeRemovingFromNetwork(self):
554 #print 'remove' 555 NetworkNode.beforeRemovingFromNetwork(self) 556 # this happens for drawing nodes with no axes specified 557 if self.axes: 558 559 self.axes.figure.delaxes(self.axes) # feel a little strange ! 560 self.canvas._tkcanvas.master.destroy() 561 elif self.canvas: 562 self.canvas._tkcanvas.master.destroy()
563 564
565 - def onlyDataChanged(self, data):
566 """returns true if only he first port (i.e. data) has new data. 567 """ 568 # This can be used to accelerate redraw by only updating the data 569 # rather than redrawing the whole figure 570 # see examples/animation_blit_tk.py 571 ports = self.inputPorts 572 if not ports[0].hasNewData(): 573 return False 574 for p in self.inputPorts: 575 if p.hasNewData(): 576 return False 577 578 return True
579 580 581
582 -class MPLFigureNE(MPLBaseNE):
583 """This node instanciates a Figure object and its FigureCanvasTkAgg object 584 in its .canvas attribute. 585 It also provide control over parameters such as width, height, dpi, etc. 586 587 Input: 588 plots - Matplotlib Axes objects 589 figwidth - width in inches 590 figheigh - height in inches 591 dpi - resolution; defaults to rc figure.dpi 592 facecolor - the background color; defaults to rc figure.facecolor 593 edgecolor - the border color; defaults to rc figure.edgecolor 594 master - Defaults to None, creating a topLevel 595 nbRows - number of rows for subgraph2D 596 nbColumns - number of columns for subgraph2D 597 frameon - boolean 598 hold - boolean 599 toolbar - boolean (init option only) 600 packOpts - string representation of packing options 601 602 Output: 603 canvas: MPLFigure Object 604 605 Todo: 606 legend 607 text 608 image ? 609 """ 610
611 - def afterAddingToNetwork(self):
612 self.figure = Figure() 613 614 master = Tkinter.Toplevel() 615 master.title(self.name) 616 self.canvas = FigureCanvasTkAgg(self.figure, master) 617 self.figure.set_canvas(self.canvas) 618 619 packOptsDict = {'side':'top', 'fill':'both', 'expand':1} 620 self.canvas.get_tk_widget().pack( *(), **packOptsDict ) 621 622 toolbar = NavigationToolbar2TkAgg(self.canvas, master)
623 624
625 - def __init__(self, name='Figure2', **kw):
626 kw['name'] = name 627 apply( MPLBaseNE.__init__, (self,), kw ) 628 629 codeBeforeDisconnect = """def beforeDisconnect(self, c): 630 node1 = c.port1.node 631 node2 = c.port2.node 632 if node2.figure.axes: 633 node2.figure.delaxes(node1.axes) 634 if node1.figure.axes: 635 node1.figure.delaxes(node1.axes) 636 node1.figure.add_axes(node1.axes) 637 """ 638 ip = self.inputPortsDescr 639 ip.append(datatype='MPLAxes', required=False, name='plots', 640 singleConnection=False, 641 beforeDisconnect=codeBeforeDisconnect) 642 ip.append(datatype='float', required=False, name='width') 643 ip.append(datatype='float', required=False, name='height') 644 ip.append(datatype='float', required=False, name='linewidth') 645 ip.append(datatype='int', required=False, name='dpi') 646 ip.append(datatype='colorRGB', required=False, name='facecolor') 647 ip.append(datatype='colorRGB', required=False, name='edgecolor') 648 ip.append(datatype='None', required=False, name='master') 649 ip.append(datatype='int', required=False, name='nbRows') 650 ip.append(datatype='int', required=False, name='nbColumns') 651 ip.append(datatype='boolean', required=False, name='frameon') 652 ip.append(datatype='boolean', required=False, name='hold') 653 ip.append(datatype='boolean', required=False, name='toolbar') 654 ip.append(datatype='None', required=False, name='packOpts') 655 656 op = self.outputPortsDescr 657 op.append(datatype='MPLFigure', name='figure') 658 659 self.widgetDescr['width'] = { 660 'class':'NEThumbWheel','master':'ParamPanel', 661 'width':75, 'height':21, 'oneTurn':2, 'type':'float', 662 'wheelPad':2, 'initialValue':8.125, 663 'labelCfg':{'text':'width in inches'} } 664 665 self.widgetDescr['height'] = { 666 'class':'NEThumbWheel','master':'ParamPanel', 667 'width':75, 'height':21, 'oneTurn':2, 'type':'float', 668 'wheelPad':2, 'initialValue':6.125, 669 'labelCfg':{'text':'height in inches'} } 670 671 self.widgetDescr['linewidth'] = { 672 'class':'NEThumbWheel','master':'ParamPanel', 673 'width':75, 'height':21, 'oneTurn':2, 'type':'int', 674 'wheelPad':2, 'initialValue':1, 675 'labelCfg':{'text':'linewidth'} } 676 677 self.widgetDescr['dpi'] = { 678 'class':'NEThumbWheel','master':'ParamPanel', 679 'width':75, 'height':21, 'oneTurn':10, 'type':'int', 680 'wheelPad':2, 'initialValue':80, 681 'labelCfg':{'text':'DPI'} } 682 683 self.widgetDescr['nbRows'] = { 684 'class':'NEThumbWheel','master':'ParamPanel', 685 'width':75, 'height':21, 'oneTurn':10, 'type':'int', 686 'wheelPad':2, 'initialValue':1, 687 'labelCfg':{'text':'nb. rows'} } 688 689 self.widgetDescr['nbColumns'] = { 690 'class':'NEThumbWheel','master':'ParamPanel', 691 'width':75, 'height':21, 'oneTurn':10, 'type':'int', 692 'wheelPad':2, 'initialValue':1, 693 'labelCfg':{'text':'nb. col'} } 694 695 self.widgetDescr['frameon'] = { 696 'class':'NECheckButton', 'master':'ParamPanel', 697 'initialValue':1, 'labelCfg':{'text':'frame'} } 698 699 self.widgetDescr['hold'] = { 700 'class':'NECheckButton', 'master':'ParamPanel', 701 'initialValue':0, 'labelCfg':{'text':'hold'} } 702 703 self.widgetDescr['toolbar'] = { 704 'class':'NECheckButton', 'master':'ParamPanel', 705 'initialValue':1, 'labelCfg':{'text':'toolbar'} } 706 707 self.widgetDescr['packOpts'] = { 708 'class':'NEEntry', 'master':'ParamPanel', 709 'labelCfg':{'text':'packing Opts.:'}, 710 'initialValue':'{"side":"top", "fill":"both", "expand":1}'} 711 712 code = """def doit(self, plots=None, width=None, height=None, linewidth=1, 713 dpi=None, facecolor=None, edgecolor=None, master=None, nbRows=None, 714 nbColumns=None, frameon=True, hold=False, toolbar=True, packOpts=None): 715 716 self.figure.clear() 717 if plots is not None: 718 for p in plots: 719 self.figure.add_axes(p) 720 721 figure = self.figure 722 # configure size 723 if width is not None or height is not None: 724 defaults = matplotlib.rcParams 725 726 if width is None: 727 width = defaults['figure.figsize'][0] 728 elif height is None: 729 height = defaults['figure.figsize'][1] 730 731 figure.set_figsize_inches(width,height) 732 733 # configure dpi 734 if dpi is not None: 735 figure.set_dpi(dpi) 736 737 # configure facecolor 738 if facecolor is not None: 739 figure.set_facecolor(facecolor) 740 741 # configure edgecolor 742 if edgecolor is not None: 743 figure.set_edgecolor(facecolor) 744 745 # configure frameon 746 if edgecolor is not None: 747 figure.set_edgecolor(facecolor) 748 749 # not sure linewidth is doing anything here 750 figure.figurePatch.set_linewidth(linewidth) 751 figure.hold(hold) 752 753 # FIXME for now we store this here but we might want to add this as 754 # regular attributes to Figure which would be used with subplot 755 #figure.nbRows = nbRows 756 #figure.nbColumns = nbColumns 757 758 self.canvas.draw() 759 760 self.outputData(figure=self.figure) 761 """ 762 self.setFunction(code)
763
764 -class MPLImageNE(MPLBaseNE):
765 """This node creates a PIL image 766 767 Input: 768 plots - Matplotlib Axes objects 769 figwidth - width in inches 770 figheigh - height in inches 771 dpi - resolution; defaults to rc figure.dpi 772 facecolor - the background color; defaults to rc figure.facecolor 773 edgecolor - the border color; defaults to rc figure.edgecolor 774 faceAlpha - alpha value of background 775 edgeAlpha - alpha value of edge 776 frameon - boolean 777 hold - boolean 778 toolbar - boolean (init option only) 779 packOpts - string representation of packing options 780 781 Output: 782 canvas: MPLFigure Object 783 784 Todo: 785 legend 786 text 787 image ? 788 """ 789
790 - def __init__(self, name='imageFigure', **kw):
791 kw['name'] = name 792 apply( MPLBaseNE.__init__, (self,), kw ) 793 794 codeBeforeDisconnect = """def beforeDisconnect(self, c): 795 node1 = c.port1.node 796 node2 = c.port2.node 797 if node1.figure.axes: 798 node1.figure.delaxes(node1.axes) 799 node1.figure.add_axes(node1.axes) 800 """ 801 ip = self.inputPortsDescr 802 ip.append(datatype='MPLAxes', required=False, name='plots', 803 singleConnection=False, 804 beforeDisconnect=codeBeforeDisconnect) 805 ip.append(datatype='float', required=False, name='width') 806 ip.append(datatype='float', required=False, name='height') 807 ip.append(datatype='int', required=False, name='dpi') 808 ip.append(datatype='colorsRGB', required=False, name='facecolor') 809 ip.append(datatype='colorsRGB', required=False, name='edgecolor') 810 ip.append(datatype='float', required=False, name='alphaFace') 811 ip.append(datatype='float', required=False, name='alphaEdge') 812 ip.append(datatype='boolean', required=False, name='frameon') 813 ip.append(datatype='boolean', required=False, name='hold') 814 815 op = self.outputPortsDescr 816 op.append(datatype='image', name='image') 817 818 self.widgetDescr['width'] = { 819 'class':'NEThumbWheel','master':'ParamPanel', 820 'width':75, 'height':21, 'oneTurn':2, 'type':'float', 821 'wheelPad':2, 'initialValue':6.4, 822 'labelCfg':{'text':'width in inches'} } 823 824 self.widgetDescr['height'] = { 825 'class':'NEThumbWheel','master':'ParamPanel', 826 'width':75, 'height':21, 'oneTurn':2, 'type':'float', 827 'wheelPad':2, 'initialValue':4.8, 828 'labelCfg':{'text':'height in inches'} } 829 830 self.widgetDescr['dpi'] = { 831 'class':'NEThumbWheel','master':'ParamPanel', 832 'width':75, 'height':21, 'oneTurn':10, 'type':'int', 833 'wheelPad':2, 'initialValue':80, 834 'labelCfg':{'text':'DPI'} } 835 836 self.widgetDescr['alphaFace'] = { 837 'class':'NEThumbWheel','master':'ParamPanel', 838 'width':75, 'height':21, 'oneTurn':1., 'type':'float', 839 'wheelPad':2, 'initialValue':0.5, 'min':0.0, 'max':1.0, 840 'labelCfg':{'text':'alpha Face'} } 841 842 self.widgetDescr['alphaEdge'] = { 843 'class':'NEThumbWheel','master':'ParamPanel', 844 'width':75, 'height':21, 'oneTurn':1., 'type':'float', 845 'wheelPad':2, 'initialValue':0.5, 'min':0.0, 'max':1.0, 846 'labelCfg':{'text':'alphaEdge'} } 847 848 self.widgetDescr['frameon'] = { 849 'class':'NECheckButton', 'master':'ParamPanel', 850 'initialValue':1, 'labelCfg':{'text':'frame'} } 851 852 self.widgetDescr['hold'] = { 853 'class':'NECheckButton', 'master':'ParamPanel', 854 'initialValue':0, 'labelCfg':{'text':'hold'} } 855 856 code = """def doit(self, plots=None, width=None, height=None, dpi=None, facecolor=None, edgecolor=None, alphaFace=0.5, alphaEdge=0.5, frameon=True, hold=False): 857 figure = self.figure 858 try: 859 self.canvas.renderer.clear() 860 except AttributeError: 861 pass 862 figure.clear() 863 864 # Powers of 2 image to be clean 865 if width>height: 866 htc = float(height)/width 867 w = 512 868 h = int(512*htc) 869 else: 870 wtc = float(width)/height 871 w = int(512*wtc) 872 h = 512 873 874 dpi = figure.get_dpi() 875 876 877 #figure.set_figsize_inches(width,height) 878 figure.set_figsize_inches(w / dpi, h / dpi) 879 880 for p in plots: 881 if hasattr(p,"figure"): 882 p.figure.set_figwidth(w / dpi) 883 p.figure.set_figheight(h / dpi) 884 figure.add_axes(p) 885 p.set_figure(figure) 886 p.axesPatch.set_alpha(alphaFace) 887 888 # configure dpi 889 if dpi is not None: 890 figure.set_dpi(dpi) 891 892 # configure facecolor 893 if facecolor is not None: 894 figure.set_facecolor(tuple(facecolor[0])) 895 896 # configure edgecolor 897 if edgecolor is not None: 898 figure.set_edgecolor(tuple(edgecolor[0])) 899 900 # configure frameon 901 if frameon is not None: 902 figure.set_frameon(frameon) 903 904 figure.hold(hold) 905 906 figure.figurePatch.set_alpha(alphaEdge) 907 self.canvas.draw() # force a draw 908 909 import Image 910 im = self.canvas.buffer_rgba(0,0) 911 ima = Image.frombuffer("RGBA", (w,h), im) 912 ima = ima.transpose(Image.FLIP_TOP_BOTTOM) 913 914 self.outputData(image=ima) 915 """ 916 self.setFunction(code)
917 918
919 - def beforeRemovingFromNetwork(self):
920 #print 'remove' 921 NetworkNode.beforeRemovingFromNetwork(self) 922 # this happens for drawing nodes with no axes specified 923 if self.axes: 924 self.axes.figure.delaxes(self.axes) # feel a little strange !
925
926 - def afterAddingToNetwork(self):
927 self.figure = Figure() 928 from matplotlib.backends.backend_agg import FigureCanvasAgg 929 self.canvas = FigureCanvasAgg(self.figure)
930 931 932
933 -class MPLDrawAreaNE(NetworkNode):
934 """Class for configuring the axes. 935 The following options can be set. 936 left,bottom,width,height ----allows to set the position of the axes. 937 frame on/off --- allows to on or off frame 938 hold on/off --- allows to on or off hold.When hold is True, subsequent plot commands will be added to 939 the current axes. When hold is False, the current axes and figure will be cleared on 940 the next plot command 941 title --- allows to set title of the figure 942 xlabel ---allows to set xlabel of the figure 943 ylabel ---allows to set ylabel of the figure 944 xlimit --- set autoscale off before setting xlimit. 945 y limit --- set autoscale off before setting ylimit. 946 xticklabels on/off --- allows to on or off xticklabels 947 yticklabels on/off --- allows to on or off yticklabels 948 axis on/off --- allows to on or off axis 949 autoscale on/off --- when on sets default axes limits ,when off sets limit from xlimit and ylimit entries. 950 """ 951
952 - def __init__(self, name='Draw Area', **kw):
953 kw['name'] = name 954 apply( NetworkNode.__init__, (self,), kw ) 955 956 ip = self.inputPortsDescr 957 ip.append(datatype='float', required=False, name='left') 958 ip.append(datatype='float', required=False, name='bottom') 959 ip.append(datatype='float', required=False, name='width') 960 ip.append(datatype='float', required=False, name='height') 961 ip.append(datatype='boolean', required=False, name='frameon') 962 ip.append(datatype='boolean', required=False, name='hold') 963 ip.append(datatype='string', required=False, name='title') 964 ip.append(datatype='string', required=False, name='xlabel') 965 ip.append(datatype='string', required=False, name='ylabel') 966 ip.append(datatype='string', required=False, name='xlimit') 967 ip.append(datatype='string', required=False, name='ylimit') 968 ip.append(datatype='boolean', required=False, name='xticklabels') 969 ip.append(datatype='boolean', required=False, name='yticklabels') 970 ip.append(datatype='boolean', required=False, name='axison') 971 ip.append(datatype='boolean', required=False, name='autoscaleon') 972 self.widgetDescr['left'] = { 973 'class':'NEThumbWheel','master':'ParamPanel', 974 'width':75, 'height':21, 'oneTurn':1., 'type':'float', 975 'labelGridCfg':{'sticky':'w'}, 976 'wheelPad':2, 'initialValue':0.1, 977 'labelCfg':{'text':'left (0. to 1.)'} } 978 979 self.widgetDescr['bottom'] = { 980 'class':'NEThumbWheel','master':'ParamPanel', 981 'width':75, 'height':21, 'oneTurn':1., 'type':'float', 982 'labelGridCfg':{'sticky':'w'}, 983 'wheelPad':2, 'initialValue':0.1, 984 'labelCfg':{'text':'bottom (0. to 1.)'} } 985 986 self.widgetDescr['width'] = { 987 'class':'NEThumbWheel','master':'ParamPanel', 988 'width':75, 'height':21, 'oneTurn':1., 'type':'float', 989 'labelGridCfg':{'sticky':'w'}, 990 'wheelPad':2, 'initialValue':0.8, 991 'labelCfg':{'text':'width (0. to 1.)'} } 992 993 self.widgetDescr['height'] = { 994 'class':'NEThumbWheel','master':'ParamPanel', 995 'width':75, 'height':21, 'oneTurn':1., 'type':'float', 996 'labelGridCfg':{'sticky':'w'}, 997 'wheelPad':2, 'initialValue':0.8, 998 'labelCfg':{'text':'height (0. to 1.0)'} } 999 1000 self.widgetDescr['frameon'] = { 1001 'class':'NECheckButton', 'master':'ParamPanel', 1002 'labelGridCfg':{'sticky':'w'}, 1003 'initialValue':1, 'labelCfg':{'text':'frame'} } 1004 1005 self.widgetDescr['hold'] = { 1006 'class':'NECheckButton', 'master':'ParamPanel', 1007 'labelGridCfg':{'sticky':'w'}, 1008 'initialValue':0, 'labelCfg':{'text':'hold'} } 1009 1010 self.widgetDescr['title'] = { 1011 'class':'NEEntry', 'master':'ParamPanel', 1012 'labelCfg':{'text':'title'},'labelGridCfg':{'sticky':'w'}, 1013 'initialValue':'Figure:'} 1014 1015 self.widgetDescr['xlabel'] = { 1016 'class':'NEEntry', 'master':'ParamPanel', 1017 'labelCfg':{'text':'X label'},'labelGridCfg':{'sticky':'w'}, 1018 'initialValue':'X'} 1019 1020 self.widgetDescr['ylabel'] = { 1021 'class':'NEEntry', 'master':'ParamPanel','labelGridCfg':{'sticky':'w'}, 1022 'labelCfg':{'text':'Y label'}, 1023 'initialValue':'Y'} 1024 1025 self.widgetDescr['xlimit'] = { 1026 'class':'NEEntry', 'master':'ParamPanel','labelGridCfg':{'sticky':'w'}, 1027 'labelCfg':{'text':'X limit'}, 1028 'initialValue':''} 1029 1030 self.widgetDescr['ylimit'] = { 1031 'class':'NEEntry', 'master':'ParamPanel','labelGridCfg':{'sticky':'w'}, 1032 'labelCfg':{'text':'Y limit'}, 1033 'initialValue':''} 1034 1035 self.widgetDescr['xticklabels'] = { 1036 'class':'NECheckButton', 'master':'ParamPanel','labelGridCfg':{'sticky':'w'}, 1037 'initialValue':1, 'labelCfg':{'text':'xticklabels'} } 1038 1039 self.widgetDescr['yticklabels'] = { 1040 'class':'NECheckButton', 'master':'ParamPanel','labelGridCfg':{'sticky':'w'},'labelGridCfg':{'sticky':'w'}, 1041 'initialValue':1, 'labelCfg':{'text':'yticklabels'} } 1042 1043 1044 self.widgetDescr['axison'] = { 1045 'class':'NECheckButton', 'master':'ParamPanel', 1046 'initialValue':1, 'labelCfg':{'text':'axis on'} } 1047 self.widgetDescr['autoscaleon'] = { 1048 'class':'NECheckButton', 'master':'ParamPanel','labelGridCfg':{'sticky':'w'}, 1049 'initialValue':1, 'labelCfg':{'text':'autoscale on'} } 1050 op = self.outputPortsDescr 1051 op.append(datatype='MPLDrawArea', name='drawAreaDef') 1052 1053 code = """def doit(self, left=.1, bottom=.1, 1054 width=.8, height=.8, frameon=True, hold=False, title='Figure', xlabel='X', 1055 ylabel='Y', xlimit='',ylimit='',xticklabels=True,yticklabels=True,axison=True,autoscaleon=True): 1056 1057 kw = {'left':left, 'bottom':bottom, 'width':width, 'height':height, 1058 'frameon':frameon, 'hold':hold, 'title':title, 'xlabel':xlabel, 1059 'ylabel':ylabel, 'axison':axison, 'xticklabels': xticklabels,'yticklabels': yticklabels,'xlimit':xlimit,'ylimit':ylimit,'autoscaleon':autoscaleon} 1060 1061 self.outputData(drawAreaDef=kw) 1062 """ 1063 self.setFunction(code)
1064 1065
1066 -class MPLMergeTextNE(NetworkNode):
1067 """Class for writting multiple labels in the axes.Takes input from Text 1068 nodes. 1069 """
1070 - def __init__(self, name='MergeText', **kw):
1071 kw['name'] = name 1072 apply( NetworkNode.__init__, (self,), kw ) 1073 ip = self.inputPortsDescr 1074 ip.append(datatype='MPLDrawArea', required=False,name='textlist',singleConnection=False) 1075 op = self.outputPortsDescr 1076 op.append(datatype='MPLDrawArea', name='drawAreaDef') 1077 code = """def doit(self,textlist): 1078 kw={'text':textlist} 1079 self.outputData(drawAreaDef=kw)""" 1080 self.setFunction(code)
1081
1082 -class MPLPlottingNode(MPLBaseNE):
1083 """Base class for plotting nodes""" 1084
1085 - def afterAddingToNetwork(self):
1086 1087 self.figure = Figure() 1088 self.axes = self.figure.add_subplot( 111 ) 1089 self.axes.node = weakref.ref(self) 1090 1091 master = Tkinter.Toplevel() 1092 master.title(self.name) 1093 self.canvas = FigureCanvasTkAgg(self.figure, master) 1094 self.figure.set_canvas(self.canvas) 1095 1096 packOptsDict = {'side':'top', 'fill':'both', 'expand':1} 1097 self.canvas.get_tk_widget().pack( *(), **packOptsDict ) 1098 self.canvas._master.protocol('WM_DELETE_WINDOW',self.canvas._master.iconify) 1099 toolbar = NavigationToolbar2TkAgg(self.canvas, master)
1100
1101 - def setDrawAreaDef(self,drawAreaDef):
1102 newdrawAreaDef={} 1103 if drawAreaDef: 1104 if len(drawAreaDef)==1 and drawAreaDef[0]!=None: 1105 for d in drawAreaDef[0].keys(): 1106 newdrawAreaDef[d]=drawAreaDef[0][d] 1107 elif len(drawAreaDef)>1: 1108 for dAD in drawAreaDef: 1109 if type(dAD)== types.DictType: 1110 for j in dAD.keys(): 1111 newdrawAreaDef[j]=dAD[j] 1112 self.setDrawArea(newdrawAreaDef)
1113 1114 codeBeforeDisconnect ="""def beforeDisconnect(self,c): 1115 node=c.port2.node 1116 node.axes.clear() 1117 node.canvas.draw() """
1118 1119 ######################################################################## 1120 #### 1121 #### PLOTTING NODES 1122 #### 1123 ######################################################################## 1124
1125 -class FillNE(MPLPlottingNode):
1126 """plots filled polygons. 1127 x - list of x vertices 1128 y - list of y vertices 1129 fillcolor - color 1130 """ 1131
1132 - def __init__(self, name='Fill', **kw):
1133 kw['name'] = name 1134 apply( MPLPlottingNode.__init__, (self,), kw ) 1135 ip = self.inputPortsDescr 1136 ip.append(datatype='list', name='x',beforeDisconnect=self.codeBeforeDisconnect) 1137 ip.append(datatype='list',name='y',beforeDisconnect=self.codeBeforeDisconnect) 1138 ip.append(datatype='string', required=False, name='fillcolor') 1139 ip.append(datatype='MPLDrawArea', required=False,name='drawAreaDef',singleConnection=False) 1140 self.widgetDescr['fillcolor'] = { 1141 'class':'NEComboBox', 'master':'node', 1142 'choices':cnames.keys(), 1143 'fixedChoices':True, 1144 'initialValue':'white', 1145 'entryfield_entry_width':7, 1146 'labelGridCfg':{'sticky':'w'}, 1147 'widgetGridCfg':{'sticky':'we'}, 1148 'labelCfg':{'text':'fillcolor:'}} 1149 op = self.outputPortsDescr 1150 op.append(datatype='MPLAxes', name='axes') 1151 op.append(datatype='None', name='fig') 1152 code = """def doit(self,x,y,fillcolor='w',drawAreaDef=None): 1153 self.axes.clear() 1154 ax=self.axes 1155 p=ax.fill(x,y,fillcolor) 1156 self.setDrawAreaDef(drawAreaDef) 1157 self.canvas.draw() 1158 self.outputData(axes=self.axes,fig=p)""" 1159 self.setFunction(code)
1160
1161 -class PolarAxesNE(MPLPlottingNode):
1162 """ This node plots on PolarAxes 1163 Input: 1164 y - sequence of values 1165 x - None; sequence of values 1166 Adjustable parameters: 1167 grid --grid on or off(default is on) 1168 gridcolor --color of the grid 1169 gridlinewidth --linewidth of the grid 1170 gridlinestyle --gridlinestyle 1171 xtickcolor -- color of xtick 1172 ytickcolor -- color of ytick 1173 xticksize --size of xtick 1174 yticksize --size of ytick 1175 """
1176 - def __init__(self, name='PolarAxes', **kw):
1177 1178 kw['name'] = name 1179 apply( MPLPlottingNode.__init__, (self,), kw ) 1180 self.styles={} 1181 for ls in Line2D._lineStyles.keys(): 1182 self.styles[Line2D._lineStyles[ls][6:]]=ls 1183 for ls in Line2D._markers.keys(): 1184 self.styles[Line2D._markers[ls][6:]]=ls 1185 #these styles are not recognized 1186 del self.styles['steps'] 1187 for s in self.styles.keys(): 1188 1189 if s =="nothing": 1190 del self.styles['nothing'] 1191 if s[:4]=='tick': 1192 del self.styles[s] 1193 self.colors=colors 1194 ip = self.inputPortsDescr 1195 #ip.append(datatype='MPLAxes', required=False, name='p', 1196 #singleConnection=True)#,beforeDisconnect=codeBeforeDisconnect) 1197 ip.append(datatype='list', name='y',beforeDisconnect=self.codeBeforeDisconnect) 1198 ip.append(datatype='list', name='x',beforeDisconnect=self.codeBeforeDisconnect) 1199 ip.append(datatype='string', required=False, name='lineStyle') 1200 ip.append(datatype='None', required=False, name='color') 1201 ip.append(datatype='boolean', required=False, name='grid') 1202 ip.append(datatype='str', required=False, name='gridlineStyle') 1203 ip.append(datatype='str', required=False, name='gridcolor') 1204 ip.append(datatype='float', required=False, name='gridlinewidth') 1205 ip.append(datatype='str', required=False, name='axisbg') 1206 ip.append(datatype='str', required=False, name='xtickcolor') 1207 ip.append(datatype='str', required=False, name='ytickcolor') 1208 ip.append(datatype='float', required=False, name='xticksize') 1209 ip.append(datatype='float', required=False, name='yticksize') 1210 ip.append(datatype='MPLDrawArea', required=False,name='drawAreaDef',singleConnection=False) 1211 self.widgetDescr['grid'] = { 1212 'class':'NECheckButton', 'master':'ParamPanel', 1213 'initialValue':1, 'labelCfg':{'text':'grid'} , 1214 'labelGridCfg':{'sticky':'w'}, 1215 'widgetGridCfg':{'sticky':'w'},} 1216 self.widgetDescr['lineStyle'] = { 1217 'class':'NEComboBox', 'master':'node', 1218 'choices':self.styles.keys(), 1219 'fixedChoices':True, 1220 'initialValue':'solid', 1221 'entryfield_entry_width':7, 1222 'labelGridCfg':{'sticky':'w'}, 1223 'widgetGridCfg':{'sticky':'w'}, 1224 'labelCfg':{'text':'line style:'}} 1225 self.widgetDescr['color'] = { 1226 'class':'NEComboBox', 'master':'node', 1227 'choices':self.colors.keys(), 1228 'fixedChoices':True, 1229 'initialValue':'black', 1230 'entryfield_entry_width':7, 1231 'labelGridCfg':{'sticky':'w'}, 1232 'widgetGridCfg':{'sticky':'we'}, 1233 'labelCfg':{'text':'color:'}} 1234 self.widgetDescr['gridlineStyle'] = { 1235 'class':'NEComboBox', 'master':'ParamPanel', 1236 'choices':lineStyles.keys(), 1237 'fixedChoices':True, 1238 'initialValue':'--', 1239 'entryfield_entry_width':7, 1240 'labelGridCfg':{'sticky':'w'}, 1241 'widgetGridCfg':{'sticky':'w'}, 1242 'labelCfg':{'text':'gridlinestyle:'}} 1243 self.widgetDescr['gridcolor'] = { 1244 'class':'NEComboBox', 'master':'ParamPanel', 1245 'choices':cnames.keys(), 1246 'fixedChoices':True, 1247 'initialValue':'gray', 1248 'entryfield_entry_width':7, 1249 'labelGridCfg':{'sticky':'w'}, 1250 'widgetGridCfg':{'sticky':'w'}, 1251 'labelCfg':{'text':'gridcolor:'}} 1252 self.widgetDescr['gridlinewidth'] = { 1253 'class':'NEThumbWheel','master':'ParamPanel', 1254 'width':60, 'height':21, 'oneTurn':2, 'type':'float', 1255 'wheelPad':2, 'initialValue':1, 1256 'labelCfg':{'text':'gridlinewidth'}, 1257 'labelGridCfg':{'sticky':'w'}, 1258 'widgetGridCfg':{'sticky':'w'}} 1259 self.widgetDescr['axisbg'] = { 1260 'class':'NEComboBox', 'master':'ParamPanel', 1261 'choices':cnames.keys(), 1262 'fixedChoices':True, 1263 'initialValue':'white', 1264 'entryfield_entry_width':7, 1265 'labelGridCfg':{'sticky':'w'}, 1266 'widgetGridCfg':{'sticky':'w'}, 1267 'labelCfg':{'text':'axisbg:'}} 1268 self.widgetDescr['xtickcolor'] = { 1269 'class':'NEComboBox', 'master':'ParamPanel', 1270 'choices':cnames.keys(), 1271 'fixedChoices':True, 1272 'initialValue':'black', 1273 'entryfield_entry_width':7, 1274 'labelGridCfg':{'sticky':'w'}, 1275 'widgetGridCfg':{'sticky':'w'}, 1276 'labelCfg':{'text':'xtickcolor:'}} 1277 self.widgetDescr['ytickcolor'] = { 1278 'class':'NEComboBox', 'master':'ParamPanel', 1279 'choices':cnames.keys(), 1280 'fixedChoices':True, 1281 'initialValue':'black', 1282 'entryfield_entry_width':7, 1283 'labelGridCfg':{'sticky':'w'}, 1284 'widgetGridCfg':{'sticky':'w'}, 1285 'labelCfg':{'text':'ytickcolor:'}} 1286 self.widgetDescr['xticksize'] = { 1287 'class':'NEThumbWheel','master':'ParamPanel', 1288 'width':60, 'height':21, 'oneTurn':2, 'type':'float', 1289 'wheelPad':2, 'initialValue':12, 1290 'labelCfg':{'text':'xticksize'},'labelGridCfg':{'sticky':'w'}, 1291 'widgetGridCfg':{'sticky':'w'} } 1292 self.widgetDescr['yticksize'] = { 1293 'class':'NEThumbWheel','master':'ParamPanel', 1294 'width':60, 'height':21, 'oneTurn':2, 'type':'float', 1295 'wheelPad':2, 'initialValue':12, 1296 'labelCfg':{'text':'yticksize'},'labelGridCfg':{'sticky':'w'}, 1297 'widgetGridCfg':{'sticky':'w'} } 1298 op = self.outputPortsDescr 1299 op.append(datatype='MPLFigure', name='figure') 1300 code = """def doit(self, y,x,lineStyle='solid',color='black',grid=1,gridlineStyle="--",gridcolor="gray",gridlinewidth=1,axisbg="white",xtickcolor="black",ytickcolor="black",xticksize=12,yticksize=12,drawAreaDef=None): 1301 1302 self.figure.clear() 1303 self.setDrawAreaDef(drawAreaDef) 1304 if grid==1: 1305 matplotlib.rc('grid',color=gridcolor,linewidth=gridlinewidth,linestyle=gridlineStyle) 1306 matplotlib.rc('xtick',color=xtickcolor,labelsize=xticksize) 1307 matplotlib.rc('ytick',color=ytickcolor,labelsize=yticksize) 1308 colorChar = self.colors[color] 1309 lineStyleChar = self.styles[lineStyle] 1310 new_axes=self.figure.add_axes(self.axes.get_position(),polar=True,axisbg=axisbg) 1311 self.axes=new_axes 1312 self.axes.plot(x, y, colorChar+lineStyleChar) 1313 if grid!=1: 1314 new_axes.grid(grid) 1315 self.canvas.draw() 1316 self.outputData(figure=self.figure)""" 1317 self.setFunction(code)
1318 1319 1320
1321 -class StemNE(MPLPlottingNode):
1322 """A stem plot plots vertical lines (using linefmt) at each x location 1323 from the baseline to y, and places a marker there using markerfmt. A 1324 horizontal line at 0 is is plotted using basefmt 1325 input: list of x values 1326 Return value is (markerline, stemlines, baseline) . 1327 """
1328 - def __init__(self, name='Stem', **kw):
1329 kw['name'] = name 1330 apply( MPLPlottingNode.__init__, (self,),kw ) 1331 ip = self.inputPortsDescr 1332 ip.append(datatype='list',required=True, name='x',beforeDisconnect=self.codeBeforeDisconnect) 1333 ip.append(datatype='list',required=True, name='y',beforeDisconnect=self.codeBeforeDisconnect) 1334 ip.append(datatype='string',required=False,name='stemlinestyle') 1335 ip.append(datatype='string',required=False,name='stemlinecolor') 1336 ip.append(datatype='string',required=False,name='markerstyle') 1337 ip.append(datatype='string',required=False,name='markerfacecolor') 1338 ip.append(datatype='string',required=False,name='baselinecolor') 1339 ip.append(datatype='string',required=False,name='baselinestyle') 1340 ip.append(datatype='MPLDrawArea', required=False,name='drawAreaDef',singleConnection=False) 1341 self.widgetDescr['stemlinestyle'] = { 1342 'class':'NEComboBox', 'master':'ParamPanel', 1343 'choices':['-.','--','-',':'], 1344 'fixedChoices':True, 1345 'initialValue':'--', 1346 'entryfield_entry_width':7, 1347 'labelGridCfg':{'sticky':'w'}, 1348 'widgetGridCfg':{'sticky':'w'}, 1349 'labelCfg':{'text':'stemlinestyle:'}} 1350 self.widgetDescr['stemlinecolor'] = { 1351 'class':'NEComboBox', 'master':'ParamPanel', 1352 'choices':colors.values(), 1353 'fixedChoices':True, 1354 'initialValue':'b', 1355 'entryfield_entry_width':7, 1356 'labelGridCfg':{'sticky':'w'}, 1357 'widgetGridCfg':{'sticky':'w'}, 1358 'labelCfg':{'text':'stemlinecolor:'}} 1359 self.widgetDescr['markerstyle'] = { 1360 'class':'NEComboBox', 'master':'ParamPanel', 1361 'choices':Line2D._markers.keys(), 1362 'fixedChoices':True, 1363 'initialValue':'o', 1364 'entryfield_entry_width':7, 1365 'labelGridCfg':{'sticky':'w'}, 1366 'widgetGridCfg':{'sticky':'w'}, 1367 'labelCfg':{'text':'markerstyle:'}} 1368 self.widgetDescr['markerfacecolor'] = { 1369 'class':'NEComboBox', 'master':'ParamPanel', 1370 'choices':colors.values(), 1371 'fixedChoices':True, 1372 'initialValue':'k', 1373 'entryfield_entry_width':7, 1374 'labelGridCfg':{'sticky':'w'}, 1375 'widgetGridCfg':{'sticky':'w'}, 1376 'labelCfg':{'text':'markerfacecolor:'}} 1377 self.widgetDescr['baselinestyle'] = { 1378 'class':'NEComboBox', 'master':'ParamPanel', 1379 'choices':['-.','--','-',':'], 1380 'fixedChoices':True, 1381 'initialValue':'-', 1382 'entryfield_entry_width':7, 1383 'labelGridCfg':{'sticky':'w'}, 1384 'widgetGridCfg':{'sticky':'w'}, 1385 'labelCfg':{'text':'baselinestyle:'}} 1386 self.widgetDescr['baselinecolor'] = { 1387 'class':'NEComboBox', 'master':'ParamPanel', 1388 'choices':colors.values(), 1389 'fixedChoices':True, 1390 'initialValue':'k', 1391 'entryfield_entry_width':7, 1392 'labelGridCfg':{'sticky':'w'}, 1393 'widgetGridCfg':{'sticky':'w'}, 1394 'labelCfg':{'text':'baselinecolor:'}} 1395 1396 op = self.outputPortsDescr 1397 op.append(datatype='MPLAxes', name='stem') 1398 code = """def doit(self,x,y,stemlinestyle='--',stemlinecolor="b",markerstyle='o',markerfacecolor='b',baselinecolor='b',baselinestyle="-",drawAreaDef=None): 1399 self.axes.clear() 1400 linefmt=stemlinecolor+stemlinestyle 1401 markerfmt=markerfacecolor+markerstyle 1402 basefmt= baselinecolor+baselinestyle 1403 markerline, stemlines, baseline = self.axes.stem(x, y, linefmt=linefmt, markerfmt=markerfmt, basefmt=basefmt ) 1404 self.setDrawAreaDef(drawAreaDef) 1405 self.canvas.draw() 1406 self.outputData(stem=self.axes)""" 1407 self.setFunction(code)
1408
1409 -class MultiPlotNE(MPLPlottingNode):
1410 """This node allows to plot multiple plots on same axes 1411 input: axes instances 1412 """
1413 - def __init__(self, name='MultiPlot', **kw):
1414 kw['name'] = name 1415 apply( MPLPlottingNode.__init__, (self,),kw ) 1416 ip = self.inputPortsDescr 1417 ip.append(datatype='MPLAxes', required=True, name='multiplot', singleConnection=False,beforeDisconnect=self.codeBeforeDisconnect) 1418 ip.append(datatype='MPLDrawArea', required=False, name='drawAreaDef', singleConnection=False) 1419 op = self.outputPortsDescr 1420 op.append(datatype='MPLAxes', name='multiplot') 1421 code = """def doit(self, plots=None,drawAreaDef=None): 1422 self.axes.clear() 1423 ax=self.axes 1424 if len(plots)>0: 1425 ax.set_xlim(plots[0].get_xlim()) 1426 ax.set_ylim(plots[0].get_ylim()) 1427 for p in plots: 1428 if p.patches!=[]: 1429 for pt in p.patches: 1430 ax.add_patch(pt) 1431 elif p.lines!=[]: 1432 if p.lines!=[]: 1433 for pt in p.lines: 1434 ax.add_line(pt) 1435 elif p.collections!=[]: 1436 if p.collections!=[]: 1437 for pt in p.collections: 1438 ax.add_collection(pt) 1439 else: 1440 ax.add_artist(p) 1441 ax.autoscale_view() 1442 self.setDrawAreaDef(drawAreaDef) 1443 self.canvas.draw() 1444 self.outputData(multiplot=self.axes)""" 1445 self.setFunction(code)
1446
1447 -class TablePlotNE(MPLPlottingNode):
1448 """Adds a table to the current axes and plots bars. 1449 input: 1450 cellText - list of values 1451 rowLabels - list of labels 1452 rowColours - list of colors 1453 colLabels - list of labels 1454 colColours - list of colors 1455 location - location where the table to be placed. 1456 """
1457 - def __init__(self, name='TablePlot', **kw):
1458 """ 1459 TABLE(cellText=None, cellColours=None, 1460 cellLoc='right', colWidths=None, 1461 rowLabels=None, rowColours=None, rowLoc='left', 1462 colLabels=None, colColours=None, colLoc='center', 1463 loc='bottom', bbox=None): 1464 1465 Adds a table to the current axes and plots bars. 1466 """ 1467 kw['name'] = name 1468 locs=locations.keys() 1469 locs.append("bottom") 1470 apply( MPLPlottingNode.__init__, (self,), kw ) 1471 ip = self.inputPortsDescr 1472 ip.append(datatype='list',required=True, name='values',singleConnection="auto",beforeDisconnect=self.codeBeforeDisconnect) 1473 ip.append(datatype='list',required=True, name='rowLabels',beforeDisconnect=self.codeBeforeDisconnect) 1474 ip.append(datatype='list',required=True, name='colLabels',beforeDisconnect=self.codeBeforeDisconnect) 1475 ip.append(datatype='list',required=False, name='rowColors') 1476 ip.append(datatype='list',required=False, name='colColors') 1477 ip.append(datatype='string',required=False, name='location') 1478 ip.append(datatype='MPLDrawArea',required=False,name='drawAreaDef',singleConnection=False) 1479 self.widgetDescr['location'] = { 1480 'class':'NEComboBox', 'master':'node', 1481 'choices':locs, 1482 'fixedChoices':True, 1483 'initialValue':'bottom', 1484 'entryfield_entry_width':7, 1485 'labelGridCfg':{'sticky':'w'}, 1486 'widgetGridCfg':{'sticky':'w'}, 1487 'labelCfg':{'text':'Location:'}} 1488 op = self.outputPortsDescr 1489 op.append(datatype='MPLAxes', name='plot') 1490 1491 code = """def doit(self,values,rowLabels,colLabels,rowColors=None,colColors=None,location='bottom',drawAreaDef=None): 1492 self.axes.clear() 1493 self.setDrawAreaDef(drawAreaDef) 1494 #self.axes.set_position([0.2, 0.2, 0.7, 0.6]) 1495 data=[] 1496 nd=[] 1497 for val in values : 1498 for v in val: 1499 nd.append(float(v)) 1500 data.append(nd) 1501 nd=[] 1502 #rcolours = get_colours(len(colLabels)) 1503 rows = len(data) 1504 ind = arange(len(colLabels)) + 0.3 # the x locations for the groups 1505 cellText = [] 1506 width = 0.4 # the width of the bars 1507 yoff = array([0.0] * len(colLabels)) # the bottom values for stacked bar chart 1508 for row in xrange(rows): 1509 self.axes.bar(ind, data[row], width, bottom=yoff, color=rowColors[row]) 1510 yoff = yoff + data[row] 1511 cellText.append(['%1.1f' % x for x in yoff]) 1512 the_table = self.axes.table(cellText=cellText, 1513 rowLabels=rowLabels, 1514 rowColours=rowColors, 1515 colColours=colColors, 1516 colLabels=colLabels, 1517 loc=location) 1518 if location=="bottom": 1519 self.axes.set_xticks([]) 1520 self.axes.set_xticklabels([]) 1521 self.canvas.draw() 1522 self.outputData(plot=self.axes)""" 1523 self.setFunction(code)
1524
1525 -class HistogramNE(MPLPlottingNode):
1526 """This nodes takes a list of values and builds a histogram using matplotlib 1527 http://matplotlib.sourceforge.net/matplotlib.pylab.html#-hist 1528 1529 Compute the histogram of x. bins is either an integer number of 1530 bins or a sequence giving the bins. x are the data to be binned. 1531 1532 The return values is (n, bins, patches) 1533 1534 If normed is true, the first element of the return tuple will be the 1535 counts normalized to form a probability distribtion, ie, 1536 n/(len(x)*dbin) 1537 1538 Addition kwargs: hold = [True|False] overrides default hold state 1539 1540 Input: 1541 values: sequence of values 1542 bins=10: number of dequence giving the gins 1543 normed=0 normalize 1544 1545 Output: 1546 plot Matplotlib Axes object 1547 """
1548 - def __init__(self, name='Histogram', **kw):
1549 kw['name'] = name 1550 1551 apply( MPLPlottingNode.__init__, (self,), kw ) 1552 self.colors=cnames 1553 ip = self.inputPortsDescr 1554 ip.append(datatype='None', name='values',beforeDisconnect=self.codeBeforeDisconnect) 1555 ip.append(datatype='None', required=False, name='bins') 1556 ip.append(datatype='boolean', required=False, name='normed') 1557 ip.append(datatype='float', required=False, name='patch_antialiased') 1558 ip.append(datatype='float', required=False, name='patch_linewidth') 1559 ip.append(datatype='string', required=False, name='patch_edgecolor') 1560 ip.append(datatype='string', required=False, name='patch_facecolor') 1561 ip.append(datatype='MPLDrawArea',required=False,name='drawAreaDef',singleConnection=False) 1562 self.widgetDescr['bins'] = { 1563 'class':'NEThumbWheel','master':'node', 1564 'width':75, 'height':21, 'oneTurn':10, 'type':'int', 'wheelPad':2, 1565 'initialValue':10, 1566 'labelCfg':{'text':'# of bins'} } 1567 1568 self.widgetDescr['normed'] = { 1569 'class':'NECheckButton', 'master':'node', 1570 'initialValue':1, 'labelCfg':{'text':'normalize'}, 1571 } 1572 self.widgetDescr['patch_linewidth'] = { 1573 'class':'NEThumbWheel','master':'ParamPanel', 1574 'width':60, 'height':21, 'oneTurn':2, 'type':'int', 1575 'wheelPad':2, 'initialValue':1, 1576 'labelCfg':{'text':'linewidth'} } 1577 self.widgetDescr['patch_antialiased'] = { 1578 'class':'NECheckButton', 'master':'ParamPanel', 1579 'labelCfg':{'text':'antialiased:'}, 1580 'initialValue':1,} 1581 self.widgetDescr['patch_edgecolor'] = { 1582 'class':'NEComboBox', 'master':'ParamPanel', 1583 'choices':self.colors.keys(), 1584 'fixedChoices':True, 1585 'initialValue':'black', 1586 'entryfield_entry_width':7, 1587 'labelGridCfg':{'sticky':'w'}, 1588 'widgetGridCfg':{'sticky':'w'}, 1589 'labelCfg':{'text':'edgecolor:'}} 1590 self.widgetDescr['patch_facecolor'] = { 1591 'class':'NEComboBox', 'master':'ParamPanel', 1592 'choices':self.colors.keys(), 1593 'fixedChoices':True, 1594 'initialValue':'blue', 1595 'entryfield_entry_width':7, 1596 'labelGridCfg':{'sticky':'w'}, 1597 'widgetGridCfg':{'sticky':'w'}, 1598 'labelCfg':{'text':'facecolor:'}} 1599 op = self.outputPortsDescr 1600 op.append(datatype='MPLAxes', name='plot') 1601 1602 code = """def doit(self, values, bins=10, normed=False,patch_antialiased=1,patch_linewidth=1,patch_edgecolor='black',patch_facecolor='blue',drawAreaDef=None): 1603 self.axes.clear() 1604 self.setDrawAreaDef(drawAreaDef) 1605 n, bins, patches = self.axes.hist(values, bins, normed) 1606 if self.axes.patches: 1607 for p in self.axes.patches: 1608 p.set_linewidth(patch_linewidth) 1609 p.set_edgecolor(patch_edgecolor) 1610 p.set_facecolor(patch_facecolor) 1611 p.set_antialiased(patch_antialiased) 1612 self.canvas.draw() 1613 self.outputData(plot=self.axes) 1614 """ 1615 self.setFunction(code)
1616 1617 #Plot Nodes 1618
1619 -class PlotNE(MPLPlottingNode):
1620 """This nodes takes two lists of values and plots the the second against the first. 1621 1622 Input: 1623 y - sequence of values 1624 x - None; sequence of values 1625 figure - None; MPLFigure object object into which to place the drawing 1626 1627 Output: 1628 plot Matplotlib Axes object 1629 line: - line 1630 """ 1631
1632 - def __init__(self, name='Plot', **kw):
1633 kw['name'] = name 1634 apply( MPLPlottingNode.__init__, (self,), kw ) 1635 self.styles=get_styles() 1636 self.colors=colors 1637 self.joinstyles = Line2D.validJoin 1638 self.capstyles = Line2D.validCap 1639 ip = self.inputPortsDescr 1640 ip.append(datatype='list', name='y',beforeDisconnect=self.codeBeforeDisconnect) 1641 ip.append(datatype='list', required=False, name='x') 1642 ip.append(datatype='string', required=False, name='lineStyle') 1643 ip.append(datatype='None', required=False, name='color') 1644 ip.append(datatype='boolean', required=False, name='line_antialiased') 1645 ip.append(datatype='float', required=False, name='line_linewidth') 1646 ip.append(datatype='string', required=False, name='solid_joinstyle') 1647 ip.append(datatype='string', required=False, name='solid_capstyle') 1648 ip.append(datatype='string', required=False, name='dash_capstyle') 1649 ip.append(datatype='string', required=False, name='dash_joinstyle') 1650 ip.append(datatype='MPLDrawArea', required=False,name='drawAreaDef',singleConnection=False) 1651 1652 self.widgetDescr['lineStyle'] = { 1653 'class':'NEComboBox', 'master':'node', 1654 'choices':self.styles.keys(), 1655 'fixedChoices':True, 1656 'initialValue':'solid', 1657 'entryfield_entry_width':7, 1658 'labelGridCfg':{'sticky':'w'}, 1659 'widgetGridCfg':{'sticky':'w'}, 1660 'labelCfg':{'text':'line style:'}} 1661 1662 self.widgetDescr['color'] = { 1663 'class':'NEComboBox', 'master':'node', 1664 'choices':self.colors.keys(), 1665 'fixedChoices':True, 1666 'initialValue':'black', 1667 'entryfield_entry_width':7, 1668 'labelGridCfg':{'sticky':'w'}, 1669 'widgetGridCfg':{'sticky':'we'}, 1670 'labelCfg':{'text':'color:'}} 1671 1672 self.widgetDescr['dash_capstyle'] = { 1673 'class':'NEComboBox', 'master':'ParamPanel', 1674 'choices':self.capstyles, 1675 'fixedChoices':True, 1676 'initialValue':'butt', 1677 'entryfield_entry_width':7, 1678 'labelGridCfg':{'sticky':'w'}, 1679 'widgetGridCfg':{'sticky':'w'}, 1680 'labelCfg':{'text':'dash_capstyle:'}} 1681 self.widgetDescr['dash_joinstyle'] = { 1682 'class':'NEComboBox', 'master':'ParamPanel', 1683 'choices':self.joinstyles, 1684 'fixedChoices':True, 1685 'initialValue':'miter', 1686 'entryfield_entry_width':7, 1687 'labelGridCfg':{'sticky':'w'}, 1688 'widgetGridCfg':{'sticky':'w'}, 1689 'labelCfg':{'text':'dash _joinstyle:'}} 1690 self.widgetDescr['solid_capstyle'] = { 1691 'class':'NEComboBox', 'master':'ParamPanel', 1692 'choices':self.capstyles, 1693 'fixedChoices':True, 1694 'initialValue':'projecting', 1695 'entryfield_entry_width':7, 1696 'labelGridCfg':{'sticky':'w'}, 1697 'widgetGridCfg':{'sticky':'w'}, 1698 'labelCfg':{'text':'solid_capstyle:'}} 1699 self.widgetDescr['solid_joinstyle'] = { 1700 'class':'NEComboBox', 'master':'ParamPanel', 1701 'choices':self.joinstyles, 1702 'fixedChoices':True, 1703 'initialValue':'miter', 1704 'entryfield_entry_width':7, 1705 'labelGridCfg':{'sticky':'w'}, 1706 'widgetGridCfg':{'sticky':'w'}, 1707 'labelCfg':{'text':'solid_joinstyle:'}} 1708 self.widgetDescr['line_linewidth'] = { 1709 'class':'NEThumbWheel','master':'ParamPanel', 1710 'width':60, 'height':21, 'oneTurn':2, 'type':'int', 1711 'wheelPad':2, 'initialValue':1, 1712 'labelCfg':{'text':'linewidth'} } 1713 1714 self.widgetDescr['line_antialiased'] = { 1715 'class':'NECheckButton', 'master':'ParamPanel', 1716 'labelCfg':{'text':'antialiased:'}, 1717 'initialValue':1,} 1718 op = self.outputPortsDescr 1719 op.append(datatype='MPLAxes', name='plot') 1720 1721 code = """def doit(self, y, x=None, lineStyle='solid',color='black',line_antialiased=1,line_linewidth=1,solid_joinstyle='miter',solid_capstyle='projecting',dash_capstyle='butt',dash_joinstyle='miter',drawAreaDef=None): 1722 self.axes.clear() 1723 self.setDrawAreaDef(drawAreaDef) 1724 colorChar = self.colors[color] 1725 lineStyleChar = self.styles[lineStyle] 1726 if x is None: 1727 l = self.axes.plot(y, colorChar+lineStyleChar) 1728 else: 1729 l = self.axes.plot(x, y, colorChar+lineStyleChar) 1730 #line properties 1731 if self.axes.lines: 1732 for l in self.axes.lines: 1733 l.set_linewidth(line_linewidth) 1734 l.set_antialiased(line_antialiased) 1735 l.set_solid_joinstyle(solid_joinstyle) 1736 l.set_solid_capstyle(solid_capstyle) 1737 l.set_dash_capstyle(dash_capstyle) 1738 l.set_dash_joinstyle(dash_joinstyle) 1739 1740 self.canvas.draw() 1741 self.outputData(plot=self.axes) 1742 """ 1743 self.setFunction(code)
1744
1745 -class PlotDateNE(MPLPlottingNode):
1746 """This nodes takes two lists of values and plots the the second against the first. 1747 1748 Input: 1749 y - sequence of dates 1750 x - sequence of dates 1751 optional arguements: 1752 lineStyle - line style 1753 color - color of the line 1754 (lineStyle+colorchar --fmt) 1755 tz - timezone 1756 xdate - is True, the x-axis will be labeled with dates 1757 ydate - is True, the y-axis will be labeled with dates 1758 Output: 1759 plot Matplotlib Axes object 1760 line: - line 1761 pytz is required. 1762 checks for pytz module and returns if not 1763 """
1764 - def __init__(self, name='PlotDate', **kw):
1765 kw['name'] = name 1766 apply( MPLPlottingNode.__init__, (self,), kw ) 1767 self.styles=get_styles() 1768 self.colors=colors 1769 self.joinstyles = Line2D.validJoin 1770 timezones=common_timezones 1771 self.capstyles = Line2D.validCap 1772 ip = self.inputPortsDescr 1773 ip.append(datatype='list', name='y',beforeDisconnect=self.codeBeforeDisconnect) 1774 ip.append(datatype='list', name='x',beforeDisconnect=self.codeBeforeDisconnect) 1775 ip.append(datatype='string', required=False, name='lineStyle') 1776 ip.append(datatype='None', required=False, name='color') 1777 ip.append(datatype='string', required=False, name='tz') 1778 ip.append(datatype='boolean', required=False, name='xdate') 1779 ip.append(datatype='boolean', required=False, name='ydate') 1780 ip.append(datatype='boolean', required=False, name='line_antialiased') 1781 ip.append(datatype='float', required=False, name='line_linewidth') 1782 ip.append(datatype='string', required=False, name='solid_joinstyle') 1783 ip.append(datatype='string', required=False, name='solid_capstyle') 1784 ip.append(datatype='string', required=False, name='dash_capstyle') 1785 ip.append(datatype='string', required=False, name='dash_joinstyle') 1786 ip.append(datatype='MPLDrawArea', required=False,name='drawAreaDef',singleConnection=False) 1787 1788 self.widgetDescr['lineStyle'] = { 1789 'class':'NEComboBox', 'master':'node', 1790 'choices':self.styles.keys(), 1791 'fixedChoices':True, 1792 'initialValue':'circle', 1793 'entryfield_entry_width':7, 1794 'labelGridCfg':{'sticky':'w'}, 1795 'widgetGridCfg':{'sticky':'w'}, 1796 'labelCfg':{'text':'line style:'}} 1797 1798 self.widgetDescr['color'] = { 1799 'class':'NEComboBox', 'master':'node', 1800 'choices':self.colors.keys(), 1801 'fixedChoices':True, 1802 'initialValue':'blue', 1803 'entryfield_entry_width':7, 1804 'labelGridCfg':{'sticky':'w'}, 1805 'widgetGridCfg':{'sticky':'we'}, 1806 'labelCfg':{'text':'color:'}} 1807 1808 self.widgetDescr['tz'] = { 1809 'class':'NEComboBox', 'master':'node', 1810 'choices':timezones, 1811 'fixedChoices':True, 1812 'initialValue':'US/PACIFIC', 1813 'entryfield_entry_width':7, 1814 'labelGridCfg':{'sticky':'w'}, 1815 'widgetGridCfg':{'sticky':'w'}, 1816 'labelCfg':{'text':'timezone:'}} 1817 1818 self.widgetDescr['xdate'] = { 1819 'class':'NECheckButton', 'master':'ParamPanel', 1820 'labelCfg':{'text':'xdate:'}, 1821 'initialValue':1,} 1822 1823 self.widgetDescr['ydate'] = { 1824 'class':'NECheckButton', 'master':'ParamPanel', 1825 'labelCfg':{'text':'ydate:'}, 1826 'initialValue':0,} 1827 1828 self.widgetDescr['dash_capstyle'] = { 1829 'class':'NEComboBox', 'master':'ParamPanel', 1830 'choices':self.capstyles, 1831 'fixedChoices':True, 1832 'initialValue':'butt', 1833 'entryfield_entry_width':7, 1834 'labelGridCfg':{'sticky':'w'}, 1835 'widgetGridCfg':{'sticky':'w'}, 1836 'labelCfg':{'text':'dash_capstyle:'}} 1837 self.widgetDescr['dash_joinstyle'] = { 1838 'class':'NEComboBox', 'master':'ParamPanel', 1839 'choices':self.joinstyles, 1840 'fixedChoices':True, 1841 'initialValue':'miter', 1842 'entryfield_entry_width':7, 1843 'labelGridCfg':{'sticky':'w'}, 1844 'widgetGridCfg':{'sticky':'w'}, 1845 'labelCfg':{'text':'dash _joinstyle:'}} 1846 self.widgetDescr['solid_capstyle'] = { 1847 'class':'NEComboBox', 'master':'ParamPanel', 1848 'choices':self.capstyles, 1849 'fixedChoices':True, 1850 'initialValue':'projecting', 1851 'entryfield_entry_width':7, 1852 'labelGridCfg':{'sticky':'w'}, 1853 'widgetGridCfg':{'sticky':'w'}, 1854 'labelCfg':{'text':'solid_capstyle:'}} 1855 self.widgetDescr['solid_joinstyle'] = { 1856 'class':'NEComboBox', 'master':'ParamPanel', 1857 'choices':self.joinstyles, 1858 'fixedChoices':True, 1859 'initialValue':'miter', 1860 'entryfield_entry_width':7, 1861 'labelGridCfg':{'sticky':'w'}, 1862 'widgetGridCfg':{'sticky':'w'}, 1863 'labelCfg':{'text':'solid_joinstyle:'}} 1864 self.widgetDescr['line_linewidth'] = { 1865 'class':'NEThumbWheel','master':'ParamPanel', 1866 'width':60, 'height':21, 'oneTurn':2, 'type':'int', 1867 'wheelPad':2, 'initialValue':1, 1868 'labelCfg':{'text':'linewidth'} } 1869 1870 self.widgetDescr['line_antialiased'] = { 1871 'class':'NECheckButton', 'master':'ParamPanel', 1872 'labelCfg':{'text':'antialiased:'}, 1873 'initialValue':1,} 1874 op = self.outputPortsDescr 1875 op.append(datatype='MPLAxes', name='plot') 1876 1877 code = """def doit(self, y, x=None, lineStyle='solid',color='black',tz='US/PACIFIC',xdate=True,ydate=False,line_antialiased=1,line_linewidth=1,solid_joinstyle='miter',solid_capstyle='projecting',dash_capstyle='butt',dash_joinstyle='miter',drawAreaDef=None): 1878 try: 1879 from pytz import common_timezones 1880 except: 1881 print "Could not import pytz " 1882 return 1883 self.axes.clear() 1884 self.setDrawAreaDef(drawAreaDef) 1885 colorChar = self.colors[color] 1886 lineStyleChar = self.styles[lineStyle] 1887 rcParams['timezone'] = tz 1888 tz=timezone(tz) 1889 fmt= colorChar+lineStyleChar 1890 l = self.axes.plot_date(x, y, fmt=colorChar+lineStyleChar, tz=tz, xdate= xdate,ydate= ydate) 1891 #line properties 1892 if self.axes.lines: 1893 for l in self.axes.lines: 1894 l.set_linewidth(line_linewidth) 1895 l.set_antialiased(line_antialiased) 1896 l.set_solid_joinstyle(solid_joinstyle) 1897 l.set_solid_capstyle(solid_capstyle) 1898 l.set_dash_capstyle(dash_capstyle) 1899 l.set_dash_joinstyle(dash_joinstyle) 1900 1901 self.canvas.draw() 1902 self.outputData(plot=self.axes) 1903 """ 1904 self.setFunction(code)
1905
1906 -class PieNE(MPLPlottingNode):
1907 """plots a pie diagram for a list of numbers. The size of each wedge 1908 will be the fraction x/sumnumbers). 1909 1910 Input: 1911 fractions - sequence of values 1912 labels - None; sequence of labels (has to match length of factions 1913 explode - None; float or sequence of values which specifies the 1914 fraction of the radius to offset that wedge. 1915 if a single float is given the list is generated automatically 1916 shadow - True; if True, will draw a shadow beneath the pie. 1917 format - None; fromat string used to label the wedges with their 1918 numeric value 1919 Output: 1920 plot - Matplotlib Axes object 1921 patches - sequence of matplotlib.patches.Wedge 1922 texts - list of the label Text instances 1923 autotextsline - list of text instances for the numeric labels (only if 1924 format is not None 1925 """ 1926
1927 - def __init__(self, name='Pie', **kw):
1928 kw['name'] = name 1929 apply( MPLPlottingNode.