~ubuntu-branches/ubuntu/utopic/python-chaco/utopic

« back to all changes in this revision

Viewing changes to docs/scipy_tutorial/chaco_talk.html

  • Committer: Package Import Robot
  • Author(s): Andrew Starr-Bochicchio
  • Date: 2014-06-01 17:04:08 UTC
  • mfrom: (7.2.5 sid)
  • Revision ID: package-import@ubuntu.com-20140601170408-m86xvdjd83a4qon0
Tags: 4.4.1-1ubuntu1
* Merge from Debian unstable. Remaining Ubuntu changes:
 - Let the binary-predeb target work on the usr/lib/python* directory
   as we don't have usr/share/pyshared anymore.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
2
 
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3
 
 
4
 
<html xmlns="http://www.w3.org/1999/xhtml">
5
 
 
6
 
<head>
7
 
<title>Data Exploration with Chaco</title>
8
 
<!-- metadata -->
9
 
<meta name="generator" content="S5" />
10
 
<meta name="version" content="S5 1.1" />
11
 
<meta name="presdate" content="20050728" />
12
 
<meta name="author" content="Eric A. Meyer" />
13
 
<meta name="company" content="Complex Spiral Consulting" />
14
 
<!-- configuration parameters -->
15
 
<meta name="defaultView" content="slideshow" />
16
 
<meta name="controlVis" content="hidden" />
17
 
<!-- style sheet links -->
18
 
<link rel="stylesheet" href="ui/default/slides.css" type="text/css" media="projection" id="slideProj" />
19
 
<link rel="stylesheet" href="ui/default/outline.css" type="text/css" media="screen" id="outlineStyle" />
20
 
<link rel="stylesheet" href="ui/default/print.css" type="text/css" media="print" id="slidePrint" />
21
 
<link rel="stylesheet" href="ui/default/opera.css" type="text/css" media="projection" id="operaFix" />
22
 
<!-- S5 JS -->
23
 
<script src="ui/default/slides.js" type="text/javascript"></script>
24
 
 
25
 
<!-- Syntax Highlighting -->
26
 
<link type="text/css" rel="stylesheet" href="SyntaxHighlighter.css"></link> 
27
 
</head>
28
 
<body>
29
 
 
30
 
<div class="layout">
31
 
<div id="controls"><!-- DO NOT EDIT --></div>
32
 
<div id="currentSlide"><!-- DO NOT EDIT --></div>
33
 
<div id="header"></div>
34
 
<div id="footer">
35
 
<h1>Scipy Tutorial Session, 16 August 2006</h1>
36
 
<h2>(Use the arrow keys or the controls in the lower-right-hand corner to navigate this slideshow.)</h2>
37
 
</div>
38
 
 
39
 
</div>
40
 
 
41
 
 
42
 
<div class="presentation">
43
 
 
44
 
<div class="slide">
45
 
<h1><i>Data Exploration with Chaco</i></h1>
46
 
<p>
47
 
<p><img src="images/chaco_splash.png"></p>
48
 
</p>
49
 
</div>
50
 
 
51
 
 
52
 
<div class="slide">
53
 
<h1>Structure of today's tutorial</h1>
54
 
<ul>
55
 
<li>Overview of Chaco</li>
56
 
<li>Basic plots and interactors</li>
57
 
<li>Creating simple interactors</li>
58
 
<li>Core concepts: data model, layout, interaction model</li>
59
 
<li>More complex plots</li>
60
 
<!-- <li>Creating more complex interactors</li> -->
61
 
<li>Walkthrough of some examples</li>
62
 
</ul>
63
 
</div>
64
 
 
65
 
<div class="slide">
66
 
<h1>Overview</h1>
67
 
<p>
68
 
Chaco is a <em>plot application toolkit</em> for Python.  You use it to build
69
 
stand-alone plotting applications, or embed it inside any application that needs
70
 
to visualize numerical data.
71
 
</p>
72
 
<p>Sample plotting applications:
73
 
<ul>
74
 
<li>batch plotting of data (csv -> png)</li>
75
 
<li>display for realtime data acquisition</li>
76
 
<li>visual plot construction kit</li>
77
 
<li>visual editor for tweaking input parameters to simulations</li>
78
 
<li>mapping and GIS applications</li>
79
 
</ul>
80
 
</p>
81
 
</div>
82
 
 
83
 
<div class="slide">
84
 
