from __future__ import print_function

__all__ = ['mapplot', 'profile', 'tileplot',
           'presslon', 'presslat', 'timeseries', 'OptionDict']

from warnings import warn
import os

import numpy as np

import PseudoNetCDF.coordutil as cu


_pre_code = 'plt.close(); plt.rcParams["image.cmap"] = "jet"'
_before_code = 'plt.figure(); plt.interactive(True); '
_after_code = 'ax.set_title(varkey); plt.draw()'
_post_code = ''
_coastlines_opt = True
_countries_opt = True
_states_opt = True
_counties_opt = False
_coordkeys = ('time', 'latitude', 'longitude', 'latitude_bounds',
              'longitude_bounds', 'time_bounds', 'tau0', 'tau1',
              'TFLAG')


class OptionDict(dict):
    def __init__(self, *args, **kwds):
        """
        coastlines = %(_coastlines_opt)s
        countries = %(_countries_opt)s
        states = %(_states_opt)s
        counties = %(_counties_opt)s
        pre_txt = Code to run before any plots (%(_pre_code)s)
        before_txt = Code to run before each variable-plot (%(_before_code)s)
        after_txt = Code to run after each plot (%(_after_code)s)
        post_txt = Code to run after all plots (%(_post_code)s)
        """ % globals()
        dict.__init__(self, coastlines=_coastlines_opt,
                      countries=_countries_opt, states=_states_opt,
                      counties=_counties_opt, pre_txt=_pre_code,
                      before_txt=_before_code, after_txt=_after_code,
                      post_txt=_post_code)
        dict.__init__(self, *args, **kwds)
        if 'outpath' not in self:
            raise KeyError('outpath is a required option')

    def __getattr__(self, key):
        return self.get(key, False)


defaultoption = OptionDict(outpath='pncview')


