Esempio n. 1
0
def prepmap(ifiles, options):
    ifile = ifiles[0]
    ax = pl.gca()
    map = getmap(ifile, resolution = 'c')
    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)
    for si, shapefile in enumerate(options.shapefiles):
        shapename = os.path.basename(shapefile)[:-3] + str(si)
        map.readshapefile(shapefile, shapename, ax = ax, linewidth = pl.rcParams['lines.linewidth'])
    options.map = map
Esempio n. 2
0
def prepmap(ifiles, options):
    ifile = ifiles[0]
    ax = pl.gca()
    map = getmap(ifile, resolution='c')
    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)
    for si, shapefile in enumerate(options.shapefiles):
        shapename = os.path.basename(shapefile)[:-3] + str(si)
        map.readshapefile(shapefile,
                          shapename,
                          ax=ax,
                          linewidth=pl.rcParams['lines.linewidth'])
    options.map = map
Esempio n. 3
0
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
Esempio n. 4
0
def plot(ifiles, args):
    import matplotlib.pylab as pl
    import matplotlib.pyplot as plt
    from pylab import figure, NullFormatter, close, rcParams
    from PseudoNetCDF.coordutil import getsigmamid, getpresmid, getpresbnds, getsigmabnds
    rcParams['text.usetex'] = False
    from matplotlib.colors import LinearSegmentedColormap, BoundaryNorm, LogNorm, Normalize
    map = not args.nomap
    scale = args.scale
    minmax = eval(args.minmax)
    minmaxq = eval(args.minmaxq)
    sigma = args.sigma
    maskzeros = args.maskzeros
    try:
        f, = ifiles
    except:
        raise ValueError(
            'curtain plot expects one file when done. Try stack time --stack=time to concatenate'
        )

    if sigma:
        vertcrd = getsigmabnds(f)
    else:
        vertcrd = getpresbnds(f, pref=101325., ptop=getattr(f, 'VGTOP', 10000))
        if vertcrd.max() > 2000: vertcrd /= 100.

    reversevert = not (np.diff(vertcrd) > 0).all()
    for var_name in args.variables:
        temp = defaultdict(lambda: 1)
        try:
            eval(var_name, None, temp)
            var = eval(var_name, None, f.variables)[:]
        except:
            temp[var_name]
            var = f.variables[var_name][:]
        if args.itertime:
            vars = [('time%02d' % vi, v) for vi, v in enumerate(var)]
        else:
            if var.shape[0] != 1:
                parser.print_help()
                sys.stderr.write(
                    '\n*****\n\nFile must have only one time or use the itertime options; to reduce file to one time, see the --slice and --reduce operators\n\n'
                )
                exit()
            vars = [('', var[0])]

        for lstr, var in vars:
            bmap = None
            if maskzeros: var = np.ma.masked_values(var, 0)
            vmin, vmax = np.percentile(
                np.ma.compressed(var).ravel(), list(minmaxq))
            if minmax[0] is not None:
                vmin = minmax[0]
            if minmax[1] is not None:
                vmax = minmax[1]

            if not args.normalize is None:
                norm = eval(args.normalize)
                if norm.scaled():
                    vmin = norm.vmin
                    vmax = norm.vmax
            else:
                if scale == 'log':
                    bins = np.logspace(np.log10(vmin), np.log10(vmax), 11)
                elif scale == 'linear':
                    bins = np.linspace(vmin, vmax, 11)
                elif scale == 'deciles':
                    bins = np.percentile(
                        np.ma.compressed(
                            np.ma.masked_greater(
                                np.ma.masked_less(var, vmin).view(
                                    np.ma.MaskedArray), vmax)).ravel(),
                        [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100])
                    bins[0] = vmin
                    bins[-1] = vmax
                norm = BoundaryNorm(bins, ncolors=256)

            if map:
                fig = pl.figure(figsize=(8, 8))
                fig.subplots_adjust(hspace=.3, wspace=.3)
                axmap = fig.add_subplot(3, 3, 5)
                try:
                    cmaqmap = getmap(f, resolution=args.resolution)
                    cmaqmap.drawcoastlines(ax=axmap)
                    cmaqmap.drawcountries(ax=axmap)
                    if not args.states: cmaqmap.drawstates(ax=axmap)
                    if args.counties: cmaqmap.drawcounties(ax=axmap)
                    cmaqmap.drawparallels(np.arange(-90, 100, 10),
                                          labels=[True, True, False, False],
                                          ax=axmap)
                    cmaqmap.drawmeridians(np.arange(-180, 190, 20),
                                          labels=[False, False, True, True],
                                          ax=axmap)
                except Exception as e:
                    warn('An error occurred and no map will be shown:\n%s' %
                         str(e))
                axn = fig.add_subplot(3, 3, 2, sharex=axmap)
                axw = fig.add_subplot(3, 3, 4, sharey=axmap)
                axe = fig.add_subplot(3, 3, 6, sharey=axmap)
                axs = fig.add_subplot(3, 3, 8, sharex=axmap)
                cax = fig.add_axes([.8, .7, .05, .25])
                for ax in [axmap, axe]:
                    ax.yaxis.set_major_formatter(NullFormatter())
                for ax in [axmap, axn]:
                    ax.xaxis.set_major_formatter(NullFormatter())
                for ax in [axn, axs]:
                    if sigma:
                        ax.set_ylabel('sigma')
                    else:
                        ax.set_ylabel('pressure')
                for ax in [axe, axw]:
                    if sigma:
                        ax.set_xlabel('sigma')
                    else:
                        ax.set_xlabel('pressure')
                xyfactor = 1
            else:
                fig = pl.figure(figsize=(16, 4))
                fig.subplots_adjust(bottom=0.15)
                axw = fig.add_subplot(1, 4, 1)
                axn = fig.add_subplot(1, 4, 2)
                axe = fig.add_subplot(1, 4, 3)
                axs = fig.add_subplot(1, 4, 4)
                cax = fig.add_axes([.91, .1, .025, .8])
                if sigma:
                    axw.set_ylabel('sigma')
                else:
                    axw.set_ylabel('pressure')

                xyfactor = 1e-3  # m -> km

            x = f.NCOLS + 1
            y = f.NROWS + 1
            start_south = 0
            end_south = start_south + x
            start_east = end_south
            end_east = start_east + y
            start_north = end_east
            end_north = start_north + x
            start_west = end_north
            end_west = start_west + y
            X, Y = np.meshgrid(np.arange(x + 1) * f.XCELL * xyfactor, vertcrd)
            patchess = axs.pcolor(X,
                                  Y,
                                  var[:, start_south:end_south],
                                  cmap=bmap,
                                  vmin=vmin,
                                  vmax=vmax,
                                  norm=norm)
            if not map:
                if reversevert: axs.set_ylim(*axs.get_ylim()[::-1])
                axs.set_title('South')
                axs.set_xlabel('E to W km')
                axs.set_xlim(*axs.get_xlim()[::-1])
            else:
                if not reversevert: axs.set_ylim(*axs.get_ylim()[::-1])

            X, Y = np.meshgrid(np.arange(-1, x) * f.XCELL * xyfactor, vertcrd)
            patchesn = axn.pcolor(X,
                                  Y,
                                  var[:, start_north:end_north],
                                  cmap=bmap,
                                  vmin=vmin,
                                  vmax=vmax,
                                  norm=norm)
            if reversevert: axn.set_ylim(*axn.get_ylim()[::-1])
            if not map:
                axn.set_title('North')
                axn.set_xlabel('W to E km')

            if map:
                X, Y = np.meshgrid(vertcrd, np.arange(y + 1) * f.YCELL)
                patchese = axe.pcolor(X,
                                      Y,
                                      var[:,
                                          start_east:end_east].swapaxes(0, 1),
                                      cmap=bmap,
                                      vmin=vmin,
                                      vmax=vmax,
                                      norm=norm)
                if reversevert: axe.set_xlim(*axe.get_xlim()[::-1])
            else:
                X, Y = np.meshgrid(
                    np.arange(y + 1) * f.YCELL * xyfactor, vertcrd)
                patchese = axe.pcolor(X,
                                      Y,
                                      var[:, start_east:end_east],
                                      cmap=bmap,
                                      vmin=vmin,
                                      vmax=vmax,
                                      norm=norm)
                if reversevert: axe.set_ylim(*axe.get_ylim()[::-1])
                axe.set_title('East')
                axe.set_xlabel('N to S km')
                axe.set_xlim(*axe.get_xlim()[::-1])
            if map:
                X, Y = np.meshgrid(vertcrd, np.arange(-1, y) * f.YCELL)
                patchesw = axw.pcolor(X,
                                      Y,
                                      var[:,
                                          start_west:end_west].swapaxes(0, 1),
                                      cmap=bmap,
                                      vmin=vmin,
                                      vmax=vmax,
                                      norm=norm)
                if not reversevert: axw.set_xlim(*axw.get_xlim()[::-1])
            else:
                X, Y = np.meshgrid(
                    np.arange(-1, y) * f.YCELL * xyfactor, vertcrd)
                patchesw = axw.pcolor(X,
                                      Y,
                                      var[:, start_west:end_west],
                                      cmap=bmap,
                                      vmin=vmin,
                                      vmax=vmax,
                                      norm=norm)
                if reversevert: axw.set_ylim(*axw.get_ylim()[::-1])
                axw.set_title('West')
                axw.set_xlabel('S to N km')
            if map:
                for ax in [axe, axw]:
                    ax.axis('tight', axis='x')
                    pl.setp(ax.xaxis.get_majorticklabels(), rotation=90)
                for ax in [axs, axn]:
                    ax.axis('tight', axis='y')
            else:
                for ax in [axe, axn, axw, axs] + ([axmap] if map else []):
                    ax.axis('tight')

            if 'TFLAG' in f.variables.keys():
                SDATE = f.variables['TFLAG'][:][0, 0, 0]
                EDATE = f.variables['TFLAG'][:][-1, 0, 0]
                STIME = f.variables['TFLAG'][:][0, 0, 1]
                ETIME = f.variables['TFLAG'][:][-1, 0, 1]
                if SDATE == 0:
                    SDATE = 1900001
                    EDATE = 1900001
                sdate = datetime.strptime('%07d %06d' % (SDATE, STIME),
                                          '%Y%j %H%M%S')
                edate = datetime.strptime('%07d %06d' % (EDATE, ETIME),
                                          '%Y%j %H%M%S')
            elif 'tau0' in f.variables.keys():
                sdate = datetime(1985, 1, 1,
                                 0) + timedelta(hours=f.variables['tau0'][0])
                edate = datetime(1985, 1, 1,
                                 0) + timedelta(hours=f.variables['tau1'][-1])
            else:
                sdate = datetime(1900, 1, 1, 0)
                edate = datetime(1900, 1, 1, 0)
            try:
                title = '%s %s to %s' % (var_name, sdate.strftime('%Y-%m-%d'),
                                         edate.strftime('%Y-%m-%d'))
            except:
                title = var_name
            fig.suptitle(title.replace('O3', 'Ozone at Regional Boundaries'))
            if var.min() < vmin and var.max() > vmax:
                extend = 'both'
            elif var.min() < vmin:
                extend = 'min'
            elif var.max() > vmax:
                extend = 'max'
            else:
                extend = 'neither'
            fig.colorbar(patchesw, cax=cax, extend=extend)
            cax.set_xlabel('ppm')
            figpath = args.outpath + var_name + lstr + '.' + args.figformat
            fig.savefig(figpath)
            if args.verbose > 0: print('Saved fig', figpath)
            pl.close(fig)