<h1>Chaco Features</h1>
85
 
<ul>
86
 
<li>Different rendering layers, backbuffering</li>
87
 
<li>Container model for layout and event dispatch</li>
88
 
<li>Modular and extensible architecture</li>
89
 
<li>Data model/filtering pipeline</li>
90
 
<li>Vector drawing engine</li>
91
 
</ul>
92
 
</div>
93
 
 
94
 
 
95
 
 
96
 
<!-------------------------------------------------------------------------------
97
 
 
98
 
 Part 1.  Basic plots and interactors
99
 
 
100
 
------------------------------------------------------------------------------->
101
 
 
102
 
 
103
 
 
104
 
<div class="slide">
105
 
<h1>A first look</h1>
106
 
<textarea name="highlightcode" class="py:nocontrols">
107
 
# tutorial1.py
108
 
 
109
 
# Create some data
110
 
from scipy import arange, pi, sin
111
 
numpoints = 100
112
 
step = 4*pi / numpoints
113
 
x = arange(-2*pi, 2*pi+step/2, step)
114
 
y = sin(x)
115
 
 
116
 
# Create the plot and set its size
117
 
from enthought import chaco
118
 
myplot = chaco.create_line_plot((x,y), bgcolor="white", add_grid=True, add_axis=True)
119
 
myplot.padding = 50
120
 
myplot.bounds = [400,400]
121
 
 
122
 
# Create a graphics context for offline rendering
123
 
plot_gc = chaco.PlotGraphicsContext(myplot.outer_bounds)
124
 
plot_gc.render_component(myplot)
125
 
plot_gc.save("tutorial1.png")
126
 
</textarea>
127
 
</div>
128
 
 
129
 
<div class="slide">
130
 
<h1>tutorial1.py</h1>
131
 
<img src="images/tutorial1.png">
132
 
</div>
133
 
 
134
 
 
135
 
<div class="slide">
136
 
<h1>Creating a window</h1>
137
 
<textarea name="highlightcode" class="py:nocontrols">
138
 
# tutorial2.py
139
 
import wx
140
 
from enthought import chaco
141
 
 
142
 
# Import the plot from Tutorial 1
143
 
from tutorial1 import myplot
144
 
 
145
 
from enthought.enable2.wx_backend.api import Window
146
 
class PlotFrame(wx.Frame):
147
 
    def __init__(self, *args, **kw):
148
 
        kw["size"] = (600,600)
149
 
        wx.Frame.__init__( *(self,) + args, **kw )
150
 
        
151
 
        # Use Enable.Window to bridge between the vector-drawing world of Chaco and WX
152
 
        self.plot_window = Window(parent=self, component=myplot)
153
 
        
154
 
        sizer = wx.BoxSizer(wx.HORIZONTAL)
155
 
        sizer.Add(self.plot_window.control, 1, wx.EXPAND)
156
 
        self.SetSizer(sizer)
157
 
        self.SetAutoLayout(True)
158
 
        self.Show(True)
159
 
        return
160
 
 
161
 
</textarea>
162
 
</div>
163
 
 
164
 
<div class="slide">
165
 
<h1>Opening the window</h1>
166
 
<p><h2>Normal python (standalone app)</h2>
167
 
<textarea name="highlightcode" class="py:nocontrols">
168
 
from tutorial2 import PlotFrame
169
 
import wx
170
 
app = wx.PySimpleApp()
171
 
frame = PlotFrame(None)
172
 
app.MainLoop()
173
 
</textarea>
174
 
</p><p>
175
 
<h2>From within IPython</h2>
176
 
<textarea name="highlightcode" class="py:nocontrols">
177
 
# This requires invoking IPython as "ipython -pylab" or "ipython -wthread"
178
 
 
179
 
from tutorial2 import PlotFrame
180
 
frame = PlotFrame(None)
181
 
</textarea>
182
 
</p>
183
 
</div>
184
 
 
185
 
<div class="slide">
186
 
<h1>Fun from within IPython</h1>
187
 
We can tweak plot attributes on the fly:
188
 
<textarea name="highlightcode" class="py:nocontrols">
189
 
plot.vgrid.visible = False
190
 
plot.x_axis.visible = False
191
 
plot.request_redraw()
192
 
</textarea>
193
 
</div>
194
 
 
195
 
<div class="slide">
196
 
<h1>Fun from within IPython</h1>
197
 