class TkApp:
    def __init__(self, ncffile, options):
        try:
            from Tkinter import Checkbutton, Frame, Label, Scrollbar
            from Tkinter import Listbox, Button, IntVar, Tk, VERTICAL
            from Tkinter import EXTENDED, END, N, S, SINGLE, Entry
            from Tkinter import StringVar, Text, DISABLED, LEFT
        except Exception:
            try:
                from tkinter import Checkbutton, Frame, Label, Scrollbar
                from tkinter import Listbox, Button, IntVar, Tk, VERTICAL
                from tkinter import EXTENDED, END, N, S, SINGLE, Entry
                from tkinter import StringVar, Text, DISABLED, LEFT
            except Exception:
                warn('tkinter unavailable')

        master = self.root = Tk()
        self.ncffile = ncffile
        self.options = options
        self.plotted_variables = set()
        frame = Frame(master)
        frame.grid(row=0)
        codeframe = Frame(master)
        codeframe.grid(row=1)
        metaframe = Frame(master)
        metaframe.grid(row=2)
        goframe = Frame(frame)
        goframe.grid(column=3, row=1)

        var_label = Label(frame, text='Select Variable')
        var_label.grid(column=0, row=0)
        var_scrollbar = Scrollbar(frame, orient=VERTICAL)
        var_scrollbar.grid(column=1, row=1, sticky=N + S)
        self.var = Listbox(frame, selectmode=EXTENDED,
                           exportselection=0,
                           yscrollcommand=var_scrollbar.set)
        self.var.grid(column=0, row=1)
        var_scrollbar.config(command=self.var.yview)

        what_to_do = Label(frame, text='Execute')
        what_to_do.grid(column=2, row=0)
        self.method_list = Listbox(frame, selectmode=SINGLE, exportselection=0)
        self.method_list.grid(column=2, row=1)
        self.pre_txt = StringVar()
        pre_label = Label(codeframe, text='Before any figures, execute code')
        self.pre_txt.set(_pre_code)
        pre_label.grid(row=2, sticky='W')
        self.pre = Entry(codeframe, width=120, textvariable=self.pre_txt)
        self.pre.grid(row=3, sticky='E')

        self.before_txt = StringVar()
        self.before_txt.set(_before_code)
        before_label = Label(
            codeframe, text='Before each figure, execute code')
        before_label.grid(row=4, sticky='W')
        self.before = Entry(codeframe, width=120, textvariable=self.before_txt)
        self.before.grid(row=5, sticky='E')

        self.after_txt = StringVar()
        self.after_txt.set(_after_code)
        after_label = Label(codeframe, text='After each figure, execute code')
        after_label.grid(row=6, sticky='W')
        self.after = Entry(codeframe, width=120, textvariable=self.after_txt)
        self.after.grid(row=7, sticky='E')

        self.post_txt = StringVar()
        self.post_txt.set(_post_code)
        post_label = Label(codeframe, text='After all figures, execute code')
        post_label.grid(row=8, sticky='W')
        self.post = Entry(codeframe, width=120, textvariable=self.post_txt)
        self.post.grid(row=9, sticky='E')

        options_label = Label(goframe, text='Options:')
        options_label.grid(column=0, row=1, sticky='W')
        self.logscale = IntVar()
        self.logscale.set(0)
        c = Checkbutton(goframe, text="log-scale?", variable=self.logscale)
        c.grid(column=0, row=2, sticky='W')

        self.coastlines = IntVar()
        self.coastlines.set(_coastlines_opt)
        coastlines = Checkbutton(
            goframe, text="coastlines?", variable=self.coastlines,
            justify=LEFT)
        coastlines.grid(column=0, row=3, sticky='W')

        self.countries = IntVar()
        self.countries.set(_countries_opt)
        countries = Checkbutton(
            goframe, text="countries?", variable=self.countries, justify=LEFT)
        countries.grid(column=0, row=4, sticky='W')

        self.states = IntVar()
        self.states.set(_states_opt)
        states = Checkbutton(goframe, text="states?",
                             variable=self.states, justify=LEFT)
        states.grid(column=0, row=5, sticky='W')

        self.counties = IntVar()
        self.counties.set(_counties_opt)
        counties = Checkbutton(goframe, text="counties?",
                               variable=self.counties, justify=LEFT)
        counties.grid(column=0, row=6, sticky='W')

        self.execute_button = Button(
            goframe, text="Make Figure", command=self.execute)
        self.execute_button.grid(row=0, column=0, sticky='W')

        self.methods = ['mapplot', 'presslat', 'presslon', 'time-lat',
                        'profile', 'timeseries', 'pressx', 'tileplot', 'plot']
        method_labels = ['lat-lon', 'press-lat', 'press-lon', 'time-lat',
                         'Vertical Profile', 'Time Series', 'press-? (2-D)',
                         'Tile Plot (2-D)', 'Plot (1-D)']
        for method in method_labels:
            self.method_list.insert(END, method)
        var_keys = [k for k, v in self.ncffile.variables.items()
                    if k not in _coordkeys]
        var_keys.sort()
        self.vars = []
        for spc in var_keys:
            self.var.insert(END, spc)
            self.vars.append(spc)

        meta_label = Label(metaframe, text='Common Data Language Header:')
        meta_label.grid(column=0, row=0, sticky='W')
        meta_scrollbar = Scrollbar(metaframe, orient=VERTICAL)
        meta_scrollbar.grid(column=1, row=1, sticky=N + S)
        self.meta = Text(metaframe, height=10, width=118, bg='white',
                         relief='flat', yscrollcommand=meta_scrollbar.set)
        self.meta.grid(column=0, row=1, sticky='W')
        from PseudoNetCDF.pncdump import pncdump
        try:
            from StringIO import StringIO
        except ImportError:
            from io import StringIO
        pdump = StringIO("")
        pncdump(self.ncffile, header=True, outfile=pdump, )
        pdump.seek(0, 0)
        self.meta.insert(END, pdump.read())
        self.meta.config(state=DISABLED)
        help = Button(goframe, text='Help', command=self.help)
        help.grid(column=0, row=7)
        quit = Button(goframe, text='Quit', command=self.quit)
        quit.grid(column=0, row=8)
        master.mainloop()

    def help(self):
        print("pl is pylab: details at matplotlib;")

    def quit(self):
        self.root.destroy()

    def _get_var(self, list):
        items = list.curselection()
        try:
            items = map(int, items)
        except Exception:
            pass
        items = [self.vars[i] for i in items]
        return items

    def get_var(self):
        return self._get_var(self.var)

    def get_methods(self):
        items = self.method_list.curselection()
        try:
            items = map(int, items)
        except Exception:
            pass
        items = [self.methods[i] for i in items]
        return items

    def execute(self):
        os.system('clear')
        vars = self.get_var()
        self.plotted_variables = self.plotted_variables.union(vars)
        methods, = self.get_methods()
        self.options.logscale = bool(self.logscale.get())
        self.options.coastlines = bool(self.coastlines.get())
        self.options.countries = bool(self.countries.get())
        self.options.states = bool(self.states.get())
        self.options.counties = bool(self.counties.get())
        self.options.pre_txt = self.pre_txt.get()
        self.options.before_txt = self.before_txt.get()
        self.options.after_txt = self.after_txt.get()
        self.options.post_txt = self.post_txt.get()
        plotwithopts(self.ncffile, methods, vars, self.options)