Esempio n. 5
0
def plot(ifiles, args):
    import pylab as pl
    from pylab import figure, NullFormatter, close, rcParams
    from PseudoNetCDF.coordutil import getsigmamid, getpresmid, getpresbnds, getsigmabnds

    rcParams["text.usetex"] = False
    from matplotlib.colors import LinearSegmentedColormap, BoundaryNorm, LogNorm

    map = not args.nomap
    scale = args.scale
    minmax = eval(args.minmax)
    minmaxq = eval(args.minmaxq)
    sigma = args.sigma
    maskzeros = args.maskzeros
    try:
        f, = ifiles
    except:
        raise ValueError("curtain plot expects one file when done. Try stack time --stack=time to concatenate")

    if sigma:
        vertcrd = getsigmabnds(f)
    else:
        vertcrd = getpresbnds(f, pref=101325.0, ptop=getattr(f, "VGTOP", 10000))
        if vertcrd.max() > 2000:
            vertcrd /= 100.0

    reversevert = not (np.diff(vertcrd) > 0).all()
    for var_name in args.variables:
        temp = defaultdict(lambda: 1)
        try:
            eval(var_name, None, temp)
            var = eval(var_name, None, f.variables)[:]
        except:
            temp[var_name]
            var = f.variables[var_name][:]
        if args.itertime:
            vars = [("time%02d" % vi, v) for vi, v in enumerate(var)]
        else:
            if var.shape[0] != 1:
                parser.print_help()
                sys.stderr.write(
                    "\n*****\n\nFile must have only one time or use the itertime options; to reduce file to one time, see the --slice and --reduce operators\n\n"
                )
                exit()
            vars = [("", var[0])]

        for lstr, var in vars:
            bmap = None
            if maskzeros:
                var = np.ma.masked_values(var, 0)
            vmin, vmax = np.percentile(np.ma.compressed(var).ravel(), list(minmaxq))
            if minmax[0] is not None:
                vmin = minmax[0]
            if minmax[1] is not None:
                vmax = minmax[1]

            if not args.normalize is None:
                norm = eval(args.normalize)
                if norm.scaled():
                    vmin = norm.vmin
                    vmax = norm.vmax
            else:
                if scale == "log":
                    bins = np.logspace(np.log10(vmin), np.log10(vmax), 11)
                elif scale == "linear":
                    bins = np.linspace(vmin, vmax, 11)
                elif scale == "deciles":
                    bins = np.percentile(
                        np.ma.compressed(np.ma.masked_greater(np.ma.masked_less(var, vmin), vmax)).ravel(),
                        [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100],
                    )
                    bins[0] = vmin
                    bins[-1] = vmax
                norm = BoundaryNorm(bins, ncolors=256)

            if map:
                fig = pl.figure(figsize=(8, 8))
                fig.subplots_adjust(hspace=0.3, wspace=0.3)
                axmap = fig.add_subplot(3, 3, 5)
                try:
                    cmaqmap = getmap(f)
                    cmaqmap.drawcoastlines(ax=axmap)
                    cmaqmap.drawcountries(ax=axmap)
                    if args.states:
                        cmaqmap.drawstates(ax=axmap)
                    if args.counties:
                        cmaqmap.drawcounties(ax=axmap)
                    cmaqmap.drawparallels(np.arange(-90, 100, 10), labels=[True, True, False, False], ax=axmap)
                    cmaqmap.drawmeridians(np.arange(-180, 190, 20), labels=[False, False, True, True], ax=axmap)
                except Exception as e:
                    warn("An error occurred and no map will be shown:\n%s" % str(e))
                axn = fig.add_subplot(3, 3, 2, sharex=axmap)
                axw = fig.add_subplot(3, 3, 4, sharey=axmap)
                axe = fig.add_subplot(3, 3, 6, sharey=axmap)
                axs = fig.add_subplot(3, 3, 8, sharex=axmap)
                cax = fig.add_axes([0.8, 0.7, 0.05, 0.25])
                for ax in [axmap, axe]:
                    ax.yaxis.set_major_formatter(NullFormatter())
                for ax in [axmap, axn]:
                    ax.xaxis.set_major_formatter(NullFormatter())
                for ax in [axn, axs]:
                    if sigma:
                        ax.set_ylabel("sigma")
                    else:
                        ax.set_ylabel("pressure")
                for ax in [axe, axw]:
                    if sigma:
                        ax.set_xlabel("sigma")
                    else:
                        ax.set_xlabel("pressure")
                xyfactor = 1
            else:
                fig = pl.figure(figsize=(16, 4))
                fig.subplots_adjust(bottom=0.15)
                axw = fig.add_subplot(1, 4, 1)
                axn = fig.add_subplot(1, 4, 2)
                axe = fig.add_subplot(1, 4, 3)
                axs = fig.add_subplot(1, 4, 4)
                cax = fig.add_axes([0.91, 0.1, 0.025, 0.8])
                if sigma:
                    axw.set_ylabel("sigma")
                else:
                    axw.set_ylabel("pressure")

                xyfactor = 1e-3  # m -> km

            x = f.NCOLS + 1
            y = f.NROWS + 1
            start_south = 0
            end_south = start_south + x
            start_east = end_south
            end_east = start_east + y
            start_north = end_east
            end_north = start_north + x
            start_west = end_north
            end_west = start_west + y
            X, Y = np.meshgrid(np.arange(x + 1) * f.XCELL * xyfactor, vertcrd)
            patchess = axs.pcolor(X, Y, var[:, start_south:end_south], cmap=bmap, vmin=vmin, vmax=vmax, norm=norm)
            if not map:
                if reversevert:
                    axs.set_ylim(*axs.get_ylim()[::-1])
                axs.set_title("South")
                axs.set_xlabel("E to W km")
                axs.set_xlim(*axs.get_xlim()[::-1])

            X, Y = np.meshgrid(np.arange(-1, x) * f.XCELL * xyfactor, vertcrd)
            patchesn = axn.pcolor(X, Y, var[:, start_north:end_north], cmap=bmap, vmin=vmin, vmax=vmax, norm=norm)
            if reversevert:
                axn.set_ylim(*axn.get_ylim()[::-1])
            if not map:
                axn.set_title("North")
                axn.set_xlabel("W to E km")

            if map:
                X, Y = np.meshgrid(vertcrd, np.arange(y + 1) * f.YCELL)
                patchese = axe.pcolor(
                    X, Y, var[:, start_east:end_east].swapaxes(0, 1), cmap=bmap, vmin=vmin, vmax=vmax, norm=norm
                )
                if reversevert:
                    axe.set_xlim(*axe.get_xlim()[::-1])
            else:
                X, Y = np.meshgrid(np.arange(y + 1) * f.YCELL * xyfactor, vertcrd)
                patchese = axe.pcolor(X, Y, var[:, start_east:end_east], cmap=bmap, vmin=vmin, vmax=vmax, norm=norm)
                if reversevert:
                    axe.set_ylim(*axe.get_ylim()[::-1])
                axe.set_title("East")
                axe.set_xlabel("N to S km")
                axe.set_xlim(*axe.get_xlim()[::-1])
            if map:
                X, Y = np.meshgrid(vertcrd, np.arange(-1, y) * f.YCELL)
                patchesw = axw.pcolor(
                    X, Y, var[:, start_west:end_west].swapaxes(0, 1), cmap=bmap, vmin=vmin, vmax=vmax, norm=norm
                )
            else:
                X, Y = np.meshgrid(np.arange(-1, y) * f.YCELL * xyfactor, vertcrd)
                patchesw = axw.pcolor(X, Y, var[:, start_west:end_west], cmap=bmap, vmin=vmin, vmax=vmax, norm=norm)
                if reversevert:
                    axw.set_ylim(*axw.get_ylim()[::-1])
                axw.set_title("West")
                axw.set_xlabel("S to N km")
            if map:
                for ax in [axe, axw]:
                    ax.axis("tight", axis="x")
                    pl.setp(ax.xaxis.get_majorticklabels(), rotation=90)
                for ax in [axs, axn]:
                    ax.axis("tight", axis="y")
            else:
                for ax in [axe, axn, axw, axs] + ([axmap] if map else []):
                    ax.axis("tight")

            if "TFLAG" in f.variables.keys():
                SDATE = f.variables["TFLAG"][:][0, 0, 0]
                EDATE = f.variables["TFLAG"][:][-1, 0, 0]
                STIME = f.variables["TFLAG"][:][0, 0, 1]
                ETIME = f.variables["TFLAG"][:][-1, 0, 1]
                if SDATE == 0:
                    SDATE = 1900001
                    EDATE = 1900001
                sdate = datetime.strptime("%07d %06d" % (SDATE, STIME), "%Y%j %H%M%S")
                edate = datetime.strptime("%07d %06d" % (EDATE, ETIME), "%Y%j %H%M%S")
            elif "tau0" in f.variables.keys():
                sdate = datetime(1985, 1, 1, 0) + timedelta(hours=f.variables["tau0"][0])
                edate = datetime(1985, 1, 1, 0) + timedelta(hours=f.variables["tau1"][-1])
            else:
                sdate = datetime(1900, 1, 1, 0)
                edate = datetime(1900, 1, 1, 0)
            try:
                title = "%s %s to %s" % (var_name, sdate.strftime("%Y-%m-%d"), edate.strftime("%Y-%m-%d"))
            except:
                title = var_name
            fig.suptitle(title.replace("O3", "Ozone at Regional Boundaries"))
            if var.min() < vmin and var.max() > vmax:
                extend = "both"
            elif var.min() < vmin:
                extend = "min"
            elif var.max() > vmax:
                extend = "max"
            else:
                extend = "neither"
            fig.colorbar(patchesw, cax=cax, extend=extend)
            cax.set_xlabel("ppm")
            fig.savefig("%s_%s%s.%s" % (args.outpath, var_name, lstr, args.figformat))
            pl.close(fig)