We can even write functions to do the tweaking for us!
198
 
<textarea name="highlightcode" class="py:nocontrols">
199
 
# tutorial2_ipython.py
200
 
 
201
 
def ytitle(text):
202
 
    plot.y_axis.title = text
203
 
    plot.request_redraw()
204
 
 
205
 
def xrange(low, high):
206
 
    plot.x_mapper.range.low = low
207
 
    plot.x_mapper.range.high = high
208
 
    plot.request_redraw()
209
 
 
210
 
def yrange(low, high):
211
 
    plot.y_mapper.range.low = low
212
 
    plot.y_mapper.range.high = high
213
 
    plot.request_redraw()
214
 
</textarea>
215
 
</div>
216
 
 
217
 
 
218
 
<div class="slide">
219
 
<h1>The Joy of Traits</h1>
220
 
<p>
221
 
Since all Chaco primitives use traits, we can easily bring up property sheets.
222
 
</p>
223
 
</div>
224
 
 
225
 
 
226
 
<div class="slide">
227
 
<h1>Adding a basic interactor</h1>
228
 
<p>All Chaco components can have tools on them, and any events they receive get forwarded on to
229
 
their tools.
230
 
 
231
 
<textarea name="highlightcode" class="py:nocontrols">
232
 
# tutorial3.py
233
 
 
234
 
from tutorial2 import myplot, PlotFrame, main
235
 
 
236
 
from enthought.chaco.tools import PanTool
237
 
 
238
 
myplot.tools.append(PanTool(myplot))
239
 
</textarea>
240
 
</p>
241
 
</div>
242
 
 
243
 
 
244
 
<div class="slide">
245
 
<h1>Adding zoom</h1>
246
 
<p>Because the zoom tool draws a visible "zoom box", we need to add it to the list
247
 
of overlays instead of the list of tools.  (It will still get events.)
248
 
<textarea name="highlightcode" class="py:nocontrols">
249
 
# tutorial4.py
250
 
 
251
 
from tutorial2 import myplot, PlotFrame, main
252
 
 
253
 
from enthought.chaco.tools import SimpleZoom
254
 
 
255
 
# Create an instance of the tool and add it as an overlay..
256
 
myplot.overlays.append(SimpleZoom(myplot, tool_mode="box", always_on=True))
257
 
</textarea>
258
 
</p>
259
 
</div>
260
 
 
261
 
 
262
 
<div class="slide">
263
 
<h1>Coordinating different tools</h1>
264
 
PanTool and SimpleZoom both key off the left mouse click/drag.  Fortunately,
265
 
PanTool is not a "stateful" interaction, and there is a way to tell SimpleZoom
266
 
to play nicely with others:
267
 
<textarea name="highlightcode" class="py:nocontrols">
268
 
# tutorial5.py
269
 
 
270
 
from tutorial2 import myplot, PlotFrame, main
271
 
from enthought.chaco.tools import PanTool, SimpleZoom
272
 
 
273
 
myplot.tools.append(PanTool(myplot))
274
 
 
275
 
zoom = SimpleZoom(myplot, tool_mode="box", always_on=False)
276
 
 
277
 
myplot.overlays.append(zoom)
278
 
</textarea>
279
 
</div>
280
 
 
281
 
 
282
 
<div class="slide">
283
 
<h1>Writing our first interactor</h1>
284
 
Diagnostic tool to dump out the events we are getting:
285
 
<textarea name="highlightcode" class="py:nocontrols">
286
 
# tutorial6.py
287
 
 
288
 
# AbstractController is the base class for non-rendering tools
289
 
from enthought.chaco.api import AbstractController
290
 
 
291
 
class EventPrinter(AbstractController):
292
 
    
293
 
    def dispatch(self, event, suffix):
294
 
        # event' is a MouseEvent or KeyEvent object from the enable2
295
 
        # package, and suffix is a text string
296
 
        print suffix, "event received at (%d,%d)" % (event.x, event.y)
297
 
 
298
 
 
299
 
from tutorial2 import myplot, PlotFrame, main
300
 
 
301
 
myplot.tools.append(EventPrinter(myplot))
302
 
</textarea>
303
 
</div>
304
 
 
305
 
 
306
 
<div class="slide">
307
 
<h1>Looking at data</h1>
308
 
We don't really want to know the mouse position; we want to know about
309
 
coordinates in data space:
310
 
 
311
 