def plotwithopts(ifile, method, vars, options=defaultoption):
    from PseudoNetCDF.sci_var import getvarpnc
    from PseudoNetCDF.pncgen import pncgen
    import matplotlib.pyplot as plt

    # dummy assignment so that flake8 sees plt as used
    # plt is loaded into the environment for exec
    varkey = plt

    exec(options.pre_txt)
    for varkey in vars:
        figpath = eval(method)(ifile=ifile, varkey=varkey, options=options,
                               before=options.before_txt,
                               after=options.after_txt)
        pncgen(getvarpnc(ifile, list(vars) + list(_coordkeys)),
               figpath + '.nc', verbose=0)
    exec(options.post_txt)


def StartTk(ncffile, options):
    TkApp(ncffile, options)


def pncview(ifile, options):
    # add a gui for plotting
    return StartTk(ifile, options)


def gettime(ifile):
    from PseudoNetCDF import PseudoNetCDFVariable
    from datetime import datetime, timedelta
    if 'time' in ifile.variables:
        time = ifile.variables['time']
        unit = time.units
        tunit, datestr = unit.split(' since ')
        sdate = datetime.strptime(datestr.replace(
            ' UTC', ''), '%Y-%m-%d %H:%M:%S')
        time = np.array([sdate + timedelta(**{tunit: t}) for t in time[:]])
        unit = 'time'
    elif 'TFLAG' in ifile.variables:
        x = ifile.variables['TFLAG'][:].copy()
        for axi in range(1, x.ndim - 1):
            x = x[:, 0]
        time = np.array(
            [(datetime.strptime('%07d %06d' % (d, t), '%Y%j %H%M%S'))
             for d, t in x])
        unit = 'time'
    elif 'time' in ifile.dimensions:
        time = np.arange(len(ifile.dimensions['time']))
        unit = 'steps'
    elif 'TSTEP' in ifile.dimensions:
        time = np.arange(1, len(ifile.dimensions['TSTEP']) + 1)
        unit = 'steps'
    else:
        raise KeyError('No time found')
    return PseudoNetCDFVariable(None, 'time', 'f', ('time',),
                                values=time[:], units=unit)


def timeseries(ifile, varkey, options, before='', after=''):
    import pylab as pl
    outpath = getattr(options, 'outpath', '.')
    time = gettime(ifile)
    var = ifile.variables[varkey]
    dims = [(k, l) for l, k in zip(var[:].shape, var.dimensions) if l > 1]
    if len(dims) > 1:
        raise ValueError(
            'Time series can have 1 non-unity dimensions; got %d - %s' %
            (len(dims), str(dims)))
    exec(before)
    ax = pl.gca()
    print(varkey, end='')
    if options.logscale:
        ax.set_yscale('log')

    ax.plot_date(time[:].squeeze(), var[:].squeeze())
    ax.set_xlabel(time.units.strip())
    ax.set_ylabel(getattr(var, 'standard_name',
                          varkey).strip() + ' ' + var.units.strip())
    fmt = 'png'
    figpath = os.path.join(outpath + '_ts_' + varkey + '.' + fmt)
    exec(after)
    pl.savefig(figpath)
    print('Saved fig', figpath)
    return figpath


def plot(ifile, varkey, options, before='', after=''):
    import pylab as pl
    outpath = getattr(options, 'outpath', '.')
    var = ifile.variables[varkey]
    dims = [(k, l) for l, k in zip(var[:].shape, var.dimensions) if l > 1]
    if len(dims) > 1:
        raise ValueError(
            'Plots can have only 1 non-unity dimensions; got %d - %s' %
            (len(dims), str(dims)))
    exec(before)
    ax = pl.gca()
    print(varkey, end='')
    if options.logscale:
        ax.set_yscale('log')

    ax.plot(var[:].squeeze())
    ax.set_xlabel('unknown')
    ax.set_ylabel(getattr(var, 'standard_name',
                          varkey).strip() + ' ' + var.units.strip())
    fmt = 'png'
    figpath = os.path.join(outpath + '_1d_' + varkey + '.' + fmt)
    exec(after)
    pl.savefig(figpath)
    print('Saved fig', figpath)
    return figpath


