source: trunk/python/asaplotgui.py @ 1563

Last change on this file since 1563 was 1563, checked in by Malte Marquarding, 15 years ago

fix for ticket #160: allow user to select the size of plotter and also honour matplotlib.rcParams

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