示例#1
0
文件: gitm.py 项目: guodj/work
    def lon_lt_ticks(self, x, pos):
        '''
        Define ticks to include local time in addition to longitude.  Assumes
        that x is longitude in degrees.
        '''
        import math
        import gitm_plot_rout as gpr

        # Calculate the local time in hours
        lth = gpr.glon_to_localtime(self['time'], x)
        ltm = int((lth - math.floor(lth)) * 60.0)

        # Build the format string
        fmtstring = "{:g}$^\circ$\n {:02d}:{:02d}".format(x, int(lth), ltm)

        return (fmtstring)
示例#2
0
文件: gitm.py 项目: guodj/work
    def lon_lt_ticks(self, x, pos):
        '''
        Define ticks to include local time in addition to longitude.  Assumes
        that x is longitude in degrees.
        '''
        import math
        import gitm_plot_rout as gpr

        # Calculate the local time in hours
        lth = gpr.glon_to_localtime(self['time'], x)
        ltm = int((lth - math.floor(lth)) * 60.0)

        # Build the format string
        fmtstring = "{:g}$^\circ$\n {:02d}:{:02d}".format(x, int(lth), ltm)

        return(fmtstring)
def gitm_single_alt_image(plot_type,
                          zkey,
                          gData,
                          lat_index=-1,
                          lon_index=-1,
                          title=None,
                          figname=None,
                          draw=True,
                          xkey="dLat",
                          lon_lt=False,
                          hold_key=None,
                          geo_key=None,
                          hold_value=None,
                          color="b",
                          marker="o",
                          line=":",
                          zmax=None,
                          zmin=None,
                          amax=None,
                          amin=None,
                          xmax=None,
                          xmin=None,
                          zcenter=False,
                          add_hmf2=False,
                          hcolor="k",
                          hline="--",
                          add_fieldlines=False,
                          apex_alts=list(),
                          acolor="k",
                          aline="-",
                          *args,
                          **kwargs):
    '''
    Creates a rectangular or polar map projection plot for a specified latitude
    range.
    Input: plot_type  = key to determine plot type (linear, contour, scatter)
           zkey       = key for z variable (ie 'Vertical TEC')
           gData      = gitm bin structure
           lat_index  = index of constant latitude (default -1, none)
           lon_index  = index of constant longitude (default -1, none)
           title      = plot title
           figname    = file name to save figure as (default is none)
           xkey       = for contour plots specify an x key (default dLat)
                        (options dLat/dLon/Latitude/Longitude)
           lon_lt     = Add local time to the x axis (default=False).  Will
                        cause problems unless xkey is dLon.
           hold_key   = Key to coordinate in which desired location is specified
           geo_key    = Geographic coordinate corresponding to hold_key coord.
           hold_value = value of desired, specific coordinate location
           color      = linear color (default blue) for b&w contour, enter 'k'
           marker     = linear marker type (default circles)
           line       = linear line type (default dotted)
           zmax       = z key maximum (None to compute automatically, default)
           zmin       = z key minimum (None to compute automatically, default)
           amax       = a key maximum (None to compute automatically, default)
           amin       = a key minimum (None to compute automatically, default)
           xmax       = x key maximum for countour plots (or None to compute
                        automatically, default)
           xmin       = x key minimum for contour plots (or None to compute
                        automatically, default)
           zcenter    = Center z axis about zero? (default is False)
           add_hmf2   = Add line showing hmF2? (default=False)
           hcolor     = Line color for hmF2 line (default=black)
           hline      = Line style for hmF2 line (default=dashes)
           add_fieldlines = Add dipole field lines (default=False)
           apex_alts      = List of apex altitudes to plot field lines at
                            (default=list(), will pick a range of apex alts)
           acolor         = Line color for field lines (default="k")
           aline          = Line style for field lines (default="-")
    '''
    # Initialize the altitude and x variable limits
    if (amin == None or amax == None):
        tmin, tmax = gpr.find_data_limits([gData], "Altitude", lat_index,
                                          lon_index, -2, 30)
        if amin == None:
            amin = tmin
            amin = math.ceil(amin / 10000.0) * 10.0
        if amax == None:
            amax = tmax
            amax = math.floor(amax / 10000.0) * 10.0

    if (plot_type.find("linear") < 0 and (xmin == None or xmax == None)):
        if gData[xkey].attrs['scale'].find("exp") >= 0:
            raw = True
        else:
            raw = False

        tmin, tmax = gpr.find_data_limits([gData],
                                          xkey,
                                          lat_index,
                                          lon_index,
                                          -2,
                                          6,
                                          raw=raw)
        if xmin == None:
            xmin = tmin
        if xmax == None:
            xmax = tmax

    # Initialize the input data indices
    datadim = [gData.attrs['nAlt']]
    if lat_index >= 0:
        latmin = lat_index
        latmax = latmin + 1
    else:
        latmin = 0
        latmax = gData.attrs['nLat']
        datadim.insert(0, gData.attrs['nLat'])

    if lon_index >= 0:
        lonmin = lon_index
        lonmax = lonmin + 1
    else:
        lonmin = 0
        lonmax = gData.attrs['nLon']
        datadim.insert(0, gData.attrs['nLon'])

    # Initialize the data
    alt_data = np.array(gData['Altitude'][lonmin:lonmax, latmin:latmax, :])
    alt_data = alt_data.reshape(datadim)

    if plot_type.find("linear") >= 0:
        # Perform interpolation to plot data at a specific location instead of a
        # grid point
        if (gData.has_key(hold_key) and hold_value is not None):
            if geo_key.find("Lon") >= 0:
                lonmin = 0
                lonmax = gData.attrs['nLon']
            elif geo_key.find("Lat") >= 0:
                latmin = 0
                latmax = gData.attrs['nLat']
            i_data = gpr.create_linear_input_array(hold_key,
                                                   hold_value,
                                                   "Altitude", [zkey],
                                                   gData,
                                                   alt_data,
                                                   lonmin=lonmin,
                                                   lonmax=lonmax,
                                                   latmin=latmin,
                                                   latmax=latmax,
                                                   altmax=gData.attrs['nAlt'])
            x_data = np.array(i_data[zkey])
            if zmin == None:
                xmin = np.nanmin(x_data)
            if zmax == None:
                xmax = np.nanmax(x_data)
        else:
            if (zmin == None or zmax == None):
                if gData[zkey].attrs['scale'].find("exp") >= 0:
                    raw = True
                else:
                    raw = False
                tmin, tmax = gpr.find_data_limits([gData],
                                                  zkey,
                                                  lat_index,
                                                  lon_index,
                                                  -2,
                                                  6,
                                                  raw=raw)
                if zmin == None:
                    xmin = tmin
                if zmax == None:
                    xmax = tmax
            x_data = np.array(gData[zkey][lonmin:lonmax, latmin:latmax, :])
            x_data = x_data.reshape(datadim)
        x_name = gData[zkey].attrs['name']
        x_scale = gData[zkey].attrs['scale']
        x_units = gData[zkey].attrs['units']
        z_data = []
        z_name = ""
        z_scale = ""
        z_units = ""
    else:
        if color.find('k') == 0:
            color = False
        else:
            color = True
        marker = True
        line = zcenter

        # Perform interpolation to plot data at a specific location instead of a
        # grid point
        if (gData.has_key(hold_key) and hold_value is not None):
            ilon = 0
            ilat = 0
            x_data = np.array(gData[xkey][lonmin:lonmax, latmin:latmax,
                                          0]).flatten()
            if geo_key.find("Lon") >= 0:
                ilon = -1
            elif geo_key.find("Lat") >= 0:
                ilat = -1

            i_data = gpr.create_contour_input_array(hold_key,
                                                    hold_value,
                                                    xkey,
                                                    "Altitude", [zkey],
                                                    gData,
                                                    x_data,
                                                    alt_data[0, :],
                                                    lonmin=ilon,
                                                    latmin=ilat)
            x_data = np.array(i_data[xkey])
            z_data = np.array(i_data[zkey])
            alt_data = np.array(i_data['Altitude'])

            if zmin == None:
                zmin = np.nanmin(z_data)
            if zmax == None:
                zmax = np.nanmax(z_data)
        else:
            if (zmin == None or zmax == None):
                if gData[zkey].attrs['scale'].find("exp") >= 0:
                    raw = True
                else:
                    raw = False
                tmin, tmax = gpr.find_data_limits([gData],
                                                  zkey,
                                                  lat_index,
                                                  lon_index,
                                                  -2,
                                                  6,
                                                  raw=raw)
                if zmin == None:
                    zmin = tmin
                if zmax == None:
                    zmax = tmax

            x_data = np.array(gData[xkey][lonmin:lonmax, latmin:latmax, :])
            x_data = x_data.reshape(datadim)
            z_data = np.array(gData[zkey][lonmin:lonmax, latmin:latmax, :])
            z_data = z_data.reshape(datadim)
        x_name = gData[xkey].attrs['name']
        x_scale = gData[xkey].attrs['scale']
        x_units = gData[xkey].attrs['units']
        z_name = gData[zkey].attrs['name']
        z_scale = gData[zkey].attrs['scale']
        z_units = gData[zkey].attrs['units']

    # Initialize the new figure
    f, ax = pap.plot_single_alt_image(plot_type,
                                      x_data,
                                      alt_data / 1000.0,
                                      z_data,
                                      x_name,
                                      x_scale,
                                      x_units,
                                      "km",
                                      z_name=z_name,
                                      z_scale=z_scale,
                                      z_units=z_units,
                                      xmin=xmin,
                                      xmax=xmax,
                                      amin=amin,
                                      amax=amax,
                                      zmin=zmin,
                                      zmax=zmax,
                                      title=title,
                                      draw=False,
                                      color1=color,
                                      color2=marker,
                                      color3=line)

    # Add local time to longitude axis, if desired
    if lon_lt:
        xfmt = FuncFormatter(gData.lon_lt_ticks)
        ax.xaxis.set_major_formatter(xfmt)
        ax.set_xlabel("Longitude \ Local Time")
        plt.subplots_adjust(bottom=.13)

    # Add hmF2 if desired
    if add_hmf2 and not gData.has_key("hmF2"):
        gData.calc_2dion()
        if not gData.has_key("hmF2"):
            print module_name, "WARNING: hmF2 data is not available"
            add_hmF2 = False

    if add_hmf2:
        if plot_type.find("linear") >= 0:
            x = np.array([xmin, xmax])
            if (gData.has_key(hold_key) and hold_value is not None):
                if geo_key.find("Lon") >= 0:
                    x_data = gData[hold_key][:, latmin:latmax,
                                             int(gData.attrs['nAlt'] /
                                                 2)].flatten()
                    y_data = gData['hmF2'][:, latmin:latmax, 0].flatten()
                elif geo_key.find("Lat") >= 0:
                    x_data = gData[hold_key][lonmin:lonmax, :,
                                             int(gData.attrs['nAlt'] /
                                                 2)].flatten()
                    y_data = gData['hmF2'][20:21, :, 0].flatten()
                hold = interpolate.interp1d(x_data, y_data)
                hmf2 = hold(hold_value)
            else:
                hmf2 = gData['hmF2'][lonmin:lonmax, latmin:latmax, 0]
            y = np.array([hmf2, hmf2])
        else:
            if (gData.has_key(hold_key) and hold_value is not None):
                if geo_key.find("Lon") >= 0:
                    lonmin = 0
                    lonmax = gData.attrs['nLon']
                elif geo_key.find("Lat") >= 0:
                    latmin = 0
                    latmax = gData.attrs['nLat']
                x = x_data[0, :]
                i_data = gpr.create_linear_input_array(hold_key,
                                                       hold_value,
                                                       xkey, ['hmF2'],
                                                       gData,
                                                       x,
                                                       lonmin=lonmin,
                                                       lonmax=lonmax,
                                                       latmin=latmin,
                                                       latmax=latmax)
                y = np.array(i_data['hmF2'])
            else:
                x = x_data
                y = np.array(gData['hmF2'][lonmin:lonmax, latmin:latmax, 0])
                y = y.reshape(datadim[0:-1])
        ax.plot(x, y, color=hcolor, linestyle=hline, linewidth=2)

    # Add field lines, if desired
    if add_fieldlines and plot_type.find("contour") >= 0:
        lon = None
        dec = None
        lon_units = "radians"
        lat_units = "degrees"
        lat_type = "geographic"

        if hold_key == None:
            hold_key = "Longitude"
            hold_value = float(gData[hold_key][lonmin:lonmax, 0, 0])

        if xkey == "Latitude" or xkey == "dLat":
            from scipy import interpolate
            x = x_data[0]

            if xkey == "Latitude":
                lat_units = "radians"
            # If the geographic equator is on the x-axis, find the longitude
            # and declination at the geomagnetic equator
            ikeys = ["Declination"]
            if hold_key != "Longitude" and hold_key != "dLon":
                ikeys.append("Longitude")
                i_data = gpr.create_linear_input_array(
                    hold_key,
                    hold_value,
                    "Inclination",
                    ikeys,
                    gData,
                    x_data[0],
                    lonmax=lonmax,
                    lonmin=lonmin,
                    latmax=latmax,
                    latmin=latmin,
                    altmax=gData.attrs['nAlt'])
            else:
                x = x_data[:, 0]
                i_data = dict()
                i_data['Inclination'] = gData['Inclination'][lonmin:lonmax,
                                                             latmin:latmax, 0]
                i_data['Inclination'] = i_data['Inclination'].reshape(latmax)
                i_data['Declination'] = gData['Declination'][lonmin:lonmax,
                                                             latmin:latmax, 0]
                i_data['Declination'] = i_data['Declination'].reshape(latmax)

            # Remove any NaN
            ikeys.append("Inclination")
            test = range(len(i_data[ikeys[0]]))
            for i in ikeys:
                test *= i_data[i]

            good = [i for i, t in enumerate(test) if not np.isnan(t)]

            if len(good) > 2:
                for i in ikeys:
                    i_data[i] = i_data[i].take(good)

                # Interpolate good data
                tckdec = interpolate.splrep(i_data['Inclination'],
                                            i_data['Declination'],
                                            s=0)
                dec = interpolate.splev(0.0, tckdec, der=0)

                if i_data.has_key("Longitude"):
                    tcklon = interpolate.splrep(i_data['Inclination'],
                                                i_data['Longitude'],
                                                s=0)
                    lon = interpolate.splev(0.0, tcklon, der=0)
                else:
                    lon = hold_value

                if np.isnan(dec) or np.isnan(lon):
                    print "WARNING: unable to interpolate lon and dec at meq"
                    lat_type = None
                else:
                    # Add local time to the title
                    lt = gpr.glon_to_localtime(gData['time'], lon, lon_units)
                    h = int(lt)
                    m = int((lt - h) * 60.0)
                    ax.set_title("{:}, {:02d}:{:02d} SLT".format(title, h, m),
                                 size="medium")
            else:
                print "WARNING: unable to find longitude and declination at meq"
                lat_type = None

        elif xkey == "Inclination":
            lat_type = "inclination"
        elif xkey == "Magnetic Latitude":
            lat_type = "magnetic"
        else:
            print "WARNING: can't output field lines when xaxis is", xkey
            lat_type = None

        if lat_type is not None:
            if len(apex_alts) < 1:
                # Set default apex altitudes
                apex_alts = [
                    amin + float(i + 1) * 200.0
                    for i in range(int(math.ceil((amax - amin) / 200.0)))
                ]

            for alt in apex_alts:
                gpr.add_dipole_fieldline(ax,
                                         alt,
                                         x,
                                         lat_units=lat_units,
                                         lat_type=lat_type,
                                         longitude=lon,
                                         lon_units=lon_units,
                                         declination=dec,
                                         color=acolor,
                                         linestyle=aline)
    if draw:
        # Draw to screen.
        if plt.isinteractive():
            plt.draw()  #In interactive mode, you just "draw".
        else:
            # W/o interactive mode, "show" stops the user from typing more
            # at the terminal until plots are drawn.
            plt.show()

    # Save output file
    if figname is not None:
        plt.savefig(figname)

    return f, ax
