source: trunk/python/asaplotgui.py @ 1153

Last change on this file since 1153 was 1153, checked in by mar637, 18 years ago

lots of changes to support soft refresh, for things like text overlays, linecatlogs etc. reworked plot_lines to to auto-peak detection. added forwarding functions to matplotlib.axes. drawing functions

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 5.4 KB
Line 
1"""
2ASAP plotting class based on matplotlib.
3"""
4
5from asap.asaplotbase import *
6import Tkinter as Tk
7from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, \
8        FigureManagerTkAgg
9# Force use of the newfangled toolbar.
10import matplotlib
11matplotlib.use("TkAgg")
12matplotlib.rcParams['toolbar'] = 'toolbar2'
13
14class asaplotgui(asaplotbase):
15    """
16    ASAP plotting class based on matplotlib.
17    """
18
19    def __init__(self, rows=1, cols=0, title='', size=(8,6), buffering=False):
20        """
21        Create a new instance of the ASAPlot plotting class.
22
23        If rows < 1 then a separate call to set_panels() is required to define
24        the panel layout; refer to the doctext for set_panels().
25        """
26        v = vars()
27        del v['self']
28
29        asaplotbase.__init__(self, **v)
30        self.window = Tk.Tk()
31        def dest_callback():
32            self.is_dead = True
33            self.window.destroy()
34
35        self.window.protocol("WM_DELETE_WINDOW", dest_callback)
36        self.canvas = FigureCanvasTkAgg(self.figure, master=self.window)
37        self.canvas.get_tk_widget().pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)
38        # Simply instantiating this is enough to get a working toolbar.
39        self.figmgr = FigureManagerTkAgg(self.canvas, 1, self.window)
40        self.window.wm_title('ASAP Plotter - Tk')
41
42        self.events = {'button_press':None,
43                       'button_release':None,
44                       'motion_notify':None}
45
46        matplotlib.rcParams["interactive"] = True
47        #self.buffering = buffering
48
49        self.canvas.show()
50
51    def map(self):
52        """
53        Reveal the ASAPlot graphics window and bring it to the top of the
54        window stack.
55        """
56        self.window.wm_deiconify()
57        self.window.lift()
58
59    def position(self):
60        """
61        Use the mouse to get a position from a graph.
62        """
63
64        def position_disable(event):
65            self.register('button_press', None)
66            print '%.4f, %.4f' % (event.xdata, event.ydata)
67
68        print 'Press any mouse button...'
69        self.register('button_press', position_disable)
70
71
72    def quit(self):
73        """
74        Destroy the ASAPlot graphics window.
75        """
76        self.window.destroy()
77
78
79    def region(self):
80        """
81        Use the mouse to get a rectangular region from a plot.
82
83        The return value is [x0, y0, x1, y1] in world coordinates.
84        """
85
86        def region_start(event):
87            height = self.canvas.figure.bbox.height()
88            self.rect = {'fig': None, 'height': height,
89                         'x': event.x, 'y': height - event.y,
90                         'world': [event.xdata, event.ydata,
91                                   event.xdata, event.ydata]}
92            self.register('button_press', None)
93            self.register('motion_notify', region_draw)
94            self.register('button_release', region_disable)
95
96        def region_draw(event):
97            self.canvas._tkcanvas.delete(self.rect['fig'])
98            self.rect['fig'] = self.canvas._tkcanvas.create_rectangle(
99                                self.rect['x'], self.rect['y'],
100                                event.x, self.rect['height'] - event.y)
101
102        def region_disable(event):
103            self.register('motion_notify', None)
104            self.register('button_release', None)
105
106            self.canvas._tkcanvas.delete(self.rect['fig'])
107
108            self.rect['world'][2:4] = [event.xdata, event.ydata]
109            print '(%.2f, %.2f)  (%.2f, %.2f)' % (self.rect['world'][0],
110                self.rect['world'][1], self.rect['world'][2],
111                self.rect['world'][3])
112
113        self.register('button_press', region_start)
114
115        # This has to be modified to block and return the result (currently
116        # printed by region_disable) when that becomes possible in matplotlib.
117
118        return [0.0, 0.0, 0.0, 0.0]
119
120
121    def register(self, type=None, func=None):
122        """
123        Register, reregister, or deregister events of type 'button_press',
124        'button_release', or 'motion_notify'.
125
126        The specified callback function should have the following signature:
127
128            def func(event)
129
130        where event is an MplEvent instance containing the following data:
131
132            name                # Event name.
133            canvas              # FigureCanvas instance generating the event.
134            x      = None       # x position - pixels from left of canvas.
135            y      = None       # y position - pixels from bottom of canvas.
136            button = None       # Button pressed: None, 1, 2, 3.
137            key    = None       # Key pressed: None, chr(range(255)), shift,
138                                  win, or control
139            inaxes = None       # Axes instance if cursor within axes.
140            xdata  = None       # x world coordinate.
141            ydata  = None       # y world coordinate.
142
143        For example:
144
145            def mouse_move(event):
146                print event.xdata, event.ydata
147
148            a = asaplot()
149            a.register('motion_notify', mouse_move)
150
151        If func is None, the event is deregistered.
152
153        Note that in TkAgg keyboard button presses don't generate an event.
154        """
155
156        if not self.events.has_key(type): return
157
158        if func is None:
159            if self.events[type] is not None:
160                # It's not clear that this does anything.
161                self.canvas.mpl_disconnect(self.events[type])
162                self.events[type] = None
163
164                # It seems to be necessary to return events to the toolbar.
165                if type == 'motion_notify':
166                    self.canvas.mpl_connect(type + '_event',
167                        self.figmgr.toolbar.mouse_move)
168                elif type == 'button_press':
169                    self.canvas.mpl_connect(type + '_event',
170                        self.figmgr.toolbar.press)
171                elif type == 'button_release':
172                    self.canvas.mpl_connect(type + '_event',
173                        self.figmgr.toolbar.release)
174
175        else:
176            self.events[type] = self.canvas.mpl_connect(type + '_event', func)
177
178
179    def show(self, hardrefresh=True):
180        """
181        Show graphics dependent on the current buffering state.
182        """
183        if not self.buffering:
184            if hardrefresh:
185                asaplotbase.show(self)
186            self.window.wm_deiconify()
187            self.canvas.show()
188
189    def terminate(self):
190        """
191        Clear the figure.
192        """
193        self.window.destroy()
194
195    def unmap(self):
196        """
197        Hide the ASAPlot graphics window.
198        """
199        self.window.wm_withdraw()
Note: See TracBrowser for help on using the repository browser.