1 """This modules implements I{View-->Plot} dialog.
2
3 Classes:
4 * SettingsDialog: sets up the settings dialog.
5 * ASCIIToNetCDFConversionDialog: creates I{View-->Plot} dialog used to plot NetCDF variables.
6 """
7
8
9 import os
10 import sys
11
12
13 import pylab
14 import matplotlib
15 from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
16 from matplotlib.colors import ColorConverter, LogNorm, Normalize, rgb2hex
17 from matplotlib.figure import Figure
18 from matplotlib.widgets import Cursor
19
20
21 import _tkinter
22 from tkFileDialog import askopenfilename, asksaveasfilename
23 from Tkinter import *
24 import tkColorChooser
25
26
27 from Scientific.IO.NetCDF import _NetCDFFile, NetCDFFile
28 from Scientific import N as Num
29
30
31 from MMTK.Trajectory import Trajectory
32
33
34 from nMOLDYN.Core.Error import Error
35 from nMOLDYN.Core.Logger import LogMessage
36 from nMOLDYN.Core.Preferences import PREFERENCES
37 from nMOLDYN.GUI.Widgets import *
38
39
40
41 interpolations = ['bessel', 'bilinear', 'bicubic', 'blackman', 'catrom', 'hamming', 'hermite', 'hanning',\
42 'gaussian', 'kaiser', 'lanczos', 'mitchell', 'nearest', 'spline16', 'spline36', 'quadric', 'sinc']
43
44
45 colorMaps = ['autumn', 'bone', 'cool', 'copper', 'flag', 'gray', 'hot', 'hsv', 'jet', 'pink', 'prism',\
46 'spring', 'summer', 'winter', 'spectral']
47
48
49 lineStyles = ['-', '--', '-.', ':', 'None']
50
51
52 markerStyles = ['+', '.', '<', '>', 'o', 'p', 's', 'v', 'x', '|', 'None']
53
54 axisScales = ['linear', 'log']
55
57 """Sets up a dialog tp perform some settings on the plots.
58 """
59
61 """The constructor.
62
63 @param parent: the parent widget.
64 """
65
66 Toplevel.__init__(self, parent)
67 self.transient(parent)
68
69 self.parent = parent
70
71 self.widgets = {}
72 self.settings = {}
73
74 self.selectedPlot = None
75
76 body = Frame(self)
77 self.initial_focus = self.body(body)
78 body.grid(row = 0, column = 0, sticky = EW)
79
80 self.buttonbox()
81
82 self.grab_set()
83
84 if not self.initial_focus:
85 self.initial_focus = self
86
87 self.protocol("WM_DELETE_WINDOW", self.cancel)
88
89 self.resizable(width = NO, height = NO)
90
91 self.title = 'Settings'
92
93 self.geometry("+%d+%d" % (parent.winfo_rootx()+50, parent.winfo_rooty()+50))
94
95 self.initial_focus.focus_set()
96
97 self.wait_window(self)
98
99 - def body(self, master):
100 """
101 Create dialog body. Return widget that should have initial focus.
102 """
103
104 settingsFrame = LabelFrame(master, text = 'Settings', bd = 2, relief = GROOVE)
105 settingsFrame.grid(row = 0, column = 0, sticky = EW, padx = 3, pady = 3)
106 settingsFrame.grid_columnconfigure(0, weight = 1)
107 settingsFrame.grid_rowconfigure(0, weight = 1)
108
109 self.gFrame = LabelFrame(settingsFrame, text = 'Global', bd = 2, relief = GROOVE)
110 self.gFrame.grid(row = 0, column = 0, sticky = "NEW", padx = 3, pady = 3)
111 self.gFrame.grid_columnconfigure(0, weight = 1)
112 self.gFrame.grid_rowconfigure(0, weight = 1)
113
114
115 self.initGlobalSettings()
116
117
118 self.widgets['plotTitle'] = ComboStringEntry(self.gFrame,frameLabel = 'Plot title', contents = self.settings['plotTitle'])
119 self.widgets['plotTitle'].grid(row = 1, column = 0, sticky = "NEW")
120 self.widgets['plotTitle'].grid_columnconfigure(0, weight = 1)
121 self.widgets['plotTitle'].entry.bind('<FocusOut>', lambda event : self.changeSettings(event, 'plotTitle'))
122
123
124 self.widgets['xLabel'] = ComboStringEntry(self.gFrame,frameLabel = 'X label', contents = self.settings['xLabel'])
125 self.widgets['xLabel'].grid(row = 2, column = 0, sticky = "NEW")
126 self.widgets['xLabel'].grid_columnconfigure(0, weight = 1)
127 self.widgets['xLabel'].entry.bind('<FocusOut>', lambda event : self.changeSettings(event, 'xLabel'))
128
129
130 self.widgets['yLabel'] = ComboStringEntry(self.gFrame,frameLabel = 'Y label', contents = self.settings['yLabel'])
131 self.widgets['yLabel'].grid(row = 3, column = 0, sticky = "NEW")
132 self.widgets['yLabel'].grid_columnconfigure(0, weight = 1)
133 self.widgets['yLabel'].entry.bind('<FocusOut>', lambda event : self.changeSettings(event, 'yLabel'))
134
135
136 self.widgets['xTicks'] = ComboStringEntry(self.gFrame,frameLabel = 'X ticks', contents = self.settings['xTicks'])
137 self.widgets['xTicks'].grid(row = 4, column = 0, sticky = "NEW")
138 self.widgets['xTicks'].grid_columnconfigure(0, weight = 1)
139 self.widgets['xTicks'].entry.bind('<FocusOut>', lambda event : self.changeSettings(event, 'xTicks'))
140
141
142 self.widgets['xTicksSize'] = ComboIntegerEntry(self.gFrame, frameLabel = 'X ticks size', contents = self.settings['xTicksSize'])
143 self.widgets['xTicksSize'].grid(row = 5, column = 0, sticky = "NEW")
144 self.widgets['xTicksSize'].grid_columnconfigure(0, weight = 1)
145 self.widgets['xTicksSize'].entry.bind('<FocusOut>', lambda event : self.changeSettings(event, 'xTicksSize'))
146
147
148 self.widgets['xTicksAngle'] = ComboIntegerEntry(self.gFrame, frameLabel = 'X ticks angle', contents = self.settings['xTicksAngle'])
149 self.widgets['xTicksAngle'].grid(row = 6, column = 0, sticky = "NEW")
150 self.widgets['xTicksAngle'].grid_columnconfigure(0, weight = 1)
151 self.widgets['xTicksAngle'].entry.bind('<FocusOut>', lambda event : self.changeSettings(event, 'xTicksAngle'))
152
153
154 self.widgets['yTicks'] = ComboStringEntry(self.gFrame,frameLabel = 'Y ticks', contents = self.settings['yTicks'])
155 self.widgets['yTicks'].grid(row = 7, column = 0, sticky = "NEW")
156 self.widgets['yTicks'].grid_columnconfigure(0, weight = 1)
157 self.widgets['yTicks'].entry.bind('<FocusOut>', lambda event : self.changeSettings(event, 'yTicks'))
158
159
160 self.widgets['yTicksSize'] = ComboIntegerEntry(self.gFrame, frameLabel = 'Y ticks size', contents = self.settings['yTicksSize'])
161 self.widgets['yTicksSize'].grid(row = 8, column = 0, sticky = "NEW")
162 self.widgets['yTicksSize'].grid_columnconfigure(0, weight = 1)
163 self.widgets['yTicksSize'].entry.bind('<FocusOut>', lambda event : self.changeSettings(event, 'yTicksSize'))
164
165
166 self.widgets['yTicksAngle'] = ComboIntegerEntry(self.gFrame, frameLabel = 'Y ticks angle', contents = self.settings['yTicksAngle'])
167 self.widgets['yTicksAngle'].grid(row = 9, column = 0, sticky = "NEW")
168 self.widgets['yTicksAngle'].grid_columnconfigure(0, weight = 1)
169 self.widgets['yTicksAngle'].entry.bind('<FocusOut>', lambda event : self.changeSettings(event, 'yTicksAngle'))
170
171
172 self.widgets['xRange'] = ComboStringEntry(self.gFrame,frameLabel = 'X range', contents = self.settings['xRange'])
173 self.widgets['xRange'].grid(row = 10, column = 0, sticky = "NEW")
174 self.widgets['xRange'].grid_columnconfigure(0, weight = 1)
175 self.widgets['xRange'].entry.bind('<FocusOut>', lambda event : self.changeSettings(event, 'xRange'))
176
177
178 self.widgets['yRange'] = ComboStringEntry(self.gFrame,frameLabel = 'Y range', contents = self.settings['yRange'])
179 self.widgets['yRange'].grid(row = 11, column = 0, sticky = "NEW")
180 self.widgets['yRange'].grid_columnconfigure(0, weight = 1)
181 self.widgets['yRange'].entry.bind('<FocusOut>', lambda event : self.changeSettings(event, 'yRange'))
182
183 if len(self.parent.figure.gca().get_images()) == 0:
184 v = axisScales.index(self.settings['xScale'])
185
186 self.widgets['xScale'] = ComboRadiobutton(self.gFrame,\
187 frameLabel = 'X scale',\
188 contents = axisScales,\
189 default = v,\
190 layout = (1,2))
191 self.widgets['xScale'].grid(row = 12, column = 0, sticky = "NEW")
192 self.widgets['xScale'].grid_columnconfigure(0, weight = 1)
193 for r in self.widgets['xScale'].radio:
194 r.bind('<ButtonRelease-1>', lambda event : self.changeSettings(event, 'xScale'))
195
196 v = axisScales.index(self.settings['yScale'])
197
198 self.widgets['yScale'] = ComboRadiobutton(self.gFrame,\
199 frameLabel = 'Y scale',\
200 contents = axisScales,\
201 default = v,\
202 layout = (1,2))
203 self.widgets['yScale'].grid(row = 13, column = 0, sticky = "NEW")
204 self.widgets['yScale'].grid_columnconfigure(0, weight = 1)
205 for r in self.widgets['yScale'].radio:
206 r.bind('<ButtonRelease-1>', lambda event : self.changeSettings(event, 'yScale'))
207
208 else:
209 v = axisScales.index(self.settings['zScale'])
210
211 self.widgets['zScale'] = ComboRadiobutton(self.gFrame,\
212 frameLabel = 'Z scale',\
213 contents = axisScales,\
214 default = v,\
215 layout = (1,2))
216 self.widgets['zScale'].grid(row = 12, column = 0, sticky = "NEW")
217 self.widgets['zScale'].grid_columnconfigure(0, weight = 1)
218 for r in self.widgets['zScale'].radio:
219 r.bind('<ButtonRelease-1>', lambda event : self.changeSettings(event, 'zScale'))
220
221
222 self.widgets['gridWidth'] = ComboFloatEntry(self.gFrame, frameLabel = 'Grid width', contents = self.settings['gridWidth'])
223 self.widgets['gridWidth'].grid(row = 15, column = 0, sticky = "NEW")
224 self.widgets['gridWidth'].grid_columnconfigure(0, weight = 1)
225 self.widgets['gridWidth'].entry.bind('<FocusOut>', lambda event : self.changeSettings(event, 'gridWidth'))
226
227
228 self.widgets['gridStyle'] = ComboSpinbox(self.gFrame, frameLabel = 'Grid style', default = self.settings['gridStyle'], contents = tuple(lineStyles))
229 self.widgets['gridStyle'].grid(row = 16, column = 0, sticky = "NEW")
230 self.widgets['gridStyle'].grid_columnconfigure(0, weight = 1)
231 self.widgets['gridStyle'].spinbox.config({'width' : 10, 'command' : lambda : self.changeSettings(None, 'gridStyle')})
232
233
234 self.widgets['gridColor'] = ComboButton(self.gFrame,\
235 frameLabel = 'Grid color')
236 self.widgets['gridColor'].grid(row = 17, column = 0, sticky = "NEW")
237 self.widgets['gridColor'].grid_columnconfigure(0, weight = 1)
238 self.widgets['gridColor'].button.config({'bg' : self.settings['gridColor'],\
239 'activebackground' : self.settings['gridColor'],\
240 'width' : 1,\
241 'command' : lambda : self.changeSettings(None, 'gridColor')})
242 self.widgets['gridColor'].results = self.settings['gridColor']
243
244 self.pFrame = LabelFrame(settingsFrame, text = 'Plot', bd = 2, relief = GROOVE)
245 self.pFrame.grid(row = 0, column = 1, sticky = "NEW", padx = 3, pady = 3)
246 self.pFrame.grid_columnconfigure(1, weight = 1)
247 self.pFrame.grid_rowconfigure(0, weight = 1)
248
249
250 self.plots = ComboListbox(self.pFrame, frameLabel = 'Available plots', contents = [])
251 self.plots.grid(row = 0, column = 0, sticky = "NEW")
252 self.plots.grid_columnconfigure(0, weight = 1)
253 self.plots.grid_rowconfigure(0, weight = 1)
254 self.plots.lb.config({'exportselection' : 0, 'width' : 28, 'height' : 4, 'selectmode' : SINGLE})
255 self.plots.lb.bind('<ButtonRelease-1>', self.addPlotSettingsWidgets)
256
257 if self.parent.figure.gca().get_images():
258 self.plots.lb.insert(END, self.parent.figure.gca().get_images()[0].get_label())
259
260 else:
261 for f in self.parent.figure.gca().get_lines():
262 self.plots.lb.insert(END, f.get_label())
263
264 self.plots.lb.selection_set(0)
265
266 self.addPlotSettingsWidgets()
267
268 return None
269
288
289
290 - def ok(self, event = None):
291
292 if not self.validate():
293 self.initial_focus.focus_set()
294 return
295
296 self.withdraw()
297 self.update_idletasks()
298
299 self.apply()
300
301 self.cancel()
302
303 - def cancel(self, event=None):
304
305
306 self.parent.grab_set()
307 self.parent.focus_set()
308 self.destroy()
309
310
312
313 try:
314 self.storeSettings()
315
316 except:
317 LogMessage('warning','Bad input. Please try again.',['gui'])
318 return False
319
320 return True
321
323 try:
324 for k, v in self.settings.items():
325 if k == 'plotTitle':
326 self.parent.figure.gca().set_title(v)
327 elif k == 'xRange':
328 xMin, xMax = [float(vv) for vv in v.split('-')]
329 self.parent.figure.gca().set_xlim((xMin, xMax))
330 elif k == 'yRange':
331 yMin, yMax = [float(vv) for vv in v.split('-')]
332 self.parent.figure.gca().set_ylim((yMin,yMax))
333 elif k == 'xLabel':
334 self.parent.figure.gca().set_xlabel(v)
335 elif k == 'yLabel':
336 self.parent.figure.gca().set_ylabel(v)
337 elif k == 'xScale':
338 self.parent.figure.gca().set_xscale(v)
339 elif k == 'yScale':
340 self.parent.figure.gca().set_yscale(v)
341 elif k == 'zScale':
342 if v == 'linear':
343 self.parent.figure.gca().get_images()[self.selectedPlot].set_norm(Normalize())
344 else:
345 self.parent.figure.gca().get_images()[self.selectedPlot].set_norm(LogNorm())
346 elif k == 'xTicks':
347 ticks, ticksLabels = [eval(t) for t in v.split(';')]
348 ticks = [float(t) for t in ticks]
349 ticksLabels = [str(t) for t in ticksLabels]
350
351 self.parent.figure.gca().set_xticks(ticks)
352 self.parent.figure.gca().set_xticklabels(ticksLabels)
353 elif k == 'xTicksSize':
354 [l.set_size(int(v)) for l in self.parent.figure.gca().get_xticklabels()]
355 elif k == 'xTicksAngle':
356 [l.set_rotation(int(v)) for l in self.parent.figure.gca().get_xticklabels()]
357 elif k == 'yTicks':
358 ticks, ticksLabels = [eval(t) for t in v.split(';')]
359 ticks = [float(t) for t in ticks]
360 ticksLabels = [str(t) for t in ticksLabels]
361
362 self.parent.figure.gca().set_yticks(ticks)
363 self.parent.figure.gca().set_yticklabels(ticksLabels)
364 elif k == 'yTicksSize':
365 [l.set_size(int(v)) for l in self.parent.figure.gca().get_yticklabels()]
366 elif k == 'yTicksAngle':
367 [l.set_rotation(int(v)) for l in self.parent.figure.gca().get_yticklabels()]
368 elif k == 'gridWidth':
369 self.parent.figure.gca().grid(True, linewidth = v)
370 elif k == 'gridStyle':
371 self.parent.figure.gca().grid(True, linestyle = v)
372 elif k == 'gridColor':
373 self.parent.figure.gca().grid(True, color = v)
374 elif isinstance(k, int):
375 for kk, vv in v.items():
376 if kk == 'lineLabel':
377 self.parent.figure.gca().get_lines()[k].set_label(vv)
378 self.plots.lb.delete(k)
379 self.plots.lb.insert(k, vv)
380 elif kk == 'lineWidth':
381 self.parent.figure.gca().get_lines()[k].set_linewidth(vv)
382 elif kk == 'lineStyle':
383 self.parent.figure.gca().get_lines()[k].set_linestyle(vv)
384 elif kk == 'lineColor':
385 self.parent.figure.gca().get_lines()[k].set_color(vv)
386 elif kk == 'markerSize':
387 self.parent.figure.gca().get_lines()[k].set_markersize(vv)
388 elif kk == 'markerStyle':
389 self.parent.figure.gca().get_lines()[k].set_marker(vv)
390 elif kk == 'markerColor':
391 self.parent.figure.gca().get_lines()[k].set_markeredgecolor(vv)
392 elif kk == 'colorMap':
393 colorMap = eval('pylab.cm.' + vv)
394 self.parent.figure.gca().get_images()[k].set_cmap(colorMap)
395 elif kk == 'interpolation':
396 self.parent.figure.gca().get_images()[k].set_interpolation(vv)
397 elif kk == 'alpha':
398 self.parent.figure.gca().get_images()[k].set_alpha(vv)
399
400 self.parent.figure.gca().legend(loc = 'best')
401 self.parent.canvas.show()
402
403 except:
404 raise Error('Error when updating plots.')
405
407
408 self.settings['plotTitle'] = self.parent.figure.gca().title.get_text()
409 self.settings['xRange'] = '-'.join([str(v) for v in self.parent.figure.gca().get_xlim()])
410 self.settings['yRange'] = '-'.join([str(v) for v in self.parent.figure.gca().get_ylim()])
411 self.settings['xLabel'] = self.parent.figure.gca().xaxis.get_label().get_text()
412 self.settings['yLabel'] = self.parent.figure.gca().yaxis.get_label().get_text()
413
414
415 if len(self.parent.figure.gca().get_images()) == 0:
416 self.settings['xScale'] = self.parent.figure.gca().get_xscale()
417 self.settings['yScale'] = self.parent.figure.gca().get_yscale()
418 else:
419 self.settings['xScale'] = 'linear'
420 self.settings['yScale'] = 'linear'
421 self.settings['zScale'] = 'linear'
422
423 self.settings['xTicks'] = str(list(self.parent.figure.gca().get_xticks()))
424 self.settings['xTicks'] += ';' + str([v.get_text() for v in self.parent.figure.gca().get_xticklabels()])
425 self.settings['xTicksSize'] = int(self.parent.figure.gca().get_xticklabels()[0].get_size())
426 self.settings['xTicksAngle'] = int(self.parent.figure.gca().get_xticklabels()[0].get_rotation())
427 self.settings['yTicks'] = str(list(self.parent.figure.gca().get_yticks()))
428 self.settings['yTicks'] += ';' + str([v.get_text() for v in self.parent.figure.gca().get_yticklabels()])
429 self.settings['yTicksSize'] = int(self.parent.figure.gca().get_yticklabels()[0].get_size())
430 self.settings['yTicksAngle'] = int(self.parent.figure.gca().get_yticklabels()[0].get_rotation())
431 self.settings['gridWidth'] = float(self.parent.figure.gca().get_xgridlines()[0].get_linewidth())
432 self.settings['gridStyle'] = lineStyles.index(self.parent.figure.gca().get_xgridlines()[0].get_linestyle())
433 self.settings['gridColor'] = rgb2hex(ColorConverter().to_rgb(self.parent.figure.gca().get_xgridlines()[0].get_color()))
434
436
437 if self.selectedPlot is None:
438 return
439
440 else:
441 self.settings[self.selectedPlot] = {}
442
443
444 if len(self.parent.figure.gca().get_images()) == 0:
445
446 plot = self.parent.figure.get_axes()[0].get_lines()[self.selectedPlot]
447
448 self.settings[self.selectedPlot]['lineLabel'] = plot.get_label()
449 self.settings[self.selectedPlot]['lineWidth'] = int(float(plot.get_linewidth()))
450
451 self.settings[self.selectedPlot]['lineStyle'] = plot.get_linestyle()
452 self.settings[self.selectedPlot]['lineColor'] = rgb2hex(ColorConverter().to_rgb(plot.get_color()))
453
454 self.settings[self.selectedPlot]['markerStyle'] = plot.get_marker()
455 self.settings[self.selectedPlot]['markerSize'] = int(plot.get_markersize())
456 self.settings[self.selectedPlot]['markerColor'] = rgb2hex(ColorConverter().to_rgb(plot.get_markeredgecolor()))
457
458 else:
459
460 plot = self.parent.figure.gca().get_images()[self.selectedPlot]
461
462 self.settings[self.selectedPlot]['colorMap'] = plot.cmap.name
463 self.settings[self.selectedPlot]['interpolation'] = plot._interpolation
464 self.settings[self.selectedPlot]['alpha'] = plot.get_alpha()
465
467
468 self.settings['plotTitle'] = self.widgets['plotTitle'].getValue()
469 self.settings['xRange'] = self.widgets['xRange'].getValue()
470 self.settings['yRange'] = self.widgets['yRange'].getValue()
471 self.settings['xLabel'] = self.widgets['xLabel'].getValue()
472 self.settings['yLabel'] = self.widgets['yLabel'].getValue()
473
474 self.settings['xTicks'] = self.widgets['xTicks'].getValue()
475 self.settings['xTicksSize'] = self.widgets['xTicksSize'].getValue()
476 self.settings['xTicksAngle'] = self.widgets['xTicksAngle'].getValue()
477 self.settings['yTicks'] = self.widgets['yTicks'].getValue()
478 self.settings['yTicksSize'] = self.widgets['yTicksSize'].getValue()
479 self.settings['yTicksAngle'] = self.widgets['yTicksAngle'].getValue()
480
481 self.settings['gridWidth'] = self.widgets['gridWidth'].getValue()
482 self.settings['gridStyle'] = self.widgets['gridStyle'].getValue()
483 self.settings['gridColor'] = self.widgets['gridColor'].getValue()
484
485
486 if len(self.parent.figure.gca().get_images()) == 0:
487 self.settings['xScale'] = self.widgets['xScale'].getValue()
488 self.settings['yScale'] = self.widgets['yScale'].getValue()
489
490 self.settings[self.selectedPlot]['lineLabel'] = self.widgets['lineLabel'].getValue()
491 self.settings[self.selectedPlot]['lineWidth'] = self.widgets['lineWidth'].getValue()
492 self.settings[self.selectedPlot]['lineStyle'] = self.widgets['lineStyle'].getValue()
493 self.settings[self.selectedPlot]['lineColor'] = self.widgets['lineColor'].getValue()
494
495 self.settings[self.selectedPlot]['markerStyle'] = self.widgets['markerStyle'].getValue()
496 self.settings[self.selectedPlot]['markerSize'] = self.widgets['markerSize'].getValue()
497 self.settings[self.selectedPlot]['markerColor'] = self.widgets['markerColor'].getValue()
498
499 else:
500 self.settings['xScale'] = 'linear'
501 self.settings['yScale'] = 'linear'
502 self.settings['zScale'] = self.widgets['zScale'].getValue()
503
504 self.settings[self.selectedPlot]['colorMap'] = self.widgets['colorMap'].getValue()
505 self.settings[self.selectedPlot]['interpolation'] = self.widgets['interpolation'].getValue()
506 self.settings[self.selectedPlot]['alpha'] = self.widgets['alpha'].getValue()
507
509
510 defaultColor = widget.button.cget('bg')
511
512 junk, selectedColor = tkColorChooser.askcolor(color = defaultColor, master = self)
513 if isinstance(selectedColor, _tkinter.Tcl_Obj):
514 selectedColor = selectedColor.string
515
516 elif isinstance(selectedColor, str):
517 pass
518
519 else:
520 selectedColor = defaultColor
521
522 widget.button.configure(bg = selectedColor, activebackground = selectedColor)
523 widget.results = selectedColor
524
525 return selectedColor
526
528 """
529 Argument:
530 - event: either a Tkinter event, either a Tkinter control variable value that has been traced for changes.
531 """
532
533 if not self.widgets.has_key(widgetName):
534 return
535
536 w = self.widgets[widgetName]
537 if widgetName == 'plotTitle':
538 self.parent.figure.gca().set_title(w.getValue())
539 elif widgetName == 'xRange':
540 xMin, xMax = [float(v) for v in w.getValue().split('-')]
541 self.parent.figure.gca().set_xlim((xMin,xMax))
542 elif widgetName == 'yRange':
543 yMin, yMax = [float(v) for v in w.getValue().split('-')]
544 self.parent.figure.gca().set_ylim((yMin,yMax))
545 elif widgetName == 'xLabel':
546 self.parent.figure.gca().set_xlabel(w.getValue())
547 elif widgetName == 'yLabel':
548 self.parent.figure.gca().set_ylabel(w.getValue())
549 elif widgetName == 'xScale':
550 self.parent.figure.gca().set_xscale(w.getValue())
551 elif widgetName == 'yScale':
552 self.parent.figure.gca().set_yscale(w.getValue())
553 elif widgetName == 'zScale':
554 if w.getValue() == 'linear':
555 self.parent.figure.gca().get_images()[self.selectedPlot].set_norm(Normalize())
556 else:
557 self.parent.figure.gca().get_images()[self.selectedPlot].set_norm(LogNorm())
558 elif widgetName == 'gridWidth':
559 self.parent.figure.gca().grid(True, linewidth = w.getValue())
560 elif widgetName == 'gridStyle':
561 self.parent.figure.gca().grid(True, linestyle = w.getValue())
562 elif widgetName == 'gridColor':
563 color = self.selectColor(w)
564 self.parent.figure.gca().grid(True, color = color)
565 elif widgetName == 'xTicks':
566 ticks, ticksLabels = [eval(t) for t in w.getValue().split(';')]
567 ticks = [float(t) for t in ticks]
568 ticksLabels = [str(t) for t in ticksLabels]
569 self.parent.figure.gca().set_xticks(ticks)
570 self.parent.figure.gca().set_xticklabels(ticksLabels)
571 elif widgetName == 'xTicksSize':
572 [l.set_size(int(w.getValue())) for l in self.parent.figure.gca().get_xticklabels()]
573 elif widgetName == 'xTicksAngle':
574 [l.set_rotation(int(w.getValue())) for l in self.parent.figure.gca().get_xticklabels()]
575 elif widgetName == 'yTicks':
576 ticks, ticksLabels = [eval(t) for t in w.getValue().split(';')]
577 ticks = [float(t) for t in ticks]
578 ticksLabels = [str(t) for t in ticksLabels]
579 self.parent.figure.gca().set_yticks(ticks)
580 self.parent.figure.gca().set_yticklabels(ticksLabels)
581 elif widgetName == 'yTicksSize':
582 [l.set_size(int(w.getValue())) for l in self.parent.figure.gca().get_yticklabels()]
583 elif widgetName == 'yTicksAngle':
584 [l.set_rotation(int(w.getValue())) for l in self.parent.figure.gca().get_yticklabels()]
585 elif widgetName == 'lineLabel':
586 self.parent.figure.gca().get_lines()[self.selectedPlot].set_label(w.getValue())
587 self.plots.lb.delete(self.selectedPlot)
588 self.plots.lb.insert(self.selectedPlot, w.getValue())
589 elif widgetName == 'lineWidth':
590 self.parent.figure.gca().get_lines()[self.selectedPlot].set_linewidth(w.getValue())
591 elif widgetName == 'lineStyle':
592 self.parent.figure.gca().get_lines()[self.selectedPlot].set_linestyle(w.getValue())
593 elif widgetName == 'lineColor':
594 color = self.selectColor(w)
595 self.parent.figure.gca().get_lines()[self.selectedPlot].set_color(color)
596 elif widgetName == 'markerSize':
597 self.parent.figure.gca().get_lines()[self.selectedPlot].set_markersize(w.getValue())
598 elif widgetName == 'markerStyle':
599 self.parent.figure.gca().get_lines()[self.selectedPlot].set_marker(w.getValue())
600 elif widgetName == 'markerColor':
601 color = self.selectColor(w)
602 self.parent.figure.gca().get_lines()[self.selectedPlot].set_markeredgecolor(color)
603 elif widgetName == 'alpha':
604 self.parent.figure.gca().get_images()[self.selectedPlot].set_alpha(w.getValue())
605 elif widgetName == 'colorMap':
606 colorMap = eval('pylab.cm.' + w.getValue())
607 self.parent.figure.gca().get_images()[self.selectedPlot].set_cmap(colorMap)
608 elif widgetName == 'interpolation':
609 self.parent.figure.gca().get_images()[self.selectedPlot].set_interpolation(w.getValue())
610
611 self.parent.figure.gca().legend(loc = 'best')
612 self.parent.canvas.show()
613
615 """
616 This method removes the previous plot settings widgets.
617 """
618
619
620 for widget in self.pFrame.winfo_children():
621
622 if widget == self.plots:
623 continue
624
625
626 else:
627 widget.destroy()
628
731
733 """Sets up a dialog used to plot variables present in a NetCDF file.
734 """
735
736 - def __init__(self, parent, title = None, netcdf = None, xVar = None, yVar = None, zVar = None):
737 """The constructor.
738
739 @param parent: the parent widget.
740
741 @param title: a string specifying the title of the dialog.
742 @type title: string
743
744 @param netcdf: the name of a NetCDF file to plot (string) or an opened NetCDF trajectory file.
745 @type netcdf: a string or a Scientific.IO.NetCDF._NetCDFFile object
746
747 @param xVar: the NetCDF variable name of the X variable to plot.
748 @type xVar: string
749
750 @param yVar: the NetCDF variable name of the Y variable to plot.
751 @type yVar:
752
753 @param zVar: the NetCDF variable name of the Z variable to plot.
754 @type zVar:
755 """
756
757 Toplevel.__init__(self, parent)
758
759 self.transient(parent)
760
761 if title:
762 self.title(title)
763
764 self.parent = parent
765
766 try:
767 if isinstance(netcdf, _NetCDFFile):
768 self.data = netcdf
769
770 elif isinstance(netcdf, Trajectory):
771 self.data = NetCDFFile(netcdf.filename, 'r')
772
773 elif isinstance(netcdf, str):
774 self.data = NetCDFFile(netcdf, 'r')
775
776 else:
777 raise
778
779 except:
780 self.data = None
781
782 self.xVar = xVar
783 self.yVar = yVar
784 self.zVar = zVar
785
786 body = Frame(self)
787 self.initial_focus = self.body(body)
788 body.grid(row = 0, column = 0, sticky = EW)
789
790 self.buttonbox()
791
792
793 if self.data is not None:
794
795 self.fileBrowser.setValue(str(self.data))
796
797
798 self.displayVariables()
799
800 if (self.xVar is not None) & (self.yVar is not None):
801 if self.zVar is not None:
802 self.plotXYZ()
803 else:
804 self.plotXY()
805
806 self.grab_set()
807
808 if not self.initial_focus:
809 self.initial_focus = self
810
811 self.protocol("WM_DELETE_WINDOW", lambda : self.cancel(self))
812
813 self.resizable(width = NO, height = NO)
814
815 self.geometry("+%d+%d" % (parent.winfo_rootx()+50, parent.winfo_rooty()+50))
816
817 self.initial_focus.focus_set()
818
819 self.wait_window(self)
820
821 - def body(self, master):
822 """
823 Create dialog body. Return widget that should have initial focus.
824 """
825
826 settingsFrame = LabelFrame(master, text = 'Settings', bd = 2, relief = GROOVE)
827 settingsFrame.grid(row = 0, column = 0, sticky = EW, padx = 3, pady = 3)
828 settingsFrame.grid_columnconfigure(0, weight = 1)
829
830
831 self.fileBrowser = ComboFileBrowser(settingsFrame,\
832 frameLabel = "NetCDF input file",\
833 contents = '',\
834 save = False,\
835 command = self.openNetCDF)
836 self.fileBrowser.grid(row = 0, column = 0, padx = 2, pady = 2, sticky = EW)
837 self.fileBrowser.grid_columnconfigure(0, weight = 1)
838 self.fileBrowser.entry.bind('<Return>', self.openNetCDF)
839
840
841 listboxesFrame = LabelFrame(settingsFrame, text = 'Variables', bd = 2, relief = GROOVE)
842 listboxesFrame.grid(row = 1, column = 0, padx = 2, pady = 2, sticky = W)
843
844
845 self.xVarLb = ComboListbox(listboxesFrame, 'X', [])
846 self.xVarLb.lb.config({'exportselection' : 0, 'width' : 22, 'height' : 4, 'selectmode' : SINGLE})
847 self.xVarLb.config({'relief' : FLAT})
848 self.xVarLb.grid(row = 0, column = 0)
849 self.xVarLb.lb.bind('<ButtonRelease-1>', self.selectXVariable)
850
851
852 self.yVarLb = ComboListbox(listboxesFrame, 'Y', [])
853 self.yVarLb.config({'relief' : FLAT})
854 self.yVarLb.grid(row = 0, column = 1)
855 self.yVarLb.lb.config({'exportselection' : 0, 'width' : 22, 'height' : 4, 'selectmode' : SINGLE})
856
857
858 self.zVarLb = ComboListbox(listboxesFrame, 'Z', [])
859 self.zVarLb.config({'relief' : FLAT})
860 self.zVarLb.grid(row = 0, column = 2)
861 self.zVarLb.lb.config({'exportselection' : 0, 'width' : 22, 'height' : 4, 'selectmode' : SINGLE})
862
863
864 plotFrame = LabelFrame(master, text = 'Plot', bd = 2, relief = GROOVE)
865 plotFrame.grid(row = 3, column = 0, padx = 2, pady = 2, sticky = EW)
866 plotFrame.grid_columnconfigure(0, weight = 1)
867
868
869 figureFrame = Frame(plotFrame, relief = FLAT)
870 figureFrame.grid(row = 0, column = 0, sticky = 'EW')
871 figureFrame.grid_columnconfigure(0, weight = 1)
872
873
874 self.figure = Figure(dpi = 72)
875 self.canvas = FigureCanvasTkAgg(self.figure, master = figureFrame)
876
877 self.canvas.get_tk_widget().pack()
878 self.canvas._tkcanvas.pack()
879 self.toolbar = NavigationToolbar2TkAgg(self.canvas, figureFrame)
880 self.toolbar.update()
881
882 return None
883
911
912
913 - def ok(self, event = None):
914
915 if not self.validate():
916 self.initial_focus.focus_set()
917 return
918
919 self.update_idletasks()
920
921 self.apply()
922
923 - def cancel(self, dialog, event = None):
924
925 dialog.parent.grab_set()
926 dialog.parent.focus_set()
927 dialog.destroy()
928
929
931
932 if not self.xVarLb.lb.curselection():
933 raise Error('Please select a X variable.')
934 self.xVar = self.xVarLb.lb.get(int(self.xVarLb.lb.curselection()[0]))
935 dimX = self.data.variables[self.xVar].dimensions[0]
936
937 if not self.yVarLb.lb.curselection():
938 raise Error('Please select a Y variable.')
939 self.yVar = self.yVarLb.lb.get(int(self.yVarLb.lb.curselection()[0]))
940 dimY = self.data.variables[self.yVar].dimensions[0]
941
942 if not self.zVarLb.lb.curselection():
943 self.zVar = None
944
945
946 if dimX != dimY:
947 raise Error('X (dim = %d) and Y (dim = %d) do not have the same dimension.' % (dimX,dimY))
948
949 else:
950 self.zVar = self.zVarLb.lb.get(int(self.zVarLb.lb.curselection()[0]))
951 dimZ = self.data.variables[self.zVar].dimensions
952 if (dimX != dimZ[0]) or (dimY != dimZ[1]):
953 raise Error('X (dim = %d) and Y (dim = %d) dimensions do not match Z (dim = %d) dimensions.' % (dimX,dimY,dimZ))
954
955 return True
956
958
959 try:
960 if self.zVar is None:
961 self.plotXY()
962
963 else:
964 self.plotXYZ()
965 except:
966 raise Error('Error when plotting datas.')
967
968
970 """This method will open the dialog to set up the global settings.
971 """
972
973 if not self.figure.gca().get_lines():
974 LogMessage('warning', 'No plot defined.', ['gui'])
975 return
976
977 g = SettingsDialog(self)
978
980 """This method will clear up all the displayed plots.
981 """
982
983
984 self.figure.clear()
985
986 if hasattr(self.figure,'xValues'):
987 delattr(self.figure, 'xValues')
988
989 if hasattr(self.figure,'yValues'):
990 delattr(self.figure, 'yValues')
991
992 if hasattr(self.figure,'zValues'):
993 delattr(self.figure, 'zValues')
994
995
996 self.canvas.show()
997
999 """This method pops up a dialog from which the plotted datas can be exported to an ASCII file.
1000 """
1001
1002 if not self.figure.gca().get_lines():
1003 LogMessage('warning', 'No plot defined.', ['gui'])
1004 return
1005
1006 self.exportDialog = Toplevel(self)
1007
1008 self.exportDialog.parent = self
1009
1010 self.exportDialog.transient(self)
1011
1012 self.exportDialog.title('Export plot to ASCII')
1013
1014 self.exportDialog.grab_set()
1015
1016
1017 settingsFrame = LabelFrame(self.exportDialog, text = 'Settings', bd = 2, relief = GROOVE)
1018 settingsFrame.grid(row = 0, column = 0, sticky = EW, padx = 3, pady = 3)
1019 settingsFrame.grid_columnconfigure(0, weight = 1)
1020
1021
1022 self.exportDialog.resizable(width = NO, height = NO)
1023
1024 self.exportDialog.geometry("+%d+%d" % (self.winfo_rootx()+50, self.winfo_rooty()+50))
1025
1026 if self.figure.gca().get_images():
1027 self.xIndexMinEntry = ComboIntegerEntry(settingsFrame, frameLabel = 'X Index min', contents = 1)
1028 self.xIndexMinEntry.grid(row = 0, column = 0, sticky = "EW")
1029 self.xIndexMinEntry.grid_columnconfigure(0, weight = 1)
1030
1031 self.xIndexMaxEntry = ComboIntegerEntry(settingsFrame, frameLabel = 'X Index max',\
1032 contents = self.figure.gca().get_images()[0].get_array().shape[1])
1033 self.xIndexMaxEntry.grid(row = 1, column = 0, sticky = "EW")
1034 self.xIndexMaxEntry.grid_columnconfigure(0, weight = 1)
1035
1036 self.yIndexMinEntry = ComboIntegerEntry(settingsFrame, frameLabel = 'Y Index min', contents = 1)
1037 self.yIndexMinEntry.grid(row = 2, column = 0, sticky = "EW")
1038 self.yIndexMinEntry.grid_columnconfigure(0, weight = 1)
1039
1040 self.yIndexMaxEntry = ComboIntegerEntry(settingsFrame, frameLabel = 'Y Index max',\
1041 contents = self.figure.gca().get_images()[0].get_array().shape[0])
1042 self.yIndexMaxEntry.grid(row = 3, column = 0, sticky = "EW")
1043 self.yIndexMaxEntry.grid_columnconfigure(0, weight = 1)
1044
1045 else:
1046 self.indexMinEntry = ComboIntegerEntry(settingsFrame, frameLabel = 'Index min', contents = 1)
1047 self.indexMinEntry.grid(row = 0, column = 0, sticky = "EW")
1048 self.indexMinEntry.grid_columnconfigure(0, weight = 1)
1049
1050 self.indexMaxEntry = ComboIntegerEntry(settingsFrame, frameLabel = 'Index max',\
1051 contents = len(self.figure.gca().get_lines()[0].get_xdata()))
1052 self.indexMaxEntry.grid(row = 1, column = 0, sticky = "EW")
1053 self.indexMaxEntry.grid_columnconfigure(0, weight = 1)
1054
1055
1056 self.exportedFileBrowser = ComboFileBrowser(settingsFrame,\
1057 frameLabel = "ASCII output file",\
1058 contents = '',\
1059 save = True)
1060 self.exportedFileBrowser.grid(row = 4, column = 0, padx = 2, pady = 2, sticky = EW)
1061 self.exportedFileBrowser.grid_columnconfigure(0, weight = 1)
1062
1063
1064 box = LabelFrame(self.exportDialog, text = 'Actions', bd = 2, relief = GROOVE)
1065 box.grid(row = 1, column = 0, sticky = EW, padx = 3, pady = 3)
1066 box.grid_columnconfigure(0, weight = 1)
1067
1068 w = Button(box, text = "Cancel", width = 10, command = lambda : self.cancel(self.exportDialog))
1069 w.grid(row = 0, column = 0, sticky = E)
1070
1071 w = Button(box, text = "OK", width = 10, command = self.exportPlot, default = ACTIVE)
1072 w.grid(row = 0, column = 1, sticky = E)
1073
1074 self.exportDialog.protocol("WM_DELETE_WINDOW", lambda : self.cancel(self.exportDialog))
1075 self.exportDialog.bind("<Return>", self.exportPlot)
1076 self.exportDialog.bind("<Escape>", lambda event : self.cancel(self.exportDialog, event))
1077
1079 """This method exports plotted datas to an ASCII file.
1080 """
1081
1082 filename = self.exportedFileBrowser.getValue()
1083 if not filename:
1084 LogMessage('warning', 'No output file defined.', ['gui'])
1085 return
1086
1087 if filename[-4:] != '.dat':
1088 filename += '.dat'
1089
1090 try:
1091
1092 fFmt = '%20.8e '
1093 sFmt = '%20s '
1094 f = open(filename, 'w')
1095
1096 if self.figure.gca().get_images():
1097 xIndexMin = self.xIndexMinEntry.getValue() - 1
1098 xIndexMax = self.xIndexMaxEntry.getValue()
1099
1100 if xIndexMin < 0:
1101 xIndexMin = 0
1102 if xIndexMax > self.figure.gca().get_images()[0].get_array().shape[1]:
1103 xIndexMax = self.figure.gca().get_images()[0].get_array().shape[1]
1104
1105 yIndexMin = self.yIndexMinEntry.getValue() - 1
1106 yIndexMax = self.yIndexMaxEntry.getValue()
1107 if yIndexMin < 0:
1108 yIndexMin = 0
1109 yIndexMax = self.yIndexMaxEntry.getValue()
1110 if yIndexMax > self.figure.gca().get_images()[0].get_array().shape[0]:
1111 yIndexMax = self.figure.gca().get_images()[0].get_array().shape[0]
1112
1113 f.write('datas = %s\n' % self.figure.gca().get_images()[0].get_label())
1114 f.write('1st line = %s\n' % self.figure.gca().get_images()[0].get_axes().get_ylabel())
1115 f.write('1st column = %s\n\n' % self.figure.gca().get_images()[0].get_axes().get_xlabel())
1116
1117 data = self.figure.gca().get_images()[0].get_array()
1118
1119
1120 f.write(sFmt % 'NaN')
1121 for v in range(yIndexMin,yIndexMax):
1122 f.write(fFmt % self.figure.yValues[v])
1123 f.write('\n')
1124
1125
1126 for ix in range(xIndexMin,xIndexMax):
1127 f.write(fFmt % self.figure.xValues[ix])
1128 for iy in range(yIndexMin,yIndexMax):
1129 v = self.figure.zValues[iy,ix]
1130 try:
1131 f.write(fFmt % v)
1132 except:
1133 f.write(sFmt % v)
1134
1135 f.write('\n')
1136
1137 else:
1138 indexMin = self.indexMinEntry.getValue() - 1
1139 indexMax = self.indexMaxEntry.getValue()
1140 if indexMin < 0:
1141 indexMin = 0
1142 if indexMax > len(self.figure.gca().get_lines()[0].get_xdata()):
1143 indexMax = len(self.figure.gca().get_lines()[0].get_xdata())
1144
1145 data = []
1146 comp = 1
1147 for p in self.figure.gca().get_lines():
1148 f.write('columns-%d = %s\n' % (comp,p.get_axes().get_xlabel()))
1149 f.write('columns-%d = %s\n' % (comp+1,p.get_axes().get_ylabel()))
1150 data.append(list(p.get_xdata())[indexMin:indexMax])
1151 data.append(list(p.get_ydata())[indexMin:indexMax])
1152 comp += 2
1153 data = [[r[col] for r in data] for col in range(len(data[0]))]
1154
1155 f.write('\n')
1156
1157 for d in data:
1158 for dd in d:
1159 try:
1160 f.write(fFmt % dd)
1161 except:
1162 f.write(sFmt % dd)
1163 f.write('\n')
1164 f.close()
1165 except:
1166 raise Error('Error when exporting plotted data.')
1167 finally:
1168 self.cancel(self.exportDialog)
1169
1171
1172 self.yVarLb.lb.selection_clear(0, END)
1173 self.zVarLb.lb.selection_clear(0, END)
1174
1176 """
1177 This method display the numeric variables found in the NetCDF file into their appropriate listbox.
1178 """
1179
1180
1181 self.xVarLb.lb.delete(0, END)
1182 self.yVarLb.lb.delete(0, END)
1183 self.zVarLb.lb.delete(0, END)
1184
1185
1186 for varName in sorted(self.data.variables.keys()):
1187 variable = self.data.variables[varName]
1188
1189 if len(variable.shape) > 2:
1190 continue
1191
1192
1193 if variable.typecode() not in [Num.Float, Num.Float0, Num.Int, Num.Int32, Num.Character]:
1194 continue
1195
1196
1197 if len(variable.shape) == 1:
1198 self.xVarLb.lb.insert(END, varName)
1199 self.yVarLb.lb.insert(END, varName)
1200
1201
1202 elif len(variable.shape) == 2:
1203 if variable.typecode() == Num.Character:
1204 self.xVarLb.lb.insert(END, varName)
1205 self.yVarLb.lb.insert(END, varName)
1206
1207 else:
1208 self.zVarLb.lb.insert(END, varName)
1209
1211 """
1212 This method opens a NetCDF file and updates the dialog with the data read from that file.
1213 Arguments:
1214 -event: Tkinter event.
1215 """
1216
1217 if event is not None:
1218 filename = self.fileBrowser.getValue()
1219
1220 else:
1221
1222 filename = askopenfilename(parent = self,\
1223 filetypes = [('NetCDF file','*.nc')],\
1224 initialdir = PREFERENCES.outputfile_path)
1225
1226
1227 if filename:
1228 try:
1229 self.data = NetCDFFile(filename, 'r')
1230
1231 self.fileBrowser.setValue(filename)
1232
1233
1234 self.displayVariables()
1235
1236 except:
1237 LogMessage('warning','The file %s could not be read.' % filename,['gui'])
1238
1239 return 'break'
1240
1242 """
1243 This method display a 2D plot.
1244 """
1245
1246 if (self.xVar is None) or (self.yVar is None):
1247 return
1248
1249 if self.yVar is None:
1250 return
1251
1252 if self.figure.gca().get_images():
1253 self.resetPlots()
1254
1255 if self.data.variables[self.xVar].typecode() == Num.Character:
1256 temp = self.data.variables[self.xVar].getValue()
1257 xValues = Num.arange(temp.shape[0])
1258 else:
1259 xValues = self.data.variables[self.xVar].getValue()
1260
1261 if self.data.variables[self.yVar].typecode() == Num.Character:
1262 temp = self.data.variables[self.yVar].getValue()
1263 yValues = Num.arange(temp.shape[0])
1264 else:
1265 yValues = self.data.variables[self.yVar].getValue()
1266
1267 self.figure.gca().plot(xValues, yValues, label = self.yVar + ' vs ' + self.xVar)
1268
1269 self.figure.gca().grid(True)
1270
1271 if self.data.variables[self.xVar].typecode() == Num.Character:
1272 xTicks = xValues[:]
1273 xTicksLabels = ['%s' % temp[v,:].tostring().rstrip('\x00') for v in range(len(temp))]
1274 self.figure.gca().set_xticks(xTicks)
1275 self.figure.gca().set_xticklabels(xTicksLabels)
1276
1277 if self.data.variables[self.yVar].typecode() == Num.Character:
1278 yTicks = yValues[:]
1279 yTicksLabels = ['%s' % temp[v,:].tostring().rstrip('\x00') for v in range(len(temp))]
1280 self.figure.gca().set_yticks(yTicks)
1281 self.figure.gca().set_yticklabels(yTicksLabels)
1282
1283
1284 try:
1285 self.figure.get_axes()[0].set_title(self.data.title)
1286 except AttributeError:
1287 self.figure.get_axes()[0].set_title('')
1288
1289
1290 try:
1291 self.figure.get_axes()[0].set_xlabel('%s (%s)' % (self.xVar, self.data.variables[self.xVar].units))
1292 except AttributeError:
1293 self.figure.get_axes()[0].set_xlabel(self.xVar)
1294
1295
1296 try:
1297 self.figure.get_axes()[0].set_ylabel('%s (%s)' % (self.yVar, self.data.variables[self.yVar].units))
1298 except AttributeError:
1299 self.figure.get_axes()[0].set_ylabel(self.yVar)
1300
1301
1302 self.figure.get_axes()[0].legend(loc = 'best')
1303
1304 self.canvas.show()
1305
1307 """
1308 This call back plot the orthogonal slices defined by the moving cursor of a 3D plot.
1309 """
1310
1311
1312 if event.button != 3:
1313 return
1314
1315
1316 if event.inaxes is None:
1317 return
1318
1319
1320 horizontalSlice = pylab.subplot(211)
1321 if self.data.variables[self.xVar].typecode() == Num.Character:
1322 temp = self.data.variables[self.xVar].getValue()
1323 xValue = Num.arange(len(temp))
1324 xTicks = ['%s' % temp[v,:].tostring().rstrip('\x00') for v in range(len(temp))]
1325 horizontalSlice.set_xticks(range(len(xTicks)))
1326 horizontalSlice.set_xticklabels(xTicks)
1327 else:
1328 xValue = self.data.variables[self.xVar].getValue()
1329
1330
1331 horizontalSlice.plot(xValue, self.data.variables[self.zVar][:,int(event.ydata)])
1332
1333
1334 if hasattr(self.data.variables[self.xVar], 'units'):
1335 horizontalSlice.set_xlabel('%s (%s)' % (self.xVar, self.data.variables[self.xVar].units))
1336 else:
1337 horizontalSlice.set_xlabel('%s (Unknown unit)' % self.xVar)
1338
1339
1340 if self.data.variables[self.yVar].typecode() == Num.Character:
1341 value = self.data.variables[self.yVar].getValue()[int(event.ydata),:].tostring()
1342 horizontalSlice.set_ylabel('%s %s = %s' % (self.zVar,self.yVar, value), fontsize = 7)
1343 else:
1344 value = self.data.variables[self.yVar].getValue()[int(event.ydata)]
1345 horizontalSlice.set_ylabel('%s %s = %.3f' % (self.zVar,self.yVar, value), fontsize = 7)
1346
1347
1348 verticalSlice = pylab.subplot(212)
1349
1350 if self.data.variables[self.yVar].typecode() == Num.Character:
1351 temp = self.data.variables[self.yVar].getValue()
1352 xValue = Num.arange(len(temp))
1353 xTicks = ['%s' % temp[v,:].tostring().rstrip('\x00') for v in range(len(temp))]
1354 verticalSlice.set_xticks(range(len(xTicks)))
1355 verticalSlice.set_xticklabels(xTicks)
1356 else:
1357 xValue = self.data.variables[self.yVar].getValue()
1358
1359
1360 verticalSlice.plot(xValue, self.data.variables[self.zVar][int(event.xdata),:])
1361
1362 verticalSlice.set_xlabel(self.yVar)
1363 if self.data.variables[self.xVar].typecode() == Num.Character:
1364 value = self.data.variables[self.xVar].getValue()[int(event.xdata),:].tostring()
1365 verticalSlice.set_ylabel('%s %s = %s' % (self.zVar,self.xVar, value), fontsize = 7)
1366 else:
1367 value = self.data.variables[self.xVar].getValue()[int(event.xdata)]
1368 verticalSlice.set_ylabel('%s %s = %.3f' % (self.zVar,self.xVar, value), fontsize = 7)
1369
1370 pylab.show()
1371
1373 """
1374 This method display a 2D plot.
1375 """
1376
1377 if (self.xVar is None) or (self.yVar is None) or (self.zVar is None):
1378 return
1379
1380 self.resetPlots()
1381
1382 xValues = self.data.variables[self.xVar].getValue()
1383 yValues = self.data.variables[self.yVar].getValue()
1384 zValues = pylab.transpose(self.data.variables[self.zVar].getValue())
1385
1386 self.figure.gca().imshow(zValues, aspect = 'auto', label = self.zVar + ' vs ' + self.xVar + ' and ' + self.yVar)
1387 self.figure.xValues = xValues
1388 self.figure.yValues = yValues
1389 self.figure.zValues = zValues
1390
1391
1392 self.figure.colorbar(self.figure.gca().get_images()[0])
1393
1394
1395 cursor = Cursor(self.figure.gca(), useblit = True, color ='red', linewidth = 1)
1396 cursor.ax.set_xlim((0, zValues.shape[1]-1))
1397 cursor.ax.set_ylim((0, zValues.shape[0]-1))
1398
1399 if self.data.variables[self.xVar].typecode() == Num.Character:
1400 self.figure.gca().set_xticks(range(len(xValues)))
1401 xTickLabels = ['%s' % xValues[v,:].tostring().rstrip('\x00') for v in range(len(xValues))]
1402 self.figure.gca().set_xticklabels(xTickLabels)
1403 else:
1404 xStep = len(xValues)/10
1405 if xStep < 1:
1406 xStep = 1
1407 self.figure.gca().set_xticks(range(0, len(xValues), xStep))
1408 self.figure.gca().set_xticklabels(['%.3f' % xValues[v] for v in range(0, len(xValues), xStep)])
1409
1410 if self.data.variables[self.yVar].typecode() == Num.Character:
1411 self.figure.gca().set_yticks(range(len(yValues)))
1412 yTickLabels = ['%s' % yValues[v,:].tostring().rstrip('\x00') for v in range(len(yValues))]
1413 self.figure.gca().set_yticklabels(yTickLabels)
1414 else:
1415 yStep = len(yValues)/10
1416 if yStep < 1:
1417 yStep = 1
1418 self.figure.gca().set_yticks(range(0, len(yValues), yStep))
1419 self.figure.gca().set_yticklabels(['%.3f' % yValues[v] for v in range(0, len(yValues), yStep)])
1420
1421
1422 try:
1423 self.figure.gca().set_title(self.data.title)
1424
1425 except AttributeError:
1426 self.figure.gca().set_title('')
1427
1428
1429 try:
1430 self.figure.gca().set_xlabel('%s (%s)' % (self.xVar, self.data.variables[self.xVar].units))
1431
1432 except AttributeError:
1433 self.figure.gca().set_xlabel(self.xVar)
1434
1435
1436 try:
1437 self.figure.gca().set_ylabel('%s (%s)' % (self.yVar, self.data.variables[self.yVar].units))
1438 except AttributeError:
1439 self.figure.gca().set_ylabel(self.yVar)
1440
1441
1442 self.canvas.mpl_connect('button_press_event', self.displayPlotSlices)
1443
1444 self.canvas.show()
1445