<textarea name="highlightcode" class="py:nocontrols">
312
 
# tutorial7.py
313
 
 
314
 
from enthought.chaco.api import AbstractController
315
 
 
316
 
class DataPrinter(AbstractController):
317
 
    def dispatch(self, event, suffix):
318
 
        # We are assuming that self.component is an X-Y plot
319
 
        x = self.component.x_mapper.map_data(event.x)
320
 
        y = self.component.y_mapper.map_data(event.y)
321
 
        print suffix, "event received at (%d,%d)" % (x, y)
322
 
 
323
 
 
324
 
from tutorial2 import myplot, PlotFrame, main
325
 
 
326
 
myplot.tools.append(DataPrinter(myplot))
327
 
</textarea>
328
 
</div>
329
 
 
330
 
 
331
 
<!-------------------------------------------------------------------------------
332
 
 
333
 
 Part 2.  Digging deeper - the data model and understanding factories
334
 
 
335
 
------------------------------------------------------------------------------->
336
 
 
337
 
 
338
 
<div class="slide">
339
 
<h1>Digging deeper</h1>
340
 
<textarea name="highlightcode" class="py:nocontrols">
341
 
# from tutorial1.py
342
 
 
343
 
myplot = chaco.create_line_plot((x,y))
344
 
</textarea>
345
 
 
346
 
What does the create_line_plot() actually do?
347
 
<ul>
348
 
    <li>creates datasources</li>
349
 
    <li>creates range objects and mappers</li>
350
 
    <li>creates the plot object</li>
351
 
</ul>
352
 
</div>
353
 
 
354
 
 
355
 
 
356
 
<div class="slide">
357
 
<h1>Datasources</h1>
358
 
<textarea name="highlightcode" class="py:nocontrols">
359
 
# plot_factory.py:create_line_plot()
360
 
 
361
 
index_data, value_data = transpose(data)
362
 
index = ArrayDataSource(index_data)
363
 
value = ArrayDataSource(value_data, sort_order="none")
364
 
</textarea>
365
 
 
366
 
ArrayDataSource is just a subclass of AbstractDataSource which works with
367
 
Numeric/numpy arrays.
368
 
<textarea name="highlightcode" class="py:nocontrols">
369
 
class AbstractDataSource(HasTraits):
370
 
    value_dimension = DimensionTrait
371
 
    index_dimension = DimensionTrait
372
 
    metadata = Dict
373
 
 
374
 
    get_data() -> array
375
 
    get_data_mask() -> array, mask
376
 
    is_masked() -> bool
377
 
    get_size() -> int
378
 
    get_bounds() -> array
379
 
</textarea>
380
 
</div>
381
 
 
382
 
<div class="slide">
383
 
<h1>Ranges, Mappers, and the Plot</h1>
384
 
<textarea name="highlightcode" class="py:nocontrols">
385
 
    index_range = DataRange()
386
 
    index_range.add(index)
387
 
    index_mapper = LinearMapper(range=index_range)
388
 
 
389
 
    value_range = DataRange()
390
 
    value_range.add(value)
391
 
    value_mapper = value_mapper_class(range=value_range)
392
 
 
393
 
    plot = LinePlot(index=index, value=value,
394
 
                index_mapper = index_mapper,
395
 
                value_mapper = value_mapper,
396
 
                orientation = orientation,
397
 
                color = color,
398
 
                line_width = width,
399
 
                line_style = dash,
400
 
                border_visible = True)
401
 
 
402
 
</textarea>
403
 
</div>
404
 
 
405
 
<!--
406
 
<div class="slide">
407
 
<h1>Decorating with Axes and Grids</h1>
408
 
<textarea name="highlightcode" class="py:nocontrols">
409
 
def add_default_axes(plot, orientation="normal", vtitle="",htitle=""):
410
 
    if orientation == "normal":
411
 
        v_mapper = plot.value_mapper
412
 
        h_mapper = plot.index_mapper
413
 
    else:
414
 
        v_mapper = plot.index_mapper
415
 
        h_mapper = plot.value_mapper
416
 
 
417
 
    left = PlotAxis(orientation='left',
418
 
                    title= vtitle,
419
 
                    mapper=v_mapper,
420
 
                    component=plot)
421
 
    
422
 
    bottom = PlotAxis(orientation='bottom',
423
 
                    title= htitle,
424
 
                    mapper=h_mapper,
425
 
                    component=plot)
