myWin_WXAgg.py 7.14 KB
Newer Older
1
2
3
4
5
6
7
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# ================= FILE HEADER ========================================
#
#   myplotlib v1.0.1,
#
8
#   @file      myWin_WXAgg.py
9
10
11
12
13
14
15
#   @author    Yori 'AGy' Fournier
#   @licence   CC-BY-SA
#
#   MyWin class: Overlay of matplotlib FigureManager
#   class. It allows a cleaner and more confortable
#   usage of windows.
#
16
#   @Class MyWin_WXAgg
17
18
19
#
#   @Constructor
#
20
21
22
23
24
25
#                fig:           the MyFig object that need to be drawn
#                show:          a flag to show the window just after
#                               creation. (default: True)
#                fignum:        number of both the Window and the Figure.
#                debug:         flag for debugging, more verbatile.
#                (kw)args:      user defined arguments and keywords.
26
27
28
#
#   @section Functions
#
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#            - _boundFigure_:   bound a figure to the window (priv.)
#
#            - _unboundFigure_: unbound a figure to the window (priv.)
#
#            - set_figure:      a clean way of setting a new figure
#                               to the window.
#
#            - refresh:         redraw the window
#                               - clean the figure
#                               - plot the figure
#                               - draw the canvas
#
#            - drawFigure:      draw a given figure on the window
#                               - set the figure of needed
#                               - refresh
#
#            - close:           close the window
#
47
48
49
50
51
52
53
#   @section History
#
#   v 1.0.1 - MyWin class for the myplotlib module.
#
# ======================================================================
#
# IMPORT ---------------------------------------------------------------
54
55
56
57
from . import INFO, SEVR, WARN, DBUG, SPCE
from . import rcParams
from . import _G_WINDOWS
from . import np
58

59
60
61
62
63
# For the WXAgg backend
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg
from matplotlib.backends.backend_wx import FigureManagerWx
from matplotlib.backends.backend_wx import _create_wx_app
from matplotlib.backends.backend_wxagg import FigureFrameWxAgg
64
65


66
# Class MyWin Overwriting the disgusting Matplotlib.FigureManager class
67
68
class MyWin_WXAgg(FigureManagerWx):
    
69
    # CONSTRUCTOR ------------------------------------------------------
70
71
    def __init__(self, fig, show=True, *args, **kwargs):
        
72
        # set the dpi to 75 (correct value for screen)
73
74
75
        if(fig.dpi != 75.):
            fig.dpi = 75.
        
76
77
78
        # Get the debug value
        debug = kwargs.get('debug', False)
        
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
        # Get the user specified ID of the window or set it to 0
        if 'fignum' in kwargs.keys():
            num = kwargs['fignum']
            fignumSpecifiedByUser = True
        else:
            num = 0
            fignumSpecifiedByUser = False
        
        # if ID already used
        if(num in [(window.num) for window in _G_WINDOWS]):
            
            # if user specified fignum then close former window and create new one
            if(fignumSpecifiedByUser):
                if(debug):
                    print(DBUG + "The fignum you specified already exists, I'll close the former window")
                # Close the window with the specified number
                _G_WINDOWS[np.where([(window.num == num) for window in _G_WINDOWS])[0][0]].close()
            else:
                # If user didn't specified a fignum
                # increase ID until found a free one
                while(num in [(window.num) for window in _G_WINDOWS]):
                    num = num + 1
101
        
102
103
104
105
        # If debug print the ID of the window
        if(debug):
            print(DBUG + "You choosed num = " + str(num))
        
106
107
        # before creating anything verify that the fig is not already
        # bounded to another window
108
        if fig.boundedToWin:
109
            # if it is the case close the bounded window.
110
            win = _G_WINDOWS[np.where([(window.num == fig.keywords['fignum']) for window in _G_WINDOWS])[0][0]]
111
112
            win.close()
        
113
        # Call the ugly FigureManagerWxAgg class
114
        # (already wondering if this is not a mistake...)
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
        if(debug):
            print(INFO + "Used WXAgg backend")
        
        # create master app
        _create_wx_app()
        
        # create the frame
        frame = FigureFrameWxAgg(num, fig)
        
        # create the figManager (our window)
        FigureManagerWx.__init__(self, frame.canvas, num, frame)
        
        # required for wxagg
        self.frame.figmgr = self
        
130
        # bound the figure to the window
131
132
133
        self.canvas.figure.boundedToWin = True
        self.canvas.figure.keywords['fignum'] = num
        
134
135
136
        # add the window in the global variable _G_WINDOWS
        # this guarenty that you never loose a window
        # (see myTool.py getWindow(num))
137
        _G_WINDOWS.append(self)
138
139
        
        # if show is on, then show the window
140
        if show:
141
142
143
144
            self.canvas.figure.clf()
            self.canvas.figure.plot()
            self.show()
            self.canvas.draw()
145
    
146
147
    
    # BOUND ------------------------------------------------------------
148
149
150
151
152
153
154
    def _boundFigure_(self, fig):
        
        fig.canvas = self.canvas
        self.canvas.figure = fig
        self.canvas.figure.boundedToWin = True
        self.canvas.figure.keywords['fignum'] = self.num
    
155
156
    
    # UNBOUND ----------------------------------------------------------
157
158
159
160
161
    def _unboundFigure_(self):
        
        self.canvas.figure.boundedToWin = False
        self.canvas.figure.keywords['fignum'] = -1
    
162
163
164
    
    # SETTERS ----------------------------------------------------------
    # SET FIGURE -------------------------------------------------------
165
166
    def set_figure(self, fig):
        
167
        # first unbound the former figure
168
169
        self._unboundFigure_()
        
170
171
        # if the new figure is already bounded close
        # its former container.
172
        if fig.boundedToWin:
173
            win = _G_WINDOWS[np.where([(window.num == fig.keywords['fignum']) for window in _G_WINDOWS])[0][0]]
174
            win.close()
175
176
        
        # bound the new figure
177
178
        self._boundFigure_(fig)
    
179
180
    
    # REFRESH ----------------------------------------------------------
181
    def refresh(self):
182
183
184
185
186
187
        
        self.canvas.figure.clf()
        self.canvas.figure.plot()
        self.canvas.draw()
        self.canvas.figure.plot()
        self.canvas.draw()
188
    
189
190
    
    # DRAW -------------------------------------------------------------
191
    def drawFigure(self, fig):
192
193
        
        # if the figure is not the current one
194
        if(fig.keywords['fignum'] != self.num):
195
            # cleanly set the new figure
196
197
            self.set_figure(fig)
        
198
        # and refresh
199
200
        self.refresh()
    
201
202
    
    # CLOSE ------------------------------------------------------------
203
204
205
206
    def close(self):
        
        self._unboundFigure_()
        self.destroy()
207
        del _G_WINDOWS[np.where([(window == self) for window in _G_WINDOWS])[0][0]]
208
209
210
211
212
        # remark if you create the window like:
        # win = MyWin(fig)
        # then win is still refering the self
        # and therefore not yet freed
        # del win would free it entirely.