def pressx(ifile, varkey, options, before='', after=''):
    import matplotlib.pyplot as plt
    from matplotlib.colors import Normalize, LogNorm
    outpath = getattr(options, 'outpath', '.')
    vert = cu.getpresbnds(ifile)
    var = ifile.variables[varkey]
    dims = [(k, l) for l, k in zip(var[:].shape, var.dimensions) if l > 1]
    if len(dims) > 2:
        raise ValueError(
            'Press-x can have 2 non-unity dimensions; got %d - %s' %
            (len(dims), str(dims)))
    if options.logscale:
        norm = LogNorm()
    else:
        norm = Normalize()
    exec(before)
    ax = plt.gca()
    print(varkey, end='')
    vals = var[:].squeeze()
    x = np.arange(vals.shape[1])
    patches = ax.pcolor(x, vert, vals, norm=norm)
    # ax.set_xlabel(X.units.strip())
    # ax.set_ylabel(Y.units.strip())
    plt.colorbar(patches)
    ax.set_ylim(vert.max(), vert.min())
    ax.set_xlim(x.min(), x.max())
    fmt = 'png'
    figpath = os.path.join(outpath + '_PRESX_' + varkey + '.' + fmt)
    exec(after)
    plt.savefig(figpath)
    print('Saved fig', figpath)
    return figpath


def presslat(ifile, varkey, options, before='', after=''):
    import matplotlib.pyplot as plt
    from matplotlib.colors import Normalize, LogNorm
    outpath = getattr(options, 'outpath', '.')
    vert = cu.getpresbnds(ifile)
    lat, latunit = cu.getlatbnds(ifile)
    lat = np.append(lat.squeeze()[..., :2].mean(
        1), lat.squeeze()[-1, 2:].mean(0))
    var = ifile.variables[varkey]
    dims = [(k, l) for l, k in zip(var[:].shape, var.dimensions) if l > 1]
    if len(dims) > 2:
        raise ValueError(
            'Press-lat can have 2 non-unity dimensions; got %d - %s' %
            (len(dims), str(dims)))
    if options.logscale:
        norm = LogNorm()
    else:
        norm = Normalize()
    exec(before)
    ax = plt.gca()
    print(varkey, end='')
    patches = ax.pcolor(lat, vert, var[:].squeeze(), norm=norm)
    # ax.set_xlabel(X.units.strip())
    # ax.set_ylabel(Y.units.strip())
    cbar = plt.colorbar(patches)
    vunit = getattr(var, 'units', 'unknown').strip()
    cbar.set_label(varkey + ' (' + vunit + ')')
    cbar.ax.text(.5, 1, '%.2g' % var[:].max(
    ), horizontalalignment='center', verticalalignment='bottom')
    cbar.ax.text(.5, 0, '%.2g' % var[:].min(
    ), horizontalalignment='center', verticalalignment='top')
    ax.set_ylim(vert.max(), vert.min())
    ax.set_xlim(lat.min(), lat.max())
    fmt = 'png'
    figpath = os.path.join(outpath + '_PRESSLAT_' + varkey + '.' + fmt)
    exec(after)
    plt.savefig(figpath)
    print('Saved fig', figpath)
    return figpath


def presslon(ifile, varkey, options, before='', after=''):
    import matplotlib.pyplot as plt
    from matplotlib.colors import Normalize, LogNorm
    outpath = getattr(options, 'outpath', '.')
    vert = cu.getpresbnds(ifile)
    lon, lonunit = cu.getlonbnds(ifile)
    lon = np.append(lon.squeeze()[..., [0, 3]].mean(
        1), lon.squeeze()[-1, [1, 2]].mean(0))
    var = ifile.variables[varkey]
    dims = [(k, l) for l, k in zip(var[:].shape, var.dimensions) if l > 1]
    if len(dims) > 2:
        raise ValueError(
            'Press-lon plots can have 2 non-unity dimensions; got %d - %s' %
            (len(dims), str(dims)))
    if options.logscale:
        norm = LogNorm()
    else:
        norm = Normalize()
    exec(before)
    ax = plt.gca()
    print(varkey, end='')
    patches = ax.pcolor(lon, vert, var[:].squeeze(), norm=norm)
    # ax.set_xlabel(X.units.strip())
    # ax.set_ylabel(Y.units.strip())
    cbar = plt.colorbar(patches)
    vunit = getattr(var, 'units', 'unknown').strip()
    cbar.set_label(varkey + ' (' + vunit + ')')
    cbar.ax.text(.5, 1, '%.2g' % var[:].max(
    ), horizontalalignment='center', verticalalignment='bottom')
    cbar.ax.text(.5, 0, '%.2g' % var[:].min(
    ), horizontalalignment='center', verticalalignment='top')

    ax.set_ylim(vert.max(), vert.min())
    ax.set_xlim(lon.min(), lon.max())
    fmt = 'png'
    figpath = os.path.join(outpath + '_PRESLON_' + varkey + '.' + fmt)
    exec(after)
    plt.savefig(figpath)
    print('Saved fig', figpath)
    return figpath


