myFig.py 8.33 KB
Newer Older
Yori 'AGy' Fournier's avatar
Yori 'AGy' Fournier committed
1
2
3
4
5
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# ================= FILE HEADER ========================================
#
6
#   myplotlib v1.0.1,
Yori 'AGy' Fournier's avatar
Yori 'AGy' Fournier committed
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#
#   @file      myFig.py
#   @author    Yori 'AGy' Fournier
#   @licence   CC-BY-SA
#
#   MyFig class: Overlay of matplotlib Figure class
#   It is done such that the user can concentrate on
#   the important aspect of the figure and not the
#   technical part.
#
#   @Class MyFig
#
#   @Constructor
#
#                fignum:      number of the Figure.
22
#                inputarg:    identifier of the raw data in G_RAWDATA.
Yori 'AGy' Fournier's avatar
Yori 'AGy' Fournier committed
23
24
25
26
27
28
29
30
#                reformat:    flag for reComputing plotted data
#                             from rawData.
#                debug:       flag for debugging, more verbatile.
#                (kw)args:    user defined arguments and keywords.
#
#   @section Functions
#
#            - printDebug:    print some debug information.
31
#
Yori 'AGy' Fournier's avatar
Yori 'AGy' Fournier committed
32
33
34
35
36
37
38
#            - plot:          overlay of Figure.plot() function,
#                             should be overwrited by the user.
#                             Consists of
#                             - creating axes,
#                             - formating the data,
#                             - adding the axis to the figure
#                             - plotting the axis
39
40
41
#
#            - update:        update the parameters in the
#                             keywords dictionary.
Yori 'AGy' Fournier's avatar
Yori 'AGy' Fournier committed
42
43
44
#
#   @section History
#
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#   v 0.1.1 - MyFig class for the myplotlib module.
#
#   v 1.0.0 - Changed rawdata with inputarg to allows any type
#             of rawdata, can be an array.
#
#             replace the attribute format (reserved word) with
#             formatted.
#
#   v 1.0.1 - Suppress the explicit definitions of the keywords.
#             by the introduction of the keywords dictionary.
#             All parameters in this dictionary are automatically
#             updated.
#
#             suppress the default value of fignum and hardcode it
#             to be -1.
#
#             add the attribute boundedToWin required for the
#             interactive mode of myplotlib.
Yori 'AGy' Fournier's avatar
Yori 'AGy' Fournier committed
63
64
65
66
67
#
# ======================================================================
#
#
# IMPORT ---------------------------------------------------------------
68
from . import os
69
from . import D_FIGSIZE, D_INPUTARG, D_DEBUG, D_REFORMAT, D_FORMATTED
70
from . import D_OFORMAT, D_OPATH
71
72
73
from . import DBUG, SEVR, INFO, SPCE, WARN
from . import G_RAWDATAS
from . import Figure, MyAxes
Yori 'AGy' Fournier's avatar
Yori 'AGy' Fournier committed
74
75


76
# Class MyFig Overwriting Matplotlib.figure.Figure
Yori 'AGy' Fournier's avatar
Yori 'AGy' Fournier committed
77
78
79
80
81
82
83
class MyFig(Figure):
  
    # Set the size of the Figure in inch
    # (private variable can not be updated)
    FIGSIZE = D_FIGSIZE
  
    # CONSTRUCTOR --------------------------------------------------------
84
85
    def __init__(self, *args, **kwargs):
        
86
        self.keywords = {'fignum': -1,  # need to be hard coded for interactive mode
87
88
89
                         'inputarg': D_INPUTARG,
                         'reformat': D_REFORMAT,
                         'debug': D_DEBUG,
90
                         'formatted': D_FORMATTED}
91
92
93
        
        # check keywords
        for keyword in self.keywords.keys():
94
            # if already in kwargs
95
96
97
98
99
100
            if keyword in kwargs.keys():
                # overwrite default value
                self.keywords[keyword] = kwargs[keyword]
                # suppress keyword from kwargs for Figure.__init__
                del kwargs[keyword]
            
101
        # add figsize in the kwargs for Figure.__init__
Yori 'AGy' Fournier's avatar
Yori 'AGy' Fournier committed
102
        kwargs['figsize'] = self.FIGSIZE
103
        
Yori 'AGy' Fournier's avatar
Yori 'AGy' Fournier committed
104
105
        # parent constructor
        Figure.__init__(self, *args, **kwargs)
106
        
107
108
109
        # This is required for the interactive mode
        # it ensures that a figure can not be bounded
        # to several windows and prevent the loss of canvas.
110
111
        self.boundedToWin = False
    
112
    
Yori 'AGy' Fournier's avatar
Yori 'AGy' Fournier committed
113
114
115
116
    # DEBUG --------------------------------------------------------------
    def printDebug(self):
        className = str(self.__class__.__name__)
        print('\n' + DBUG + "  {0} PARAMETERS: ".format(className))
117
118
        print(SPCE + "          Raw data: " + str(self.keywords['inputarg']))
        print(SPCE + "     ID the figure: " + str(self.keywords['fignum']))