426
 
 
427
 
    plot.underlays.append(left)
428
 
    plot.underlays.append(bottom)
429
 
</textarea>
430
 
Adding grids is basically the same code.
431
 
</div>
432
 
-->
433
 
 
434
 
<div class="slide">
435
 
<h1>Two plots</h1>
436
 
We can use a container to put two plots on the screen.
437
 
<textarea name="highlightcode" class="py:nocontrols" rows="24">
438
 
    def _create_plot(self):
439
 
        x = arange(-5.0, 15.0, 20.0/100)
440
 
        
441
 
        y = jn(0, x)
442
 
        left_plot = create_line_plot((x,y), bgcolor="white",add_grid=True, add_axis=True)
443
 
        left_plot.tools.append(PanTool(left_plot))
444
 
        self.left_plot = left_plot
445
 
        
446
 
        y = jn(1, x)
447
 
        right_plot = create_line_plot((x,y), bgcolor="white", add_grid=True, add_axis=True)
448
 
        right_plot.tools.append(PanTool(right_plot))
449
 
        right_plot.y_axis.orientation = "right"
450
 
        self.right_plot = right_plot
451
 
        
452
 
        container = HPlotContainer(spacing=20, padding=50, bgcolor="lightgray")
453
 
        container.add(left_plot)
454
 
        container.add(right_plot)        
455
 
        return container
456
 
    
457
 
</textarea>
458
 
</div>
459
 
 
460
 
 
461
 
<div class="slide">
462
 
<h1>Connecting the two plots</h1>
463
 
We're going to link the X dimension of the two plots.  Really, all we have to do to
464
 
achieve this is to set the horizontal range on the two plots to be the same.
465
 
<textarea name="highlightcode" class="py:nocontrols">
466
 
# tutorial9.py 
467
 
 
468
 
class PlotFrame2(PlotFrame):
469
 
    
470
 
    def _create_plot(self):
471
 
        
472
 
        container = super(PlotFrame2, self)._create_plot()
473
 
        
474
 
        self.right_plot.index_mapper.range = self.left_plot.index_mapper.range
475
 
        
476
 
        return container
477
 
   
478
 
</textarea>
479
 
</div>
480
 
 
481
 
<div class="slide">
482
 
<h1>Connecting the two plots (cont.)</h1>
483
 
We can connect the Y dimension, too.  And let's throw in a zoom tool.
484
 
<textarea name="highlightcode" class="py:nocontrols">
485
 
# tutorial9b.py
486
 
 
487
 
self.right_plot.value_mapper.range = self.left_plot.value_mapper.range
488
 
 
489
 
self.left_plot.overlays.append(
490
 
    SimpleZoom(self.left_plot, tool_mode="box", always_on=False))
491
 
 
492
 
self.right_plot.overlays.append(
493
 
    SimpleZoom(self.right_plot, tool_mode="box", always_on=False))
494
 
    
495
 
</textarea>
496
 
</div>
497
 
 
498
 
 
499
 
<div class="slide">
500
 
<h1>Linked views, but not connected data</h1>
501
 
Adding a line inspector will show the problem.
502
 
<textarea name="highlightcode" class="py:nocontrols">
503
 
# tutorial10.py
504
 
 
505
 
from tutorial9b import PlotFrame2
506
 
 
507
 
class PlotFrame3(PlotFrame2):
508
 
    def _create_plot(self):
509
 
        container = super(PlotFrame2, self)._create_plot()
510
 
        
511
 
        self.left_plot.overlays.append(
512
 
            LineInspector(component=self.left_plot,
513
 
                          write_metadata=True,
514
 
                          is_listener=True))
515
 
        
516
 
        self.right_plot.overlays.append(
517
 
            LineInspector(component=self.right_plot,
518
 
                          write_metadata=True,
519
 
                          is_listener=True))
520
 
        return container
521
 
    
522
 
</textarea>
523
 
</div>
524
 
 
525
 
<div class="slide">
526
 
<h1>Connecting the data</h1>
527
 
 
528
 
<textarea name="highlightcode" class="py:nocontrols">
529
 
# tutorial10b.py
530
 
 
531
 
class PlotFrame3(PlotFrame2):
532
 
    def _create_plot(self):
533
 
        container = super(PlotFrame2, self)._create_plot()