def tileplot(ifile, varkey, options, before='', after=''):
    import matplotlib.pyplot as plt
    from matplotlib.colors import Normalize, LogNorm
    outpath = getattr(options, 'outpath', '.')
    var = ifile.variables[varkey]
    if options.logscale:
        norm = LogNorm()
    else:
        norm = Normalize()
    exec(before)
    ax = plt.gca()
    print(varkey, end='')
    dims = [(k, l) for l, k in zip(var[:].shape, var.dimensions) if l > 1]
    if len(dims) > 2:
        raise ValueError(
            'Tile plots can have 2 non-unity dimensions; got %d - %s' %
            (len(dims), str(dims)))
    patches = ax.pcolor(var[:].squeeze(), norm=norm)
    ax.set_xlim(0, var[:].squeeze().shape[1])
    ax.set_ylim(0, var[:].squeeze().shape[0])
    ax.set_xlabel(dims[1][0])
    ax.set_ylabel(dims[0][0])
    # ax.set_xlabel(X.units.strip())
    # ax.set_ylabel(Y.units.strip())
    cbar = plt.colorbar(patches)
    vunit = getattr(var, 'units', 'unknown').strip()
    cbar.set_label(varkey + ' (' + vunit + ')')
    cbar.ax.text(.5, 1, '%.2g' % var[:].max(
    ), horizontalalignment='center', verticalalignment='bottom')
    cbar.ax.text(.5, 0, '%.2g' % var[:].min(
    ), horizontalalignment='center', verticalalignment='top')
    fmt = 'png'
    figpath = os.path.join(outpath + '_2D_' + varkey + '.' + fmt)
    exec(after)
    plt.savefig(figpath)
    print('Saved fig', figpath)
    return figpath


def minmaxmean(ax, vals, vertcrd, **kwds):
    minval = vals.min(1)
    meanval = vals.mean(1)
    maxval = vals.max(1)
    kwds.setdefault('edgecolor', 'k')
    kwds.setdefault('facecolor', 'grey')
    kwds.setdefault('alpha', 1)
    kwds.setdefault('ls', 'solid')
    linekwds = kwds.copy()
    linekwds['color'] = linekwds.pop('edgecolor')
    linekwds.pop('facecolor')
    linekwds.pop('alpha')
    linekwds.pop('ls')
    fillkwds = kwds.copy()

    line, = ax.plot(meanval, vertcrd, **linekwds)

    x = np.ma.concatenate([minval[:vertcrd.size], maxval[:vertcrd.size][::-1]])
    y = np.ma.concatenate([vertcrd[:], vertcrd[::-1]])
    mask = x.mask | y.mask
    x = np.ma.masked_where(mask, x).compressed()
    y = np.ma.masked_where(mask, y).compressed()
    range, = ax.fill(x, y, **fillkwds)
    return line, range


def profile(ifile, varkey, options, before='', after=''):
    import matplotlib.pyplot as plt
    print(varkey, end='')
    outpath = getattr(options, 'outpath', '.')
    try:
        vert = cu.getpresmid(ifile)
        vunit = 'Pa'
    except Exception:
        vert = cu.getsigmamid(ifile)
        vunit = r'\sigma'
    var = ifile.variables[varkey]

    dims = list(var.dimensions)
    for knownvert in ['layer', 'LAY'] + ['layer%d' % i for i in range(72)]:
        if knownvert in dims:
            vidx = dims.index(knownvert)
            break
    else:
        raise KeyError("No known vertical coordinate; got %s" % str(dims))
    vert = vert[:var[:].shape[vidx]]
    units = var.units.strip()
    vals = np.rollaxis(var[:], vidx, start=0).view(
        np.ma.MaskedArray).reshape(vert.size, -1)
    ax = plt.gca()
    minmaxmean(ax, vals, vert)
    ax.set_xlabel(varkey + ' (' + units + ')')
    ax.set_ylabel(vunit)
    ax.set_ylim(vert.max(), vert.min())
    if options.logscale:
        ax.set_xscale('log')
    fmt = 'png'
    figpath = os.path.join(outpath + '_profile_' + varkey + '.' + fmt)
    exec(after)
    plt.savefig(figpath)
    print('Saved fig', figpath)
    return figpath


