Changeset 6344


Ignore:
Timestamp:
Feb 16, 2009, 2:12:14 PM (16 years ago)
Author:
rwilson
Message:

Recursion error - move to linux box - see if matplotlib version change helps.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • misc/tools/plotcsv/plotcsv.py

    r6341 r6344  
    1414import getopt
    1515import pylab
     16try:
     17    import cpickle
     18except:
     19    import pickle
    1620
    1721try:
     
    9397MinimumHeight = ''
    9498MaximumHeight = ''
     99
     100# Flag strings - keys in the 'options' dictionary
     101X_DATACOL = 'x_datacol'
     102Y_DATACOL = 'y_datacol'
     103X_RANGE = 'x_range'
     104Y_RANGE = 'y_range'
     105FILENAME = 'filename'
     106SIZE = 'size'
     107TITLE = 'title'
     108X_LABEL = 'x_label'
     109Y_LABEL = 'y_label'
     110
     111CSVWildcard = 'CSV files (*.csv)|*.csv|All files (*.*)|*.*'
    95112
    96113# Flag strings - keys in the 'options' dictionary
     
    130147
    131148
    132 ##
    133 # @brief Issue an error message.
    134 # @param msg The message.
    135 def error(msg):
    136     print >>sys.stderr, msg
    137     sys.exit(10)
    138 
    139  
     149################################################################################
     150# An object that behaves like a dictionary but is pickled/unpickled from a file.
     151################################################################################
     152
     153class Config(object):
     154    """
     155    An object that behaves like a dictionary but is persistent:
     156
     157        cfg = Config('filename')
     158        cfg['save'] = 'A saved value'
     159        cfg[123] = 'value 123'
     160        print cfg['save']
     161
     162    The values stored in the file 'filename' will be available to any
     163    application using that config file.
     164    """
     165
     166    def __init__(self, configfile=None):
     167        """
     168        __init__(self, String filename=None) -> Config
     169        """
     170
     171        self.delconf = False
     172        self.cfgdict = {}
     173        self.changed = False
     174        if not configfile:
     175            self.delconf = True
     176            configfile =tempfile.mktemp()
     177        self.configfile = os.path.abspath(configfile)
     178        if os.path.exists(self.configfile):
     179            try:
     180                f = open(configfile, "r")
     181                u = pickle.Unpickler(f)
     182                self.cfgdict = u.load()
     183            except pickle.UnpicklingError, e:
     184                print e
     185            except:
     186                pass
     187            else:
     188                f.close()
     189
     190    def __setitem__(self, key, value):
     191        """
     192        Override to allow: cfg[<key>] = <value>
     193        """
     194        self.cfgdict[key] = value
     195        self.changed = True
     196
     197    def __getitem__(self, key):
     198        """
     199        Override to allow: <var> = cfg[<key>]
     200        """
     201        return self.cfgdict.get(key, None)
     202
     203    def __str__(self):
     204        """
     205        __str__(self) -> String
     206        """
     207        return "<config object at %s>" % hex(id(self))
     208
     209    def getfilename(self):
     210        """
     211        getfilename(self) -> String filename
     212        """
     213        return self.configfile
     214
     215    def setdeleted(self):
     216        """
     217        setdeleted(self)
     218        """
     219        self.delconf = True
     220
     221    def save(self):
     222        """
     223        save(self)
     224        """
     225        try:
     226            f = open(self.configfile, "w")
     227            p = pickle.Pickler(f)
     228            p.dump(self.cfgdict)
     229        except pickle.PicklingError, e:
     230            print e
     231        else:
     232            f.close()
     233        self.changed = False
     234
     235    def close(self):
     236        """
     237        close(self)
     238        """
     239        if self.changed:
     240            self.save()
     241        if self.delconf:
     242            if os.path.exists(self.configfile):
     243                os.remove(self.configfile)
     244
     245    def __del__(self):
     246        """
     247        __del__(self)
     248        """
     249        self.close()
     250
     251################################################################################
     252# Plot routines
     253################################################################################
     254
    140255##
    141256# @brief Plot a sequence of data.
    142257# @param x_data The X data sequence to plot.
    143 # @param y_data A list of one or more Y data sequences to plot.
     258# @param y_data The Y data sequence to plot.
    144259# @param options A dictionary of plot options.
    145260def plot_data(x_data, y_data, options):
     261    print 'x_data=%s' % str(x_data)
     262    print 'y_data=%s' % str(y_data)
    146263    pylab.plot(x_data, y_data)
    147     pylab.title(options.get(TITLE, ''))
    148     pylab.grid(True)
    149 
    150     # if user request a particular Y range
     264
     265    # if user requested a particular Y range
    151266    if not options[Y_RANGE] is None:
    152267        try:
     
    158273        pylab.ylim(ymin=minimum, ymax=maximum)
    159274
    160     pylab.xlabel(options.get(X_LABEL, ''))
    161     pylab.ylabel(options.get(Y_LABEL, ''))
    162 
    163     pylab.show()
    164 
    165275
    166276##
    167 # @brief Plot a data file.
     277# @brief Get CSV data from a file.
    168278# @param filename Path to the data file to plot.
     279# @param x_hdr The X axis title string (or index).
     280# @param y_hdr The Y axis title string (or index).
    169281# @param options A dictionary of options.
    170 def plot_file(filename, options=None):
    171     # set options defaults
    172     opts = options
    173     if opts is None:
    174         opts = {}
    175 
    176     opts[X_DATACOL] = opts.get(X_DATACOL, '0')
    177     opts[Y_DATACOL] = opts.get(Y_DATACOL, '1')
    178     opts[SIZE] = opts.get(SIZE, '800,600')
    179     opts[Y_RANGE] = opts.get(Y_RANGE, None)
    180 
     282def getCSVData(filename, x_hdr, y_hdr, options):
    181283    # get contents of data file
    182284    # after this, 'header' is list of column header strings
     
    189291    fd.close()
    190292    header = data[0]
    191     del data[0]
     293    del data[0]         # get rid of header in dataset
    192294
    193295    # convert column specifiers to 'int' if required
    194296    try:
    195         index = int(opts[X_DATACOL])
     297        index = int(x_hdr)
    196298    except:
    197299        try:
    198             index = header.index(opts[X_DATACOL])
     300            index = header.index(x_hdr)
    199301        except ValueError:
    200             error("Sorry, X column header '%s' isn't in the data file." % opts[X_DATACOL])
    201     opts[X_DATACOL] = index
     302            error("Sorry, X column header '%s' isn't in the data file." % x_hdr)
     303    options[X_DATACOL] = index
    202304
    203305    try:
    204         index = int(opts[Y_DATACOL])
     306        index = int(y_hdr)
    205307    except:
    206308        try:
    207             index = header.index(opts[Y_DATACOL])
     309            index = header.index(y_hdr)
    208310        except ValueError:
    209             error("Sorry, Y column header '%s' isn't in the data file." % opts[Y_DATACOL])
    210     opts[Y_DATACOL] = index
     311            error("Sorry, Y column header '%s' isn't in the data file." % y_hdr)
     312    options[Y_DATACOL] = index
    211313   
    212     # extract required columns from the data
    213     x_col = opts[X_DATACOL]
    214     y_col = opts[Y_DATACOL]
     314    # extract required columns from the data (int at this point)
     315    x_col = options[X_DATACOL]
     316    y_col = options[Y_DATACOL]
    215317
    216318    # get max column number, check requested columns
     
    227329    y_label = header[y_col].title()
    228330
    229     opts[TITLE] = 'File: %s' % filename
    230     opts[X_LABEL] = x_label
    231     opts[Y_LABEL] = y_label
    232 
    233     plot_data(x_data, y_data, opts)
     331    options[X_LABEL] = x_label
     332    options[Y_LABEL] = y_label
     333
     334    return (x_data, y_data)
     335
     336
     337##
     338# @brief Plot data files.
     339# @param filenames List of full pathnames to plot.
     340# @param options A dictionary of options.
     341def plot_files(filenames, options=None):
     342    # set options defaults
     343    opts = options
     344    if opts is None:
     345        opts = {}
     346
     347##    pylab.title(options.get(TITLE, ''))
     348##    pylab.xlabel(options.get(X_LABEL, ''))
     349##    pylab.ylabel(options.get(Y_LABEL, ''))
     350##    pylab.grid(True)
     351##
     352    for f in filenames:
     353        (x_data, y_data) = getCSVData(f, opts[X_LABEL], opts[Y_LABEL], options)
     354        print 'x_data=%s' % str(x_data)
     355        print 'y_data=%s' % str(y_data)
     356        pylab.plot(x_data, y_data)
     357
     358    pylab.show()
    234359
    235360
     
    258383        wx.StaticBox(p, -1, 'CSV files', (3, Y_OFFSET),
    259384                     size=(BOX_CSV_WIDTH, BOX_CSV_HEIGHT))
    260 
    261 ##        wx.StaticText(p, -1, 'Minimum wave height',
    262 ##                      pos=(GEN_LABELXOFFSET, Y_OFFSET),
    263 ##                      size=(CTL_WIDTH, CTL_HEIGHT), style=wx.ALIGN_RIGHT)
    264 ##        self.txtMinH = wx.TextCtrl(p, -1, size=(100, 20),
    265 ##                                   pos=(GEN_TEXTXOFFSET, Y_OFFSET))
    266385        Y_OFFSET += GEN_DELTAY
    267 
    268 ##        self.lstGenerate = wx.ListCtrl(p, -1, pos=(8, Y_OFFSET),
    269 ##                                       size=(TEXTLIST_WIDTH,TEXTLIST_HEIGHT),
    270 ##                                       style=wx.LC_SINGLE_SEL)
    271 ##        self.txtCSVFiles = wx.TextCtrl(p, -1,
    272 ##                        "Here is a looooooooooooooong line of text set in the control.\n\n"
    273 ##                        "The quick brown fox jumped over the lazy dog...",
    274 ##                       pos=(8, Y_OFFSET), size=(TXT_CSVFILE_WIDTH,TXT_CSVFILE_HEIGHT), style=wx.TE_MULTILINE|wx.TE_PROCESS_ENTER)
    275         self.txtCSVFiles = wx.ListBox(p, -1, pos=(8, Y_OFFSET), size=(TXT_CSVFILE_WIDTH,TXT_CSVFILE_HEIGHT))
     386        self.txtCSVFiles = wx.ListBox(p, -1, pos=(8, Y_OFFSET),
     387                                      size=(TXT_CSVFILE_WIDTH,
     388                                            TXT_CSVFILE_HEIGHT))
     389        self.CSVFiles = []
    276390        Y_OFFSET += TXT_CSVFILE_HEIGHT + MARGIN
    277391        x = FORM_WIDTH/2 - BUTTON_WIDTH - DOUBLE_BUTTON_OFFSET
     
    288402        wx.StaticText(p, -1, 'X-Column',
    289403                      pos=(COLLAB_X_OFFSET, Y_OFFSET+LAB_CTRL_OFFSET), style=wx.ALIGN_LEFT)
    290         self.cbXColHdr = wx.ComboBox(p, -1, pos=(COLLAB_X_OFFSET+50, Y_OFFSET),
    291                                      size=(80, -1), style=wx.CB_DROPDOWN)
     404        self.cbXColHdr = wx.Choice(p, -1, pos=(COLLAB_X_OFFSET+50, Y_OFFSET),
     405                                   size=(80, -1))
     406        self.XColHdr = []
    292407        wx.StaticText(p, -1, 'Y-Column',
    293408                      pos=(FORM_WIDTH/2+COLLAB_X_OFFSET,
    294409                           Y_OFFSET+LAB_CTRL_OFFSET), style=wx.ALIGN_LEFT)
    295410        x = FORM_WIDTH/2 + COLLAB_X_OFFSET
    296         self.cbYColHdr = wx.ComboBox(p, -1, pos=(x+50, Y_OFFSET),
    297                                      size=(80, -1), style=wx.CB_DROPDOWN)
     411        self.cbYColHdr = wx.Choice(p, -1, pos=(x+50, Y_OFFSET), size=(80, -1))
     412        self.YColHdr = []
    298413
    299414        Y_OFFSET += BUTTON_HEIGHT + MARGIN
    300415        x = FORM_WIDTH/2 - BUTTON_WIDTH/2
    301         self.btnPlote = wx.Button(p, label="Plot", pos=(x, Y_OFFSET),
     416        self.btnPlot = wx.Button(p, label="Plot", pos=(x, Y_OFFSET),
    302417                                     size=(100, BUTTON_HEIGHT))
    303418
    304 
    305 
    306 
    307 
    308 ##        wx.StaticText(p, -1, 'Maximum wave height',
    309 ##                      pos=(GEN_LABELXOFFSET, Y_OFFSET),
    310 ##                      size=(CTL_WIDTH, CTL_HEIGHT), style=wx.ALIGN_RIGHT)
    311 ##        self.chXColHdr = wx.Choice(p, -1, size=(CHBOX_WIDTH, CHBOX_HEIGHT),
    312 ##                                   pos=(10,Y_OFFSET))
    313 
    314 
    315 
    316 
    317 
    318 
    319 ##        wx.StaticText(p, -1, 'Maximum wave height',
    320 ##                      pos=(GEN_LABELXOFFSET, Y_OFFSET),
    321 ##                      size=(CTL_WIDTH, CTL_HEIGHT), style=wx.ALIGN_RIGHT)
    322 ##        self.txtMaxH = wx.TextCtrl(p, -1, size=(100, 20),
    323 ##                                   pos=(GEN_TEXTXOFFSET, Y_OFFSET))
    324 ##        Y_OFFSET += GEN_DELTAY
    325 ##        x = FORM_WIDTH/2 - BUTTON_WIDTH/2
    326 ##        self.btnGenerate = wx.Button(p, label="List",
    327 ##                                     pos=(x, Y_OFFSET),
    328 ##                                     size=(100, BUTTON_HEIGHT))
    329 ##        Y_OFFSET += GEN_DELTAY + BUTTON_HEIGHT/2
    330 ##
    331 ##        self.lstGenerate = wx.ListCtrl(p, -1, pos=(8, Y_OFFSET),
    332 ##                                       size=(TEXTLIST_WIDTH,TEXTLIST_HEIGHT),
    333 ##                                       style=wx.LC_REPORT|wx.LC_SINGLE_SEL)
    334 ##       
    335 ##        Y_OFFSET += TEXTLIST_HEIGHT + 20
    336 ##        self.Bind(wx.EVT_BUTTON, self.GenerateClick, self.btnGenerate)
    337 ##        self.lstGenerate.Bind(wx.EVT_LIST_ITEM_SELECTED,
    338 ##                              self.OnItemSelected, self.lstGenerate)
    339 ##
    340 ##        # start laying out get_multimux controls
    341 ##        wx.StaticBox(p, -1, 'multimux_grid', (3, Y_OFFSET),
    342 ##                     size=(BOX_WIDTH, BOX2_HEIGHT))
    343 ##        Y_OFFSET += 18
    344 ##        wx.StaticText(p, -1, 'Quake ID', pos=(GEN_LABELXOFFSET, Y_OFFSET),
    345 ##                      size=(CTL_WIDTH, CTL_HEIGHT), style=wx.ALIGN_RIGHT)
    346 ##        self.txtQuakeID = wx.TextCtrl(p, -1, size=(100, 20),
    347 ##                                      pos=(GEN_TEXTXOFFSET, Y_OFFSET))
    348 ##        Y_OFFSET += GEN_DELTAY
    349 ##        x = FORM_WIDTH/2 - BUTTON_WIDTH - DOUBLE_BUTTON_OFFSET
    350 ##        self.btnMultimux = wx.Button(p, label="Multimux", pos=(x, Y_OFFSET),
    351 ##                                     size=(100, BUTTON_HEIGHT))
    352 ##        x = FORM_WIDTH/2 + DOUBLE_BUTTON_OFFSET
    353 ##        self.btnGrid = wx.Button(p, label="Grid", pos=(x, Y_OFFSET),
    354 ##                                     size=(100, BUTTON_HEIGHT))
    355 ##        Y_OFFSET += GEN_DELTAY + BUTTON_HEIGHT/2
    356 ##        self.lstMultimux = wx.ListCtrl(p, -1, pos=(8, Y_OFFSET),
    357 ##                                       size=(TEXTLIST_WIDTH,TEXTLIST_HEIGHT),
    358 ##                                       style=wx.LC_REPORT|wx.LC_SINGLE_SEL)
    359 ##        Y_OFFSET += TEXTLIST_HEIGHT + 20
    360 ##        self.Bind(wx.EVT_BUTTON, self.MultimuxClick, self.btnMultimux)
    361 ##        self.Bind(wx.EVT_BUTTON, self.GridClick, self.btnGrid)
    362 
     419        self.Bind(wx.EVT_BUTTON, self.AddCSVFile, self.btnAddCSVFile)
     420        self.Bind(wx.EVT_BUTTON, self.DelCSVFile, self.btnDelCSVFile)
     421        self.Bind(wx.EVT_BUTTON, self.PlotFiles, self.btnPlot)
    363422        self.Bind(wx.EVT_CLOSE, self.doStateSave)
     423        self.Bind(wx.EVT_CLOSE, self.doStateSave)
     424        self.cfg = Config(ConfigFilename)
     425        self.common_headers = None
    364426        self.doStateRestore()
     427        self.updateHdrChoices()
     428       
     429    def AddCSVFile(self, event):
     430        """Add a CSV file to the listbox"""
     431
     432        dlg = wx.FileDialog(self, message='Choose a CSV file',
     433                            defaultDir=self.file_dir,
     434                            defaultFile='',
     435                            wildcard=CSVWildcard,
     436                            style=wx.OPEN | wx.CHANGE_DIR)
     437
     438        if dlg.ShowModal() == wx.ID_OK:
     439            # This returns a list of  files that were selected.
     440            path = dlg.GetPath()
     441            self.file_dir = dlg.GetDirectory()
     442            dlg.Destroy()
     443            if path not in self.CSVFiles:
     444                headers = self.getHeaders(path)
     445                if headers:
     446                    common_headers = self.orHeaders(headers)
     447                    if not common_headers or len(common_headers) < 2:
     448                        self.error("Sorry, file '%s' doesn't have enough headers in common with current files" % path)
     449                    else:
     450                        self.headers.append(headers)
     451                        self.common_headers = common_headers
     452                        self.CSVFiles.append(path)
     453                        self.txtCSVFiles.Append(path)
     454                else:
     455                    self.error("Sorry, file '%s' doesn't appear to be a CSV file" % path)
     456                self.updateHdrChoices()
     457
     458    def DelCSVFile(self, event):
     459        """Add a CSV file to the listbox"""
     460
     461        sel = self.txtCSVFiles.GetSelections()
     462        if sel:
     463            sel = sel[0]
     464            self.txtCSVFiles.Delete(sel)
     465            del self.CSVFiles[sel]
     466            del self.headers[sel]
     467            self.common_headers = self.GenCommonHeaders(self.headers)
     468            self.updateHdrChoices()
    365469
    366470    def doStateSave(self, event):
    367         """
    368         Save state here.
    369         """
    370 ##        self.cfg['OutputDirectory'] = self.txtOutputDir.GetValue()
    371 ##        self.cfg['Region'] = self.cbRegion.GetValue()
    372 ##        self.cfg['GaugeNumber'] = self.txtTGN.GetValue()
    373 ##        self.cfg['MinimumHeight'] = self.txtMinH.GetValue()
    374 ##        self.cfg['MaximumHeight'] = self.txtMaxH.GetValue()
    375 ##        self.cfg.save()
     471        """Save state from 'self' variables."""
     472
     473        self.cfg['CSVFiles'] = self.CSVFiles
     474        self.cfg['XColHdr'] = self.XColHdr
     475        self.cfg['XColHdrSelection'] = self.cbXColHdr.GetSelection()
     476        self.cfg['YColHdr'] = self.YColHdr
     477        self.cfg['YColHdrSelection'] = self.cbYColHdr.GetSelection()
     478        self.cfg['file_dir'] = self.file_dir
     479
     480        self.cfg.save()
     481        event.Skip(True)
     482
     483    def doStateRestore(self):
     484        """Restore state to 'self' variables."""
     485
     486        self.CSVFiles = self.cfg['CSVFiles']
     487        if self.CSVFiles is None:
     488            self.CSVFiles = []
     489        self.XColHdr = self.cfg['XColHdr']
     490        if self.XColHdr is None:
     491            self.XColHdr = []
     492        # -1 here means 'no selection'
     493        self.XColHdrSelection = self.cfg['XColHdrSelection', -1]
     494        self.YColHdr = self.cfg['YColHdr']
     495        if self.YColHdr is None:
     496            self.YColHdr = []
     497        # -1 here means 'no selection'
     498        self.YColHdrSelection = self.cfg['YColHdrSelection', -1]
     499        self.file_dir = self.cfg['file_dir']
     500        if self.file_dir is None:
     501            self.file_dir = os.getcwd()
     502
     503        # put data into controls
     504        self.headers = []
     505        for (i, f) in enumerate(self.CSVFiles):
     506            headers = self.getHeaders(f)
     507            self.headers.append(headers)
     508            self.txtCSVFiles.Insert(f, i)
     509
     510    def getHeaders(self, filename):
     511        '''Get header list from a file'''
     512
     513        try:
     514            fd = open(filename, 'r')
     515            hdr = fd.readline()
     516            fd.close()
     517        except:
     518            return None
     519
     520        hdr = hdr.split(',')
     521        hdr = [x.strip() for x in hdr]
     522
     523        return hdr
    376524       
    377         event.Skip(True)
    378 
    379     def doStateRestore(self):
    380         """
    381         Restore state here - globals have been set and tested sane
    382         """
    383 ##        global Region, GaugeNumber, MinimumHeight, MaximumHeight
    384 ##
    385 ##        cfg = Config(ConfigFilename)
    386 ##        output_dir = cfg['OutputDirectory']
    387 ##        Region = cfg['Region']
    388 ##        GaugeNumber = cfg['GaugeNumber']
    389 ##        if GaugeNumber:
    390 ##            GaugeNumber = int(GaugeNumber)
    391 ##        MinimumHeight = cfg['MinimumHeight']
    392 ##        if MinimumHeight:
    393 ##            MinimumHeight = float(MinimumHeight)
    394 ##        MaximumHeight = cfg['MaximumHeight']
    395 ##        if MaximumHeight:
    396 ##            MaximumHeight = float(MaximumHeight)
    397 ##
    398 ##        self.cfg = cfg
    399 ##
    400 ##        region_name = None
    401 ##        for (name, dir) in Regions:
    402 ##            if name == Region:
    403 ##                region_name = name
    404 ##        if not region_name:
    405 ##            Region = ''
    406 ##
    407 ##        if output_dir:
    408 ##            self.txtOutputDir.WriteText(output_dir)
    409 ##        self.cbRegion.SetStringSelection(Region)
    410 ##        if GaugeNumber:
    411 ##            self.txtTGN.WriteText(str(GaugeNumber))
    412 ##        if MinimumHeight:
    413 ##            self.txtMinH.WriteText(str(MinimumHeight))
    414 ##        if MaximumHeight:
    415 ##            self.txtMaxH.WriteText(str(MaximumHeight))
     525    def updateHdrChoices(self):
     526        '''Update choice controls with header lists.
     527
     528        Keep initially visible strings visible afterwards, if posssible.
     529        '''
     530
     531        selected_x = self.cbXColHdr.GetStringSelection()
     532        selected_y = self.cbYColHdr.GetStringSelection()
    416533       
     534        self.cbXColHdr.Clear()
     535        self.cbYColHdr.Clear()
     536
     537        if self.common_headers:
     538            self.cbXColHdr.Enable()
     539            self.cbYColHdr.Enable()
     540            self.btnPlot.Enable()
     541            for h in self.common_headers:
     542                self.cbXColHdr.Append(h)
     543                self.cbYColHdr.Append(h)
     544            if selected_x in self.common_headers:
     545                index = self.common_headers.index(selected_x)
     546                self.cbXColHdr.SetSelection(index)
     547            if selected_y in self.common_headers:
     548                index = self.common_headers.index(selected_y)
     549                self.cbYColHdr.SetSelection(index)
     550        else:
     551            self.cbXColHdr.Disable()
     552            self.cbYColHdr.Disable()
     553            self.btnPlot.Disable()
     554
     555    def orHeaders(self, new_header):
     556        '''Update X & Y column header choices'''
     557
     558        if self.common_headers:
     559            result = [x for x in new_header if x in self.common_headers]
     560        else:
     561            result = new_header
     562        return result
     563
     564    def GenCommonHeaders(self, headers):
     565        '''Get new set of common headers'''
     566
     567        result = []
     568        for header in headers:
     569            if result:
     570                result = [x for x in result if x in header]
     571            else:
     572                result = header
     573        return result
     574
     575    def PlotFiles(self, event):
     576        selected_x = self.cbXColHdr.GetStringSelection()
     577        selected_y = self.cbYColHdr.GetStringSelection()
     578
     579        if selected_x and selected_y:
     580            options = {}
     581            # set X and Y axis labels
     582            options[X_LABEL] = selected_x
     583            options[Y_LABEL] = selected_y
     584            options[SIZE] = '800,600'
     585            options[TITLE] = 'TITLE'
     586
     587            plot_files(self.CSVFiles, options)
     588           
    417589    def error(self, msg):
    418590        dlg = wx.MessageDialog(self, msg, 'Error',
Note: See TracChangeset for help on using the changeset viewer.