myWin_WXAgg.py 7.43 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
            self.canvas.figure.plot()
            self.show()
            self.canvas.draw()
144
    
145
146
    
    # BOUND ------------------------------------------------------------
147
148
149
150
151
152
153
    def _boundFigure_(self, fig):
        
        fig.canvas = self.canvas
        self.canvas.figure = fig
        self.canvas.figure.boundedToWin = True
        self.canvas.figure.keywords['fignum'] = self.num
    
154
155
    
    # UNBOUND ----------------------------------------------------------
156
157
158
159
160
    def _unboundFigure_(self):
        
        self.canvas.figure.boundedToWin = False
        self.canvas.figure.keywords['fignum'] = -1
    
161
162
163
    
    # SETTERS ----------------------------------------------------------
    # SET FIGURE -------------------------------------------------------
164
165
    def set_figure(self, fig):
        
166
        # first unbound the former figure
167
168
        self._unboundFigure_()
        
169
170
        # if the new figure is already bounded close
        # its former container.
171
        if fig.boundedToWin:
172
            win = _G_WINDOWS[np.where([(window.num == fig.keywords['fignum']) for window in _G_WINDOWS])[0][0]]
173
            win.close()
174
175
        
        # bound the new figure
176
177
        self._boundFigure_(fig)
    
178
179
    
    # REFRESH ----------------------------------------------------------
180
    def refresh(self):
181
        
182
183
        # in the case the figure got another canvas
        # rebound the figure. This situation should not happend!!
184
        if self.canvas != self.canvas.figure.canvas:
185
            print(WARN + "Something weird happend, the canvas of the figure have been changed")
186
187
188
            self.set_figure(self.canvas.figure)
        
        #refresh
189
190
191
192
        self.canvas.figure.plot()
        self.canvas.draw()
        self.canvas.figure.plot()
        self.canvas.draw()
193
194
        
        return(True)
195
    
196
197
    
    # DRAW -------------------------------------------------------------
198
    def drawFigure(self, fig):
199
200
        
        # if the figure is not the current one
201
        if(fig.keywords['fignum'] != self.num):
202
            # cleanly set the new figure
203
204
            self.set_figure(fig)
        
205
        # and refresh
206
207
        self.refresh()
    
208
209
    
    # CLOSE ------------------------------------------------------------
210
211
212
213
    def close(self):
        
        self._unboundFigure_()
        self.destroy()
214
        del _G_WINDOWS[np.where([(window == self) for window in _G_WINDOWS])[0][0]]
215
216
217
218
219
        # 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.