def mapplot(ifile, varkey, options, before='', after=''):
    """
    ifile - a pseudonetcdf file
    varkey - the variable to plot
    options - argparse name space with mapping options
    """
    import matplotlib.pyplot as plt
    from matplotlib.colors import Normalize, LogNorm
    outpath = getattr(options, 'outpath', '.')
    map = cu.getmap(ifile)
    if map.projection == 'cyl':
        latb, latunit = cu.getlatbnds(ifile)[:]
        lonb, lonunit = cu.getlonbnds(ifile)[:]
    else:
        latb, latunit = cu.getybnds(ifile)[:]
        lonb, lonunit = cu.getxbnds(ifile)[:]
    if latb.ndim == lonb.ndim and lonb.ndim == 2:
        LON, LAT = lonb, latb
    else:
        LON, LAT = np.meshgrid(lonb, latb)

    ax = plt.gca()
    if options.logscale:
        norm = LogNorm()
    else:
        norm = Normalize()
    var = ifile.variables[varkey]
    exec(before)
    ax = plt.gca()
    vunit = getattr(var, 'units', 'unknown').strip()
    print(varkey, end='')
    try:
        if options.coastlines:
            map.drawcoastlines(ax=ax)
        if options.countries:
            map.drawcountries(ax=ax)
        if options.states:
            map.drawstates(ax=ax)
        if options.counties:
            map.drawcounties(ax=ax)
    except Exception:
        print('nomap')
        pass
    patches = map.pcolor(LON, LAT, var[:].squeeze(), norm=norm, ax=ax)
    if lonunit == 'x (LCC m)':
        ax.xaxis.get_major_formatter().set_scientific(True)
        ax.xaxis.get_major_formatter().set_powerlimits((-3, 3))
    if latunit == 'y (LCC m)':
        ax.yaxis.get_major_formatter().set_scientific(True)
        ax.yaxis.get_major_formatter().set_powerlimits((-3, 3))
    ax.set_xlabel(lonunit)
    ax.set_ylabel(latunit)
    height = LAT.max() - LAT.min()
    width = LON.max() - LON.min()
    if width > height:
        orientation = 'horizontal'
    else:
        orientation = 'vertical'
    cbar = plt.gcf().colorbar(patches, orientation=orientation)
    cbar.set_label(varkey + ' (' + vunit + ')')
    if orientation == 'vertical':
        cbar.ax.text(.5, 1, '%.2g' % var[:].max(
        ), horizontalalignment='center', verticalalignment='bottom')
        cbar.ax.text(.5, 0, '%.2g' % var[:].min(
        ), horizontalalignment='center', verticalalignment='top')
    else:
        cbar.ax.text(1, .5, '%.2g' % var[:].max(
        ), verticalalignment='center', horizontalalignment='left')
        cbar.ax.text(0, .5, '%.2g' % var[:].min(
        ), verticalalignment='center', horizontalalignment='right')
    try:
        cbar.formatter.set_scientific(True)
        cbar.formatter.set_powerlimits((-3, 3))
    except Exception:
        pass
    cbar.update_ticks()
    fmt = 'png'
    figpath = os.path.join(outpath + '_map_' + varkey + '.' + fmt)
    exec(after)
    plt.savefig(figpath)
    print('Saved fig', figpath)
    return figpath


def main():
    import matplotlib.pyplot as plt
    from .pncparse import pncparse
    ifiles, options = pncparse(
        has_ofile=True, plot_options=True, interactive=False)
    if len(ifiles) != 1:
        raise IOError(
            'pncview can operate on only 1 file; user requested %d' %
            len(ifiles))
    ifile, = ifiles
    plt.interactive(True)
    for method_vars in options.plotcommands:
        pieces = method_vars.split(',')
        plotargs = [p for p in pieces if '=' not in p]
        plotkwds = [p for p in pieces if '=' in p]
        method, = plotargs[:1]
        vars = plotargs[1:]
        plotoptions = eval('OptionDict(outpath="%s",%s)' %
                           (options.outpath, ','.join(plotkwds)))
        print(plotoptions.logscale)
        plotwithopts(ifile, method, vars, plotoptions)
    plt.interactive(False)
    if len(options.plotcommands) == 0:
        pncview(ifile, options)


if __name__ == '__main__':
    main()