Yori 'AGy' Fournier's avatar
Yori 'AGy' Fournier committed
119
        print(SPCE + "Size of the figure: " + str(self.FIGSIZE) + ' [inch] \n')
120
    
Yori 'AGy' Fournier's avatar
Yori 'AGy' Fournier committed
121
122
123
124
    # PLOT ---------------------------------------------------------------
    def plot(self):
        
        try:
125
            self.rawdata = G_RAWDATAS[self.keywords['inputarg']]
Yori 'AGy' Fournier's avatar
Yori 'AGy' Fournier committed
126
        except KeyError:
127
            print(SEVR + "The dataset {dataName} does not exist. --> FALSE".format(dataName=self.keywords['inputarg']))
Yori 'AGy' Fournier's avatar
Yori 'AGy' Fournier committed
128
129
130
131
132
133
134
135
136
            return(False)
        
        ratio = 6. / 8.  # height/width of the axes (in inch)
        frame = [0.0, 0.0, 1.0, 1.0]  # part of the fig that is available
        
        # create an axes MyAxes with a given rect
        ax = MyAxes(self, ratio, frame)
        
        # reformat the data if needed (default True)
137
        if((self.keywords['reformat']) or (not self.keywords['formatted'])):
Yori 'AGy' Fournier's avatar
Yori 'AGy' Fournier committed
138
139
            try:
                status = ax.formatRawData(self.rawdata)
140
                self.keywords['formatted'] = True
Yori 'AGy' Fournier's avatar
Yori 'AGy' Fournier committed
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
            except (TypeError, KeyError):
                print(SEVR + 'The formatting of the data was apparently wrong. --> EXIT')
                return(False)
        
        if(not status): return(False)
        
        # add the axis to the figure
        self.add_axes(ax)
        
        # try to plot the Axes
        status = ax.plotting()
        if(not status): return(False)
        
        return(True)
   
    # UPDATE -------------------------------------------------------------
157
    def update(self, **kwargs):
Yori 'AGy' Fournier's avatar
Yori 'AGy' Fournier committed
158
     
159
160
161
162
163
        # check keywords
        for keyword in self.keywords.keys():
            # if already in kwargs overwrite default value
            if keyword in kwargs.keys():
                self.keywords[keyword] = kwargs[keyword]
164
165
166
167
168
    
    
    # PRINT 2 FILE -------------------------------------------------------
    def print2file(self, filename, *args, **kwargs):
        
169
        # get the keywords
170
        debug = kwargs.get('debug', D_DEBUG)
171
172
173
        oformat = kwargs.get('oformat', D_OFORMAT)
        opath = kwargs.get('opath', D_OPATH)
        
174
        # set the dpi
175
176
177
178
179
180
181
182
        if(oformat == 'png'):
            dpi = 300.
            addMetaData = True  # NOT YET IMPLEENTED
        else:
            dpi = 100.
            addMetaData = False  # NOT YET IMPLEMENTED
        
        from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
183
184
185
186
187
188
189
190
        # if the figure is boundedToWin
        # save to canvas in a local variable and restore after saving to file.
        if self.boundedToWin:
            winCanvas = self.canvas
        else:
            winCanvas = None
            
        canvas = FigureCanvas(self)  # the canvas of the figure changed
191
192
193
194
195
196
197
198
199
200
201
202
203
204
        
        # Plot the figure 
        self.plot()
        
        # draw the figure on the new canvas
        canvas.draw()  # not really needed (savefig does that)
        
        # check if the extention is in the name
        if '.png' in str(filename):
            oformat = 'png'
            filename = filename[:-4]
        elif '.eps' in str(filename):
            oformat = 'eps'
            filename = filename[:-4]
205
        
206
207
208
209
210
211
212
        # check if the path is in the name
        if '/' in str(filename):
            if(debug):
                print(WARN + "I detect that the path is in the name of the file, will ignore D_OPATH.")
            arg = filename
            filename = os.path.basename(arg)
            opath = os.path.dirname(arg)
213
214
215
216
217
218
219
220
221
222
223
        
        # take care of the . in the extention
        if oformat[0] == '.':
            oformat = oformat[1:]
        
        # clean the output path
        if str(opath)[-1] == '/':
            opath = str(opath)[:-1]
        else:
            opath = str(opath)
        
224
        # print into a file
225
226
227
228
229
230
231
232
233
234
        try:
            self.savefig(str(opath) + '/' + str(filename) + '.' + str(oformat), dpi=dpi)  # ! this not the save from plt but from fig
        except IOError:
            print(SEVR + 'the path to the file does not exists:')
            print(SPCE + str(opath) + '/' + str(filename) + '.' + str(oformat) + ' --> EXIT')
            return(False)
        except:
            print(SEVR + 'Can not save file. sorry --> EXIT')
            return(False)
        
235
236
237
238
        # restore the former canvas
        if winCanvas is not None:
            self.canvas = winCanvas
        
239
        return(True)