534
 
        
535
 
        self.left_plot.overlays.append(
536
 
            LineInspector(component=self.left_plot,
537
 
                          write_metadata=True,
538
 
                          is_listener=True))
539
 
        
540
 
        self.right_plot.overlays.append(
541
 
            LineInspector(component=self.right_plot,
542
 
                          write_metadata=True,
543
 
                          is_listener=True))
544
 
        
545
 
        self.right_plot.index = self.left_plot.index 
546
 
        
547
 
        return container
548
 
    
549
 
</textarea>
550
 
</div>
551
 
 
552
 
 
553
 
<div class="slide">
554
 
<h1>Why Index-Value instead of X-Y?</h1>
555
 
Because you are then immune to a plot's physical layout.
556
 
<textarea name="highlightcode" class="py:nocontrols">
557
 
# tutorial11.py
558
 
 
559
 
class PlotFrame4(PlotFrame3):
560
 
    def _create_plot(self):
561
 
        container = super(PlotFrame4, self)._create_plot()
562
 
        
563
 
        plot = self.right_plot
564
 
        plot.orientation = "v"
565
 
        plot.hgrid.mapper = plot.index_mapper
566
 
        plot.vgrid.mapper = plot.value_mapper
567
 
        plot.y_axis.mapper = plot.index_mapper
568
 
        plot.x_axis.mapper = plot.value_mapper
569
 
        
570
 
        self.left_plot.overlays.append(
571
 
                LineInspector(component=self.left_plot,
572
 
                              write_metadata=True,
573
 
                              is_listener=True, color="blue",
574
 
                              axis="value"))
575
 
        
576
 
        self.right_plot.overlays.append(
577
 
                LineInspector(component=self.right_plot,
578
 
                              write_metadata=True,
579
 
                              is_listener=True, color="blue",
580
 
                              axis="value"))
581
 
        return container
582
 
</textarea>
583
 
</div>
584
 
 
585
 
 
586
 
<!-------------------------------------------------------------------------------
587
 
 
588
 
 Part 3.  Real-world examples 
589
 
 
590
 
------------------------------------------------------------------------------->
591
 
 
592
 
<div class="slide">
593
 
<h1>Examples</h1>
594
 
</div>
595
 
 
596
 
<div class="slide">
597
 
<h1>Visual Components</h1>
598
 
<ul>
599
 
<li>Renderers</li>
600
 
<li>Containers</li>
601
 
<li>Tools and tool overlays</li>
602
 
<li>Legends, annotations, etc.</li>
603
 
</ul>
604
 
</div>
605
 
 
606
 
<div class="slide">
607
 
<h1>Visual Components (cont.)</h1>
608
 
<ul>
609
 
<li>have bounds, position, padding, border, bgcolor</li>
610
 
<li>can be placed inside containers</li>
611
 
<li>can be horizontally and vertically resized (or not)</li>
612
 
<li>implement draw (and request draw on their underlays and overlays)</li>
613
 
<li>implement dispatch (and dispatch to underlays and overlays)</li>
614
 
</ul>
615
 
</div>
616
 
 
617
 
 
618
 
<div class="slide">
619
 
<h1>More about Containers</h1>
620
 
<ul>
621
 
<li>Layout</li>
622
 
<li>Dispatch</li>
623
 
<li>Draw order & backbuffering</li>
624
 
</ul>
625
 
</div>
626
 
 
627
 
 
628
 
<div class="slide">
629
 
<h1>Walkthrough of interesting examples</h1>
630
 
</div>
631
 
 
632
 
 
633
 
<div class="slide">
634
 
<h1>How to get it</h1>
635
 
<p><font size=+5><a href="http://code.enthought.com/chaco">http://code.enthought.com/chaco</a></font></p>
636
 
<p>Mailing lists: chaco-users@enthought.com, enthought-dev@enthought.com</p>
637
 
<p>Get Enthon!  http://code.enthought.com/enthon</p>
638
 
</div>
639
 
 
640
 
 
641
 
</div>
642
 
 
643
 
<script language="javascript" src="Scripts/shCore.js"></script>  
644
 
<script language="javascript" src="Scripts/shBrushPython.js"></script>  
645
 
<script language="javascript" src="Scripts/shBrushXml.js"></script>  
646
 
<script language="javascript">  
647
 
    dp.SyntaxHighlighter.HighlightAll('highlightcode');  
648
 
</script>  
649
 
 
650
 
 
651
 
</body>
652
 
</html>