Esempio n. 6
0
def makemaps(args):
    ifiles = args.ifiles
    cbar = None
    ifile = ifiles[0]
    if args.iter != []:
        ifile, = ifiles
        ifiles = []
        for dimk in args.iter:
            ifiles += [
                slice_dim(getvarpnc(ifile, None), '%s,%d' % (dimk, i))
                for i in range(len(ifile.dimensions[dimk]))
            ]
    ax = plt.gca()
    map = getmap(ifile, resolution=args.resolution)
    if args.coastlines:
        map.drawcoastlines(ax=ax)
    if args.countries:
        map.drawcountries(ax=ax)
    if args.states:
        map.drawstates(ax=ax)
    if args.counties:
        map.drawcounties(ax=ax)
    for si, shapefile in enumerate(args.shapefiles):
        shapeopts = shapefile.split(',')
        shapepath = shapeopts[0]
        shapeoptdict = eval('dict(' + ','.join(shapeopts[1:]) + ')')
        shapename = os.path.basename(shapepath)[:-3] + str(si)
        map.readshapefile(shapepath, shapename, ax=ax, **shapeoptdict)
    args.map = map
    fig = plt.gcf()
    if len(args.figure_keywords) > 0:
        plt.setp(fig, **args.figure_keywords)

    ax = plt.gca()
    if len(args.axes_keywords) > 0:
        plt.setp(ax, **args.axes_keywords)

    map = args.map
    nborders = len(ax.collections)
    for fi, ifile in enumerate(ifiles):
        if map.projection in ('lcc', 'merc'):
            lat = ifile.variables['latitude']
            lon = ifile.variables['longitude']
            latb, latunit = getybnds(ifile)[:]
            lonb, lonunit = getxbnds(ifile)[:]
        else:
            lat = ifile.variables['latitude']
            lon = ifile.variables['longitude']
            latb, latunit = getlatbnds(ifile)[:]
            lonb, lonunit = getlonbnds(ifile)[:]

        if latb.ndim == lonb.ndim and lonb.ndim == 2:
            LON, LAT = lonb, latb
        else:
            LON, LAT = np.meshgrid(lonb.view(np.ndarray),
                                   latb.view(np.ndarray))

        variables = args.variables
        if variables is None:

            def isgeo(var):
                geo2d = set(['latitude', 'longitude'])
                vard = getattr(var, 'coordinates', '').split()
                hasgeo2d = len(geo2d.intersection(vard)) == 2
                return hasgeo2d

            variables = [
                key for key, var in ifile.variables.items() if isgeo(var)
            ]
        if len(variables) == 0:
            raise ValueError('Unable to heuristically determin plottable ' +
                             'variables; use -v to specify variables for ' +
                             'plotting')
        for varkey in variables:
            ax = plt.gca()

            if not args.overlay:
                del ax.collections[nborders:]
            var = ifile.variables[varkey]
            if args.squeeze:
                vals = var[:].squeeze()
            else:
                vals = var[:]
            vmin, vmax = vals.min(), vals.max()
            if args.normalize is None:
                from scipy.stats import normaltest
                if normaltest(vals.ravel())[1] < 0.001:
                    cvals = np.ma.compressed(vals)
                    boundaries = np.percentile(cvals, np.arange(0, 110, 10))
                    warn('Autoselect deciles colormap of %s; override ' +
                         'width --norm' % varkey)
                else:
                    boundaries = np.linspace(vmin, vmax, num=11)
                    warn(('Autoselect linear colormap of %s; override ' +
                          'width --norm') % varkey)
                ordermag = (boundaries.max() /
                            np.ma.masked_values(boundaries, 0).min())
                if (ordermag) > 10000:
                    formatter = LogFormatter(labelOnlyBase=False)
                else:
                    formatter = None
                norm = BoundaryNorm(boundaries, ncolors=256)
            else:
                norm = eval(args.normalize)
                formatter = None
            if args.colorbarformatter is not None:
                try:
                    formatter = eval(args.colorbarformatter)
                except Exception:
                    formatter = args.colorbarformatter

            if norm.vmin is not None:
                vmin = norm.vmin
            if norm.vmax is not None:
                vmax = norm.vmax
            varunit = getattr(var, 'units', 'unknown').strip()
            if args.verbose > 0:
                print(varkey, sep='')
            if vals.ndim == 1:
                notmasked = ~(np.ma.getmaskarray(lon[:]) | np.ma.getmaskarray(
                    lat[:]) | np.ma.getmaskarray(vals[:]))
                scatlon = lon[:][notmasked]
                scatlat = lat[:][notmasked]
                scatvals = vals[:][notmasked]
                patches = map.scatter(scatlon[:],
                                      scatlat[:],
                                      c=scatvals,
                                      edgecolors='none',
                                      s=24,
                                      norm=norm,
                                      ax=ax,
                                      zorder=2)
            else:
                if vals.ndim != 2:
                    dimlendictstr = str(dict(zip(var.dimensions, var.shape)))
                    warn('Maps require 2-d data; values right now %s %s' %
                         (str(vals.shape), dimlendictstr))
                patches = map.pcolor(LON, LAT, vals, norm=norm, ax=ax)
            if lonunit == 'x (m)':
                ax.xaxis.get_major_formatter().set_scientific(True)
                ax.xaxis.get_major_formatter().set_powerlimits((-3, 3))
            if latunit == 'y (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 = np.abs(np.diff(ax.get_ylim()))
            width = np.abs(np.diff(ax.get_xlim()))
            if width >= height:
                orientation = 'horizontal'
            else:
                orientation = 'vertical'
            if cbar is None:
                cax = None
            else:
                cax = cbar.ax
                cax.cla()

            if vals.max() > vmax and vals.min() < vmin:
                extend = 'both'
            elif vals.max() > vmax:
                extend = 'max'
            elif vals.min() < vmin:
                extend = 'min'
            else:
                extend = 'neither'
            cbar = plt.gcf().colorbar(patches,
                                      orientation=orientation,
                                      cax=cax,
                                      extend=extend,
                                      format=formatter,
                                      spacing='proportional')
            del cbar.ax.texts[:]
            varminmaxtxt = ('; min=%.3g; max=%.3g)' %
                            (var[:].min(), var[:].max()))
            cbar.set_label(varkey + ' (' + varunit + varminmaxtxt)
            # if orientation == 'vertical':
            #     cbar.ax.text(.5, 1.05, '%.3g' % var[:].max(),
            #                  horizontalalignment = 'center',
            #                  verticalalignment = 'bottom')
            #     cbar.ax.text(.5, -.06, '%.3g ' % var[:].min(),
            #                  horizontalalignment = 'center',
            #                  verticalalignment = 'top')
            # else:
            #     cbar.ax.text(1.05, .5, ' %.3g' % var[:].max(),
            #                  verticalalignment = 'center',
            #                  horizontalalignment = 'left')
            #     cbar.ax.text(-.06, .5, '%.3g ' % var[:].min(),
            #                  verticalalignment = 'center',
            #                  horizontalalignment = 'right')
            cbar.update_ticks()
            fmt = args.figformat
            outpath = args.outpath
            if len(ifiles) > 1:
                lstr = str(fi).rjust(len(str(len(ifiles))), '0')
                if args.verbose > 0:
                    print('adding numeric suffix for file', lstr)
            else:
                lstr = ''

            figpath = os.path.join(outpath + varkey + lstr + '.' + fmt)
            if args.interactive:
                csl = PNCConsole(locals=globals())
                csl.interact()
            for cmd in args.plotcommands:
                exec(cmd)
            plt.savefig(figpath)
            if args.verbose > 0:
                print('Saved fig', figpath)