示例#4
0
def gitm_single_alt_image(plot_type, zkey, gData, lat_index=-1, lon_index=-1,
                          title=None, figname=None, draw=True, xkey="dLat",
                          lon_lt=False, hold_key=None, geo_key=None,
                          hold_value=None, color="b", marker="o",  line=":",
                          zmax=None, zmin=None, amax=None, amin=None, xmax=None,
                          xmin=None, zcenter=False, add_hmf2=False, hcolor="k",
                          hline="--", add_fieldlines=False, apex_alts=list(),
                          acolor="k", aline="-", *args, **kwargs):
    '''
    Creates a rectangular or polar map projection plot for a specified latitude
    range.
    Input: plot_type  = key to determine plot type (linear, contour, scatter)
           zkey       = key for z variable (ie 'Vertical TEC')
           gData      = gitm bin structure
           lat_index  = index of constant latitude (default -1, none)
           lon_index  = index of constant longitude (default -1, none)
           title      = plot title
           figname    = file name to save figure as (default is none)
           xkey       = for contour plots specify an x key (default dLat)
                        (options dLat/dLon/Latitude/Longitude)
           lon_lt     = Add local time to the x axis (default=False).  Will
                        cause problems unless xkey is dLon.
           hold_key   = Key to coordinate in which desired location is specified
           geo_key    = Geographic coordinate corresponding to hold_key coord.
           hold_value = value of desired, specific coordinate location
           color      = linear color (default blue) for b&w contour, enter 'k'
           marker     = linear marker type (default circles)
           line       = linear line type (default dotted)
           zmax       = z key maximum (None to compute automatically, default)
           zmin       = z key minimum (None to compute automatically, default)
           amax       = a key maximum (None to compute automatically, default)
           amin       = a key minimum (None to compute automatically, default)
           xmax       = x key maximum for countour plots (or None to compute
                        automatically, default)
           xmin       = x key minimum for contour plots (or None to compute
                        automatically, default)
           zcenter    = Center z axis about zero? (default is False)
           add_hmf2   = Add line showing hmF2? (default=False)
           hcolor     = Line color for hmF2 line (default=black)
           hline      = Line style for hmF2 line (default=dashes)
           add_fieldlines = Add dipole field lines (default=False)
           apex_alts      = List of apex altitudes to plot field lines at
                            (default=list(), will pick a range of apex alts)
           acolor         = Line color for field lines (default="k")
           aline          = Line style for field lines (default="-")
    '''
    # Initialize the altitude and x variable limits
    if(amin == None or amax == None):
        tmin, tmax = gpr.find_data_limits([gData], "Altitude", lat_index,
                                          lon_index, -2, 30)
        if amin == None:
            amin = tmin
            amin = math.ceil(amin / 10000.0) * 10.0
        if amax == None:
            amax = tmax
            amax = math.floor(amax / 10000.0) * 10.0

    if(plot_type.find("linear") < 0 and (xmin == None or xmax == None)):
        if gData[xkey].attrs['scale'].find("exp") >= 0:
            raw = True
        else:
            raw = False

        tmin, tmax = gpr.find_data_limits([gData], xkey, lat_index, lon_index,
                                          -2, 6, raw=raw)
        if xmin == None:
            xmin = tmin
        if xmax == None:
            xmax = tmax

    # Initialize the input data indices
    datadim = [gData.attrs['nAlt']]
    if lat_index >= 0:
        latmin = lat_index
        latmax = latmin + 1
    else:
        latmin = 0
        latmax = gData.attrs['nLat']
        datadim.insert(0, gData.attrs['nLat'])

    if lon_index >= 0:
        lonmin = lon_index
        lonmax = lonmin + 1
    else:
        lonmin = 0
        lonmax = gData.attrs['nLon']
        datadim.insert(0, gData.attrs['nLon'])

    # Initialize the data
    alt_data = np.array(gData['Altitude'][lonmin:lonmax,latmin:latmax,:])
    alt_data = alt_data.reshape(datadim)

    if plot_type.find("linear") >= 0:
        # Perform interpolation to plot data at a specific location instead of a
        # grid point
        if(gData.has_key(hold_key) and hold_value is not None):
            if geo_key.find("Lon") >= 0:
                lonmin = 0
                lonmax = gData.attrs['nLon']
            elif geo_key.find("Lat") >= 0:
                latmin = 0
                latmax = gData.attrs['nLat']
            i_data = gpr.create_linear_input_array(hold_key, hold_value,
                                                   "Altitude", [zkey], gData,
                                                   alt_data, lonmin=lonmin,
                                                   lonmax=lonmax, latmin=latmin,
                                                   latmax=latmax,
                                                   altmax=gData.attrs['nAlt'])
            x_data = np.array(i_data[zkey])
            if zmin == None:
                xmin = np.nanmin(x_data)
            if zmax == None:
                xmax = np.nanmax(x_data)
        else:
            if(zmin == None or zmax == None):
                if gData[zkey].attrs['scale'].find("exp") >= 0:
                    raw = True
                else:
                    raw = False
                tmin, tmax = gpr.find_data_limits([gData],zkey,lat_index,
                                                  lon_index,-2,6,raw=raw)
                if zmin == None:
                    xmin = tmin
                if zmax == None:
                    xmax = tmax
            x_data = np.array(gData[zkey][lonmin:lonmax,latmin:latmax,:])
            x_data = x_data.reshape(datadim)
        x_name = gData[zkey].attrs['name']
        x_scale = gData[zkey].attrs['scale']
        x_units = gData[zkey].attrs['units']
        z_data = []
        z_name = ""
        z_scale = ""
        z_units = ""
    else:
        if color.find('k') == 0:
            color = False
        else:
            color = True
        marker=True
        line=zcenter

        # Perform interpolation to plot data at a specific location instead of a
        # grid point
        if(gData.has_key(hold_key) and hold_value is not None):
            ilon = 0
            ilat = 0
            x_data = np.array(gData[xkey][lonmin:lonmax,latmin:latmax,
                                          0]).flatten()
            if geo_key.find("Lon") >= 0:
                ilon = -1
            elif geo_key.find("Lat") >= 0:
                ilat = -1

            i_data = gpr.create_contour_input_array(hold_key, hold_value, xkey,
                                                    "Altitude", [zkey], gData,
                                                    x_data, alt_data[0,:],
                                                    lonmin=ilon, latmin=ilat)
            x_data = np.array(i_data[xkey])
            z_data = np.array(i_data[zkey])
            alt_data = np.array(i_data['Altitude'])

            if zmin == None:
                zmin = np.nanmin(z_data)
            if zmax == None:
                zmax = np.nanmax(z_data)
        else:
            if(zmin == None or zmax == None):
                if gData[zkey].attrs['scale'].find("exp") >= 0:
                    raw = True
                else:
                    raw = False
                tmin, tmax = gpr.find_data_limits([gData],zkey,lat_index,
                                                  lon_index, -2, 6, raw=raw)
                if zmin == None:
                    zmin = tmin
                if zmax == None:
                    zmax = tmax

            x_data = np.array(gData[xkey][lonmin:lonmax,latmin:latmax,:])
            x_data = x_data.reshape(datadim)
            z_data = np.array(gData[zkey][lonmin:lonmax,latmin:latmax,:])
            z_data = z_data.reshape(datadim)
        x_name = gData[xkey].attrs['name']
        x_scale = gData[xkey].attrs['scale']
        x_units = gData[xkey].attrs['units']
        z_name = gData[zkey].attrs['name']
        z_scale = gData[zkey].attrs['scale']
        z_units = gData[zkey].attrs['units']

    # Initialize the new figure
    f, ax = pap.plot_single_alt_image(plot_type, x_data, alt_data/1000.0,
                                      z_data, x_name, x_scale, x_units, "km",
                                      z_name=z_name, z_scale=z_scale,
                                      z_units=z_units, xmin=xmin, xmax=xmax,
                                      amin=amin, amax=amax, zmin=zmin,
                                      zmax=zmax, title=title, draw=False,
                                      color1=color, color2=marker, color3=line)

    # Add local time to longitude axis, if desired
    if lon_lt:
        xfmt = FuncFormatter(gData.lon_lt_ticks)
        ax.xaxis.set_major_formatter(xfmt)
        ax.set_xlabel("Longitude \ Local Time")
        plt.subplots_adjust(bottom=.13)

    # Add hmF2 if desired
    if add_hmf2 and not gData.has_key("hmF2"):
        gData.calc_2dion()
        if not gData.has_key("hmF2"):
            print module_name, "WARNING: hmF2 data is not available"
            add_hmF2 = False

    if add_hmf2:
        if plot_type.find("linear") >= 0:
            x = np.array([xmin, xmax])
            if(gData.has_key(hold_key) and hold_value is not None):
                if geo_key.find("Lon") >= 0:
                    x_data = gData[hold_key][:,latmin:latmax, int(gData.attrs['nAlt']/2)].flatten()
                    y_data = gData['hmF2'][:,latmin:latmax,0].flatten()
                elif geo_key.find("Lat") >= 0:
                    x_data = gData[hold_key][lonmin:lonmax,:,int(gData.attrs['nAlt']/2)].flatten()
                    y_data = gData['hmF2'][20:21,:,0].flatten()
                hold = interpolate.interp1d(x_data, y_data)
                hmf2 = hold(hold_value)
            else:
                hmf2 = gData['hmF2'][lonmin:lonmax,latmin:latmax,0]
            y = np.array([hmf2, hmf2])
        else:
            if(gData.has_key(hold_key) and hold_value is not None):
                if geo_key.find("Lon") >= 0:
                    lonmin = 0
                    lonmax = gData.attrs['nLon']
                elif geo_key.find("Lat") >= 0:
                    latmin = 0
                    latmax = gData.attrs['nLat']
                x = x_data[0,:]
                i_data = gpr.create_linear_input_array(hold_key, hold_value,
                                                       xkey, ['hmF2'], gData,
                                                       x, lonmin=lonmin,
                                                       lonmax=lonmax,
                                                       latmin=latmin,
                                                       latmax=latmax)
                y = np.array(i_data['hmF2'])
            else:
                x = x_data
                y = np.array(gData['hmF2'][lonmin:lonmax,latmin:latmax,0])
                y = y.reshape(datadim[0:-1])
        ax.plot(x, y, color=hcolor, linestyle=hline, linewidth=2)

    # Add field lines, if desired
    if add_fieldlines and plot_type.find("contour")>=0:
        lon = None
        dec = None
        lon_units = "radians"
        lat_units = "degrees"
        lat_type = "geographic"

        if hold_key == None:
            hold_key = "Longitude"
            hold_value = float(gData[hold_key][lonmin:lonmax,0,0])

        if xkey == "Latitude" or xkey == "dLat":
            from scipy import interpolate
            x = x_data[0]

            if xkey == "Latitude":
                lat_units = "radians"
            # If the geographic equator is on the x-axis, find the longitude
            # and declination at the geomagnetic equator
            ikeys = ["Declination"]
            if hold_key != "Longitude" and hold_key != "dLon":
                ikeys.append("Longitude")
                i_data = gpr.create_linear_input_array(hold_key, hold_value,
                                                       "Inclination", ikeys,
                                                       gData, x_data[0],
                                                       lonmax=lonmax,
                                                       lonmin=lonmin,
                                                       latmax=latmax,
                                                       latmin=latmin, altmax=gData.attrs['nAlt'])
            else:
                x = x_data[:,0]
                i_data = dict()
                i_data['Inclination'] = gData['Inclination'][lonmin:lonmax,
                                                             latmin:latmax,0]
                i_data['Inclination'] = i_data['Inclination'].reshape(latmax)
                i_data['Declination'] = gData['Declination'][lonmin:lonmax,
                                                             latmin:latmax,0]
                i_data['Declination'] = i_data['Declination'].reshape(latmax)

            # Remove any NaN
            ikeys.append("Inclination")
            test = range(len(i_data[ikeys[0]]))
            for i in ikeys:
                test *= i_data[i]

            good = [i for i,t in enumerate(test) if not np.isnan(t)]

            if len(good) > 2:
                for i in ikeys:
                    i_data[i] = i_data[i].take(good)

                # Interpolate good data
                tckdec = interpolate.splrep(i_data['Inclination'],
                                            i_data['Declination'], s=0)
                dec = interpolate.splev(0.0, tckdec, der=0)

                if i_data.has_key("Longitude"):
                    tcklon = interpolate.splrep(i_data['Inclination'],
                                                i_data['Longitude'], s=0)
                    lon = interpolate.splev(0.0, tcklon, der=0)
                else:
                    lon = hold_value

                if np.isnan(dec) or np.isnan(lon):
                    print "WARNING: unable to interpolate lon and dec at meq"
                    lat_type = None
                else:
                    # Add local time to the title
                    lt = gpr.glon_to_localtime(gData['time'], lon, lon_units)
                    h = int(lt)
                    m = int((lt - h) * 60.0)
                    ax.set_title("{:}, {:02d}:{:02d} SLT".format(title, h, m),
                                 size="medium")
            else:
                print "WARNING: unable to find longitude and declination at meq"
                lat_type = None

        elif xkey == "Inclination":
            lat_type = "inclination"
        elif xkey == "Magnetic Latitude":
            lat_type = "magnetic"
        else:
            print "WARNING: can't output field lines when xaxis is", xkey
            lat_type = None

        if lat_type is not None:
            if len(apex_alts) < 1:
                # Set default apex altitudes
                apex_alts = [amin+float(i+1)*200.0 for i in
                             range(int(math.ceil((amax-amin)/200.0)))]

            for alt in apex_alts:
                gpr.add_dipole_fieldline(ax, alt, x, lat_units=lat_units,
                                         lat_type=lat_type, longitude=lon,
                                         lon_units=lon_units, declination=dec,
                                         color=acolor, linestyle=aline)
    if draw:
        # Draw to screen.
        if plt.isinteractive():
            plt.draw() #In interactive mode, you just "draw".
        else:
            # W/o interactive mode, "show" stops the user from typing more 
            # at the terminal until plots are drawn.
            plt.show()

    # Save output file
    if figname is not None:
        plt.savefig(figname)

    return f, ax