示例#1
0
def plotMesh(xx, yy, zz, cmap='plasma', target=None, horiz=False):
    fig, ax = splot.set_target(target)
    orient = 'horizontal' if horiz else 'vertical'
    map_ax = ax.pcolormesh(xx, yy, zz, cmap=cmap)
    cax = fig.colorbar(map_ax, ax=ax, orientation=orient)
    m0 = 0  # colorbar min value
    ntens = 10 if (1 / cax.vmax <= 10) else 100
    m5 = roundUpTo(cax.vmax, ntens)  # colorbar max value
    num_ticks = 5
    newticks = np.linspace(m0, m5, num_ticks)
    cax.set_ticks(newticks.tolist())
    cax.set_ticklabels(['{:.2f}'.format(x) for x in newticks.tolist()])
    return ax, cax
示例#2
0
文件: cimi.py 项目: mudtop/spacepy
    def plotlog(self, vars, xlim=None, ylim=None,
                  target=None, 
                  loc=111, title=None,
                  dolog=False, 
                  figsize=(8.34,7),
                  *args, **kwargs):
        '''
        Create a plot of variable *var* at a given time.

        If kwarg **target** is None (default), a new figure is 
        generated from scratch.  If target is a matplotlib Figure
        object, a new axis is created to fill that figure at subplot
        location **loc**.  If **target** is a matplotlib Axes object, 
        the plot is placed into that axis.
        '''

        import matplotlib.pyplot as plt
        

        fig, ax = set_target(target, loc=loc, figsize=figsize)
        #ax.set_aspect('equal')

        # Grab values from correct time/location.
        for var in vars:
            x = self['time'][:]
            y = self[var][:]
            ax.plot(x,y,label=var)

        
        # Create levels and set norm based on dolog.
        if dolog:
            plt.yscale('log')

        #add legend
        ax.legend()



        if xlim != None:
            ax.set_xlim(xlim[0],xlim[1])

        if ylim != None:
            ax.set_ylim(ylim[0],ylim[1])
            

            
        return fig, ax
示例#3
0
文件: dgcpm.py 项目: yugidoge/spacepy
    def add_contour(self,
                    var,
                    zlim=None,
                    target=None,
                    loc=111,
                    title=None,
                    Lmax=None,
                    add_cbar=False,
                    clabel=None,
                    dolog=False,
                    filled=True,
                    nLev=31,
                    labelsize=14,
                    **kwargs):
        '''
        Create a polar contour plot of variable *var* and add it to *target*. 
        Extra keyword arguments are handed to matplotlib's contourf command.

        Parameters
        ==========
        var : string
             The variable within the object to plot.

        Returns
        =======
        fig : matplotlib figure object
        ax  : matplotlib axes object
        cont : matplotlib contour object
        cbar : matplotlib colorbar object

        Other Parameters
        ================
        nLev : int
             Sets the number of contour levels.  Defaults to 31.
        zlim : two-element list or array
             Set the color bar range.  Some variables have default ranges.  Others
             will use max and min of *var*.
        Lmax : real
             Set the radial extent of the plot.
        add_cbar : bool
             Set whether to add a color bar or not.  Defaults to **False**.
        dolog : bool
             If **True**, use a log scale to plot *var*.  Defaults to **False**.
        labelsize : int
             Sets the font size of the labels.  Defaults to 14.
        title : string
             Sets the plot title.  Defaults to 'auto', using the variable label.
        clabel : string
             Set label for the color bar.  Defaults to *var* and associated units.
        target : Figure or Axes
             If None (default), a new figure is generated from scratch.
             If a matplotlib Figure object, a new axis is created
             to fill that figure.
             If a matplotlib Axes object, the plot is placed
             into that axis.
        loc : int
            Use to specify the subplot placement of the axis
            (e.g. loc=212, etc.) Used if target is a Figure or None.
            Default 111 (single plot).

        '''
        from numpy import linspace, pi
        import matplotlib.pyplot as plt
        from matplotlib.colors import LogNorm
        from matplotlib.ticker import MultipleLocator, LogLocator

        # Set ax and fig based on given target.
        fig, ax = set_target(target, figsize=(10.5, 8), loc=loc, polar=True)

        # Set function based on boolean "filled":
        if filled:
            contour = ax.contourf
        else:
            contour = ax.contour

        # Get max/min if none given.
        if zlim == None:
            if var in self._default_zlims:
                zlim = self._default_zlims[var]
            else:
                zlim = [self[var].min(), self[var].max()]
            if dolog and zlim[0] <= 0:
                zlim[0] = np.min([0.0001, zlim[1] / 1000.0])

        # Create levels and set norm based on dolog.
        if dolog:
            levs = np.power(
                10, np.linspace(np.log10(zlim[0]), np.log10(zlim[1]), nLev))
            z = np.where(self[var] > zlim[0], self[var], 1.01 * zlim[0])
            z[z > zlim[-1]] = zlim[-1]
            norm = LogNorm()
            lct = LogLocator()
        else:
            levs = np.linspace(zlim[0], zlim[1], nLev)
            z = self[var]
            norm = None
            lct = None

        # Allow results to cross phi=360.
        phi = np.concatenate(
            (self['lon'], [360.0])) * np.pi / 180. - np.pi / 2.
        z = np.concatenate((z, np.array([z[:, 0]]).transpose()), 1)

        # Set default color tables based on variable plotted.
        if ('cmap' not in kwargs) and ('colors' not in kwargs) and \
                (var in self._default_cmaps):
            kwargs['cmap'] = self._default_cmaps[var]

        # -------Plot away------
        # Contour:
        cont = contour(phi, self['L'], z, levs, norm=norm, **kwargs)
        # Add cbar if requested:
        if add_cbar:
            cbar = plt.colorbar(cont, pad=0.08, shrink=.8, ticks=lct, ax=ax)
            if clabel == None:
                clabel = "%s ($%s$)" % (var, self[var].attrs['units'])
            cbar.set_label(clabel)
        else:
            cbar = None

        # Adjust plot appropriately.
        if not Lmax:
            # Default to inside ghost cells.
            Lmax = self['L'][-3]
            if title:
                ax.set_title(title + '\n' + self.attrs['time'].isoformat(),
                             position=(0, 1),
                             ha='left',
                             size=14)
        _adjust_dialplot(ax, Lmax, labelsize=labelsize)

        return fig, ax, cont, cbar
示例#4
0
文件: dgcpm.py 项目: yugidoge/spacepy
    def add_pcolor(self,
                   var,
                   zlim=None,
                   target=None,
                   loc=111,
                   title=None,
                   Lmax=None,
                   add_cbar=False,
                   clabel=None,
                   dolog=False,
                   labelsize=14,
                   **kwargs):
        '''
        Create a polar pcolor plot of variable *var* and add it to *target*. 
        Extra keyword arguments are handed to matplotlib's pcolor command.

        Parameters
        ==========
        var : string
             The variable within the object to plot.

        Returns
        =======
        fig : matplotlib figure object
        ax  : matplotlib axes object
        cont : matplotlib contour object
        cbar : matplotlib colorbar object

        Other Parameters
        ================
        zlim : two-element list or array
             Set the color bar range.  Some variables have default ranges.  Others
             will use max and min of *var*.
        Lmax : real
             Set the radial extent of the plot.
        add_cbar : bool
             Set whether to add a color bar or not.  Defaults to **False**.
        dolog : bool
             If **True**, use a log scale to plot *var*.  Defaults to **False**.
        labelsize : int
             Sets the font size of the labels.  Defaults to 14.
        title : string
             Sets the plot title.  Defaults to 'auto', using the variable label.
        clabel : string
             Set label for the color bar.  Defaults to *var* and associated units.
        target : Figure or Axes
             If None (default), a new figure is generated from scratch.
             If a matplotlib Figure object, a new axis is created
             to fill that figure.
             If a matplotlib Axes object, the plot is placed
             into that axis.
        loc : int
            Use to specify the subplot placement of the axis
            (e.g. loc=212, etc.) Used if target is a Figure or None.
            Default 111 (single plot).

        '''

        from numpy import linspace, pi
        import matplotlib.pyplot as plt
        from matplotlib.colors import LogNorm

        # Set ax and fig based on given target.
        fig, ax = set_target(target, figsize=(10.5, 8), loc=loc, polar=True)

        # Get max/min if none given.
        if zlim == None:
            if var in self._default_zlims:
                zlim = self._default_zlims[var]
            else:
                zlim = [self[var].min(), self[var].max()]
            if dolog and zlim[0] <= 0:
                zlim[0] = np.min([0.0001, zlim[1] / 1000.0])

        # Logarithmic scale?
        if dolog:
            z = np.where(self[var] > zlim[0], self[var], 1.01 * zlim[0])
            norm = LogNorm()
        else:
            z = self[var]
            norm = None

        # Set up proper meshes.
        nL, nPhi = len(self['L']), len(self['lon'])
        dL, dPhi = self.attrs['dL'], self.attrs['dLon'] * pi / 180.0
        phi = linspace(-1.0 * dPhi / 2.0, 2. * pi - dPhi / 2.0,
                       nPhi + 1) - pi / 2.
        r = linspace(self['L'][0] - dL / 2.0, self['L'][-1] + dL / 2.0, nL + 1)

        # Set default color tables based on variable plotted.
        if ('cmap' not in kwargs) and var in self._default_cmaps:
            kwargs['cmap'] = self._default_cmaps[var]

        # -------Plot away------
        # Mesh:
        pcol = ax.pcolormesh(phi,
                             r,
                             z,
                             vmin=zlim[0],
                             vmax=zlim[1],
                             norm=norm,
                             **kwargs)
        # Add cbar if requested:
        if add_cbar:
            cbar = plt.colorbar(pcol, pad=0.08, shrink=.8, ax=ax)
            if clabel == None:
                clabel = "%s ($%s$)" % (var, self[var].attrs['units'])
            cbar.set_label(clabel)
        else:
            cbar = None

        # Adjust plot appropriately.
        if not Lmax:
            # Default to inside ghost cells.
            Lmax = self['L'][-3]
            if title:
                ax.set_title(title + '\n' + self.attrs['time'].isoformat(),
                             position=(0, 1),
                             ha='left',
                             size=14)
        _adjust_dialplot(ax, Lmax, labelsize=labelsize)

        return fig, ax, pcol, cbar
示例#5
0
    def add_oval_line(self, time, *args, **kwargs):
        '''
        Adds the location of the auroral oval at time *time* as a line plot on to
        *target*, which must be a Matplotlib figure/axes.  

        If *target* not given, a new axes object is created.  If *target* is
        not an existing axes object, a new axes object is created and customized
        to be an ionosphere polar plot.

        Extra arguments/kwargs are sent to :meth:`matplotlib.pyplot.plot`.

        Parameters
        ==========
        time : integer or datetime
           Sets the time at which to plot the line.  If an integer is used,
           the integer is used to index the internal array naively.  If a
           datetime object is given and is within the bounds of self['time'],
           the oval location will be interpolated to *time*.  Control of the
           interpolation happens via the *interp* keyword.

        Returns
        =======
        fig  : matplotlib figure object
        ax   : matplotlib axes object
        line : matplotlib line object

        Other Parameters
        ================
        target : Figure or Axes
            If None (default), a new figure is generated from scratch.
            If a matplotlib Figure object, a new axis is created
            to fill that figure.
            If a matplotlib Axes object, the plot is placed
            into that axis.
        loc : int
            Use to specify the subplot placement of the axis
            (e.g. loc=212, etc.) Used if target is a Figure or None.
            Default 111 (single plot).
        interp : bool
            Control the behavior of time interpolation when the *time* argument
            is given as a datetime object.  Defaults to **True**, meaning that
            oval location is interpolated in time.  

        Examples
        ========
        >>> 
        '''

        import datetime as dt

        # Handle kwargs not being handed to plot:
        target=None; loc=111; interp=True
        if 'target' in kwargs: target=kwargs.pop('target')
        if 'interp' in kwargs: interp=kwargs.pop('interp')
        if 'loc'    in kwargs: loc=kwargs.pop('loc')
            
        # Set plot targets:
        fig, ax = set_target(target, polar=True, loc=loc)

        # Get oval interpolated in time:
        if type(time) == dt.datetime:
            oval = self.get_oval(time, interp=interp)
        elif type(time) == int:
            oval = self['oval'][time]
        else:
            raise TypeError('Unrecognized type for *time*:'+type(time))

        # Plot oval:
        line = ax.plot(self['lon']+np.pi/2., oval, *args, **kwargs)

        return fig, ax, line
示例#6
0
            outputlist = inputlist/fac
        except TypeError: #not an array
            outputlist = [el/fac for el in inputlist]
    return outputlist

isi = convert_tdelt(results['tau_valid'], units='minutes')
isi_hr = convert_tdelt(results['tau_valid'], units='hours')
tau_ax = np.arange(0,30*60,.2)

try:
    from sklearn.neighbors.kde import KernelDensity
    kern_type = 'epanechnikov'
    kern_lab = '{0}{1} KDE'.format(kern_type[0].upper(), kern_type[1:])
    kernel = KernelDensity(kernel=kern_type, bandwidth=60).fit(isi[:, np.newaxis])
    kde_plot = np.exp(kernel.score_samples(tau_ax[:, np.newaxis]))
except ImportError:
    from scipy import stats
    kern_lab = 'Gaussian KDE'
    kernel = stats.gaussian_kde(isi, bw_method='scott')
    kde_plot = kernel.evaluate(tau_ax)

fig, ax = splot.set_target(None)
ax.hist(isi_hr, bins=np.arange(0,25,0.5), histtype='step', normed=True, lw=1.5, label='Binned Data')
ax.plot(tau_ax/60., kde_plot*60., lw=1.5, label=kern_lab)
ax.set_xlim([0,25])
ax.set_ylabel('Probability')
ax.set_xlabel(r'Inter-substorm Interval, $\tau$ [hours]') #raw string req'd (else \t in \tau becomes [tab]au
ax.legend()
fig.suptitle('MSM$_{Python}$: ' + '{0} (1998-2002)'.format(satname))
plt.show()
示例#7
0
    def add_histplot(self,
                     target=False,
                     loc=111,
                     label='Kyoto $K_{p}$',
                     time_range=None,
                     **kwargs):
        '''
        Make a quick histogram-style plot of the Kp data.

        Returns
        =======
        fig : matplotlib figure object
        ax  : matplotlib axes object

        Other Parameters
        ================
        target : Figure or Axes
             If None (default), a new figure is generated from scratch.
             If a matplotlib Figure object, a new axis is created
             to fill that figure.
             If a matplotlib Axes object, the plot is placed
             into that axis.
        
        loc : int
           Use to specify the subplot placement of the axis
           (e.g. loc=212, etc.) Used if target is a Figure or None.
           Default 111 (single plot).

        label : string
            The label applied to the line when a legend is added to the axes.
            Defaults to 'Kyoto $K_{p}$'.

        time_range : tuple of datetimes
            The time range to plot.  Only the first and last values in the
            tuple (or list) are used if the number of elements is greater than
            two.  Defaults to **None**, meaning that the full time range
            available is used.

        Extra keyword arguments are passed to :function:`matplotlib.pyplot.plot`
        to customize the line style.

        Examples
        ========
        >>> import spacepy.pybats.kyoto as kt
        >>> kp = kt.fetch('kp', (1981, 11), (1981, 11)
        >>> kp.add_histplot(lw=2.0, lc='r', label='Example KP')

        '''

        import matplotlib.pyplot as plt

        # Shortcuts for the lazy.
        bstart = self['binstart']
        bstop = self['binstop']
        npts = self.attrs['npts']

        # Reformulate time to get histogram-type look.
        newtime = np.zeros(npts * 24, dtype=object)
        newkp = np.zeros(npts * 24)

        # Set time range.
        if not time_range:
            time_range = newtime

        for i in range(npts * 8):
            newtime[3 * i] = bstart[i]
            newtime[3 * i + 1] = self['time'][i]
            newtime[3 * i + 2] = bstop[i]
            newkp[3 * i:3 * i +
                  3] = self['kp'][i], self['kp'][i], self['kp'][i]

        fig, ax = set_target(target, figsize=(10, 4), loc=loc)
        line = ax.plot(newtime, newkp, label=label, **kwargs)
        applySmartTimeTicks(ax, time_range, dolabel=True)

        return fig, ax
示例#8
0
文件: pwom.py 项目: aglocer/spacepy
    def add_slice(self,
                  var,
                  time,
                  nlev=31,
                  zlim=None,
                  target=None,
                  loc=111,
                  title=None,
                  latoffset=1.05,
                  rlim=50.,
                  add_cbar=True,
                  clabel=None,
                  show_pts=False,
                  dolog=False,
                  lats=[75., 60.],
                  colats=None,
                  figsize=(8.34, 7),
                  *args,
                  **kwargs):
        '''
        Create a plot of variable *var*.

        If kwarg **target** is None (default), a new figure is 
        generated from scratch.  If target is a matplotlib Figure
        object, a new axis is created to fill that figure at subplot
        location **loc**.  If **target** is a matplotlib Axes object, 
        the plot is placed into that axis.
        '''

        import matplotlib.pyplot as plt
        from matplotlib.colors import (LogNorm, Normalize)
        from matplotlib.patches import Circle
        from matplotlib.ticker import (LogLocator, LogFormatter,
                                       LogFormatterMathtext, MultipleLocator)

        # Grab the slice of data that we want:
        if type(time) == type(self['time'][0]):
            if time not in self['time']:
                raise ValueError('Time not in object')
            time = np.arange(self.attrs['nTime'])[self['time'] == time][0]

        fig, ax = set_target(target, loc=loc, figsize=figsize)
        ax.set_aspect('equal')

        # Create values in Cartesian plane.
        self._get_latlon()

        # Grab values from correct time/location.
        x = self._xLat[time, :]
        y = self._yLat[time, :]
        value = self[var][time, :]

        # Get max/min if none given.
        if zlim == None:
            zlim = [0, 0]
            zlim[0] = value.min()
            zlim[1] = value.max()
            if dolog and zlim[0] <= 0:
                zlim[0] = np.min([0.0001, zlim[1] / 1000.0])

        # Create levels and set norm based on dolog.
        if dolog:
            levs = np.power(
                10, np.linspace(np.log10(zlim[0]), np.log10(zlim[1]), nlev))
            z = np.where(value > zlim[0], value, 1.01 * zlim[0])
            norm = LogNorm()
            ticks = LogLocator()
            fmt = LogFormatterMathtext()
        else:
            levs = np.linspace(zlim[0], zlim[1], nlev)
            z = value
            norm = None
            ticks = None
            fmt = None

        # Create contour plot.
        cont=ax.tricontourf(np.asarray(x), np.asarray(y), np.asarray(z), \
                            np.asarray(levs), *args, norm=norm, **kwargs)

        if show_pts:
            ax.plot(x, y, '+w')

        # Add cbar if necessary.
        if add_cbar:
            cbar = plt.colorbar(cont, ticks=ticks, format=fmt, pad=0.01)
            if clabel == None:
                clabel = "%s (%s)" % (var, self[var].attrs['units'])
            cbar.set_label(clabel)
        else:
            cbar = None  # Need to return something, even if none.

        # Set title, labels, axis ranges (use defaults where applicable.)
        if title: ax.set_title(title)
        ax.set_yticks([]), ax.set_xticks([])
        ax.set_ylabel(r'Sun $\rightarrow$')
        colat_lim = 90. - rlim
        ax.set_xlim([-1 * colat_lim, colat_lim])
        ax.set_ylim([-1 * colat_lim, colat_lim])

        if colats:
            for colat in colats:
                r = latoffset * colat / np.sqrt(2)
                ax.add_patch(
                    Circle([0, 0], colat, fc='none', ec='k', ls='dashed'))
                ax.text(r,
                        r,
                        '{:.0f}'.format(colat) + r'$^{\circ}$',
                        rotation=315,
                        ha='center',
                        va='center')
        else:
            for lat in lats:
                colat = 90 - lat
                r = latoffset * colat / np.sqrt(2)
                ax.add_patch(
                    Circle([0, 0], colat, fc='none', ec='k', ls='dashed'))
                ax.text(r,
                        r,
                        '{:.0f}'.format(lat) + r'$^{\circ}$',
                        rotation=315,
                        ha='center',
                        va='center')

        return fig, ax, cont, cbar
示例#9
0
文件: dgcpm.py 项目: spacepy/spacepy
    def add_ltut(self, target=None, loc=111, cmap='Greens_r', zlim=[1,1000], 
                 add_cbar=True, clabel='Density $cm^{-3}$', xlabel='full', 
                 ylim=[4,20], title=None, grid=True, ntick=5):
        '''
        Plot log(density) as a contour against local time (y-axis) and
        universal time (x-axis) using the PyBats *target* method of other
        standard plotting methods.  Four items are returned: the Matplotlib
        Figure, Axes, Mesh, and ColorBar objects used (if cbar is set to
        **False**, the returned ColorBar object is simply set to **False**.)

        ========== =======================================================
        Kwarg      Description
        ---------- -------------------------------------------------------
        target     Select plot destination.  Defaults to new figure/axis.
        loc        The location of any generated subplots.  Default is 111.
        add_cbar   Toggles the automatic colorbar.  Default is**True**.
        cmap       Selects Matplotlib color table.  Defaults to *Greens_r*.
        zlim       Limits for z-axis.  Defaults to [0.1, 1000]
        ylim       Sets the MLT range on the y-axis.  Defaults to [4,20].
        clabel     Sets colorbar label.  Defaults to units.
        xlabel     Sets x-axis labels, use 'full', 'ticks', or **None**.
        title      Sets axis title; defaults to **None**.
        grid       Show white dotted grid?  Defaults to **True**
        ntick      Number of attempted cbar ticks.  Defaults to 5.
        ========== =======================================================
        
        '''
        
        import matplotlib.pyplot as plt
        from matplotlib.ticker import LogLocator, LogFormatterMathtext
        from matplotlib.colors import LogNorm

        # Set ax and fig based on given target.
        fig, ax  = set_target(target, loc=loc)
        # Enforce values to be within limits.
        z=np.where(self['n']>zlim[0], self['n'], 1.01*zlim[0])
        z[z>zlim[1]] = zlim[1]

        # Create plot:
        mesh = ax.pcolormesh(self._dtime, self._y, z.transpose(), 
                             cmap=plt.get_cmap(cmap), norm=LogNorm(),
                             vmin=zlim[0], vmax=zlim[-1])

        # Use LT ticks and markers on y-axis:
        ax.set_yticks([6, 12, 18])
        ax.set_yticklabels(['Dawn', 'Noon', 'Dusk'])
        ax.set_ylim(ylim)

        # White ticks, slightly thicker:
        ax.tick_params(axis='both', which='both', color='w', width=1.2)

        # Grid marks:
        if grid: ax.grid(c='w')

        if title: ax.set_title(title)
        if xlabel == 'full':
            # Both ticks and label.
            applySmartTimeTicks(ax, self['time'], dolabel=True)
        elif xlabel == 'ticks':
            # Ticks, but no date label.
            applySmartTimeTicks(ax, self['time'], dolabel=False)
        else:
            # A blank x-axis is often useful.
            applySmartTimeTicks(ax, self['time'], dolabel=False)
            ax.set_xticklabels('')
        # Add cbar as necessary:
        if add_cbar:
            #lct = LogLocator
            cbar=plt.colorbar(mesh, ax=ax, pad=0.01, shrink=0.85)#, ticks=lct)
            cbar.set_label(clabel)
        else:
            cbar=None
            
        return fig, ax, mesh, cbar
示例#10
0
文件: dgcpm.py 项目: spacepy/spacepy
    def add_separatrix(self, target=None,loc=111,Lmax=None,title=None,**kwargs):
        '''
        Attempts to locate the separatrix (separator between closed and
        open drift paths) by finding the minimum velocity in the domain and
        tracing the path of constant potential that passes through that point.
        The figure, axes, and contour object containing the separatrix line
        are returned to the user.

        If kwarg **target** is None (default), a new figure is 
        generated from scratch.  If target is a matplotlib Figure
        object, a new axis is created to fill that figure at subplot
        location **loc**.  If **target** is a matplotlib Axes object, 
        the plot is placed into that axis.

        Four values are returned: the matplotlib Figure and Axes objects,
        the matplotlib contour object, and the matplotlib colorbar object
        (defaults to *False* if not used.)

        Kwargs that set line characteristics behave in the typical matplotlib
        manner (i.e. "colors" can be set to either a color name or a 
        hexidecimal specifier.)

        =========== ==========================================================
        Kwarg       Description
        ----------- ----------------------------------------------------------
        target      Set plot destination.  Defaults to new figure.
        loc         Set subplot location.  Defaults to 111.
        linewidths  Set width of plotted line.  Defaults to 3.0.
        colors      Set color of line.  Defaults to 'orange'.
        linestyles  Set line style.  Defaults to 'dashed'.
        ----------- ----------------------------------------------------------
        
        '''
        
        from numpy import linspace, pi, sqrt
        import matplotlib.pyplot as plt

        # Set default line behavior.
        if 'linewidths' not in kwargs:
            kwargs['linewidths'] = 3.0
        if 'colors' not in kwargs:
            kwargs['colors'] = 'orange'
        if 'linestyles' not in kwargs:
            kwargs['linestyles'] = 'solid'

        # Set ax and fig based on given target.
        fig, ax  = set_target(target, figsize=(10.5,8), loc=loc, polar=True)
        doAdjust = not target==ax
            
        # Find the stagnation point by looking for E = 0.
        # Get the potential value at that spot.
        # Exclude near-boundary points and limit azimuthal extent.
        if 'E' not in self:
            self.calc_E()
        i = np.arange(self['L'].size  )[self['L']<9.75]
        j = np.arange(self['lon'].size)[(self['lon']>250.) & (self['lon']<360.)]
        pmin  = self['pot'][self['E'] == self['E'][i[0]:i[-1],j[0]:j[-1]].min()][0]

        # Create a contour that only follows that potential curve.
        phi = np.concatenate( (self['lon'], [360.0]) ) * pi/180. - pi/2.
        z   = np.concatenate( (self['pot'], 
                               np.array([self['pot'][:,0]]).transpose()  ), 1)
        cnt = ax.contour(phi, self['L'], z, levels=[pmin], **kwargs)

        # Adjust plot appropriately.
        if doAdjust:
            if not Lmax:
                # Default to inside ghost cells.
                Lmax = self['L'][-3]
                if title:
                    ax.set_title(title+'\n'+self.attrs['time'].isoformat(), 
                                 position=(0,1), ha='left', size=14)
            _adjust_dialplot(ax, Lmax, labelsize=14)

        # Return bits to user.
        return fig, ax, cnt
示例#11
0
文件: dgcpm.py 项目: spacepy/spacepy
    def add_contour(self, var, zlim=None, target=None, loc=111, title=None,
                    Lmax=None, add_cbar=False, clabel=None, dolog=False, 
                    filled=True, nLev=31, labelsize=14, **kwargs):
        '''
        Create a polar contour plot of variable *var* and add it to *target*. 
        Extra keyword arguments are handed to matplotlib's contourf command.

        Parameters
        ==========
        var : string
             The variable within the object to plot.

        Returns
        =======
        fig : matplotlib figure object
        ax  : matplotlib axes object
        cont : matplotlib contour object
        cbar : matplotlib colorbar object

        Other Parameters
        ================
        nLev : int
             Sets the number of contour levels.  Defaults to 31.
        zlim : two-element list or array
             Set the color bar range.  Some variables have default ranges.  Others
             will use max and min of *var*.
        Lmax : real
             Set the radial extent of the plot.
        add_cbar : bool
             Set whether to add a color bar or not.  Defaults to **False**.
        dolog : bool
             If **True**, use a log scale to plot *var*.  Defaults to **False**.
        labelsize : int
             Sets the font size of the labels.  Defaults to 14.
        title : string
             Sets the plot title.  Defaults to 'auto', using the variable label.
        clabel : string
             Set label for the color bar.  Defaults to *var* and associated units.
        target : Figure or Axes
             If None (default), a new figure is generated from scratch.
             If a matplotlib Figure object, a new axis is created
             to fill that figure.
             If a matplotlib Axes object, the plot is placed
             into that axis.
        loc : int
            Use to specify the subplot placement of the axis
            (e.g. loc=212, etc.) Used if target is a Figure or None.
            Default 111 (single plot).

        '''        
        from numpy import linspace, pi
        import matplotlib.pyplot as plt
        from matplotlib.colors import LogNorm
        from matplotlib.ticker import MultipleLocator, LogLocator

        # Set ax and fig based on given target.
        fig, ax  = set_target(target, figsize=(10.5,8), loc=loc, polar=True)

        # Set function based on boolean "filled":
        if filled:
            contour = ax.contourf
        else:
            contour = ax.contour

        # Get max/min if none given.
        if zlim==None:
            if var in self._default_zlims:
                zlim = self._default_zlims[var]
            else:
                zlim = [self[var].min(), self[var].max()]
            if dolog and zlim[0]<=0:
                zlim[0] = np.min( [0.0001, zlim[1]/1000.0] )

        # Create levels and set norm based on dolog.
        if dolog:
            levs = np.power(10, np.linspace(np.log10(zlim[0]), 
                                            np.log10(zlim[1]), nLev))
            z=np.where(self[var]>zlim[0],  self[var], 1.01*zlim[0])
            z[z>zlim[-1]] = zlim[-1]
            norm=LogNorm()
            lct= LogLocator()
        else:
            levs = np.linspace(zlim[0], zlim[1], nLev)
            z=self[var]
            norm=None
            lct=None
            
        # Allow results to cross phi=360.
        phi = np.concatenate( (self['lon'], [360.0]) ) * np.pi/180. - np.pi/2.
        z = np.concatenate( (z, np.array([z[:,0]]).transpose()  ), 1)

        # Set default color tables based on variable plotted.
        if ('cmap' not in kwargs) and ('colors' not in kwargs) and \
                (var in self._default_cmaps):
            kwargs['cmap'] = self._default_cmaps[var]

        # -------Plot away------
        # Contour:
        cont = contour(phi, self['L'], z, levs, norm=norm, **kwargs)
        # Add cbar if requested:
        if add_cbar:
            cbar=plt.colorbar(cont, pad=0.08, shrink=.8, ticks=lct, ax=ax)
            if clabel==None: 
                clabel="%s ($%s$)" % (var, self[var].attrs['units'])
            cbar.set_label(clabel)
        else:
            cbar=None
        
        # Adjust plot appropriately.
        if not Lmax:
            # Default to inside ghost cells.
            Lmax = self['L'][-3]
            if title:
                ax.set_title(title+'\n'+self.attrs['time'].isoformat(), 
                             position=(0,1), ha='left', size=14)
        _adjust_dialplot(ax, Lmax, labelsize=labelsize)

        return fig, ax, cont, cbar
示例#12
0
文件: dgcpm.py 项目: spacepy/spacepy
    def add_pcolor(self, var, zlim=None, target=None, loc=111, title=None,
                   Lmax=None, add_cbar=False, clabel=None, dolog=False, 
                   labelsize=14, **kwargs):
        '''
        Create a polar pcolor plot of variable *var* and add it to *target*. 
        Extra keyword arguments are handed to matplotlib's pcolor command.

        Parameters
        ==========
        var : string
             The variable within the object to plot.

        Returns
        =======
        fig : matplotlib figure object
        ax  : matplotlib axes object
        cont : matplotlib contour object
        cbar : matplotlib colorbar object

        Other Parameters
        ================
        zlim : two-element list or array
             Set the color bar range.  Some variables have default ranges.  Others
             will use max and min of *var*.
        Lmax : real
             Set the radial extent of the plot.
        add_cbar : bool
             Set whether to add a color bar or not.  Defaults to **False**.
        dolog : bool
             If **True**, use a log scale to plot *var*.  Defaults to **False**.
        labelsize : int
             Sets the font size of the labels.  Defaults to 14.
        title : string
             Sets the plot title.  Defaults to 'auto', using the variable label.
        clabel : string
             Set label for the color bar.  Defaults to *var* and associated units.
        target : Figure or Axes
             If None (default), a new figure is generated from scratch.
             If a matplotlib Figure object, a new axis is created
             to fill that figure.
             If a matplotlib Axes object, the plot is placed
             into that axis.
        loc : int
            Use to specify the subplot placement of the axis
            (e.g. loc=212, etc.) Used if target is a Figure or None.
            Default 111 (single plot).

        '''

        from numpy import linspace, pi
        import matplotlib.pyplot as plt
        from matplotlib.colors import LogNorm

        # Set ax and fig based on given target.
        fig, ax  = set_target(target, figsize=(10.5,8), loc=loc, polar=True)

        # Get max/min if none given.
        if zlim==None:
            if var in self._default_zlims:
                zlim = self._default_zlims[var]
            else:
                zlim = [self[var].min(), self[var].max()]
            if dolog and zlim[0]<=0:
                zlim[0] = np.min( [0.0001, zlim[1]/1000.0] )

        # Logarithmic scale?
        if dolog:
            z=np.where(self[var]>zlim[0], self[var], 1.01*zlim[0])
            norm=LogNorm()
        else:
            z=self[var]
            norm=None

        # Set up proper meshes. 
        nL, nPhi = len(self['L']), len(self['lon'])
        dL, dPhi = self.attrs['dL'], self.attrs['dLon']*pi/180.0
        phi = linspace(-1.0*dPhi/2.0, 2.*pi-dPhi/2.0, nPhi+1)-pi/2.
        r   = linspace(self['L'][0]-dL/2.0, self['L'][-1]+dL/2.0, nL+1)

        # Set default color tables based on variable plotted.
        if ('cmap' not in kwargs) and var in self._default_cmaps:
            kwargs['cmap'] = self._default_cmaps[var]

        # -------Plot away------
        # Mesh:
        pcol = ax.pcolormesh(phi, r, z, vmin=zlim[0], vmax=zlim[1],
                             norm=norm, **kwargs)
        # Add cbar if requested:
        if add_cbar:
            cbar=plt.colorbar(pcol, pad=0.08, shrink=.8, ax=ax)
            if clabel==None: 
                clabel="%s ($%s$)" % (var, self[var].attrs['units'])
            cbar.set_label(clabel)
        else:
            cbar=None
        
        # Adjust plot appropriately.
        if not Lmax:
            # Default to inside ghost cells.
            Lmax = self['L'][-3]
            if title:
                ax.set_title(title+'\n'+self.attrs['time'].isoformat(), 
                             position=(0,1), ha='left', size=14)
        _adjust_dialplot(ax, Lmax, labelsize=labelsize)

        return fig, ax, pcol, cbar
示例#13
0
    def add_histplot(self, target=False, loc=111, label='Kyoto $K_{p}$', 
                     time_range=None, **kwargs):
        '''
        Make a quick histogram-style plot of the Kp data.

        Returns
        =======
        fig : matplotlib figure object
        ax  : matplotlib axes object

        Other Parameters
        ================
        target : Figure or Axes
             If None (default), a new figure is generated from scratch.
             If a matplotlib Figure object, a new axis is created
             to fill that figure.
             If a matplotlib Axes object, the plot is placed
             into that axis.
        
        loc : int
           Use to specify the subplot placement of the axis
           (e.g. loc=212, etc.) Used if target is a Figure or None.
           Default 111 (single plot).

        label : string
            The label applied to the line when a legend is added to the axes.
            Defaults to 'Kyoto $K_{p}$'.

        time_range : tuple of datetimes
            The time range to plot.  Only the first and last values in the
            tuple (or list) are used if the number of elements is greater than
            two.  Defaults to **None**, meaning that the full time range
            available is used.

        Extra keyword arguments are passed to :function:`matplotlib.pyplot.plot`
        to customize the line style.

        Examples
        ========
        >>> import spacepy.pybats.kyoto as kt
        >>> kp = kt.fetch('kp', (1981, 11), (1981, 11)
        >>> kp.add_histplot(lw=2.0, lc='r', label='Example KP')

        '''

        import matplotlib.pyplot as plt

        # Shortcuts for the lazy.
        bstart=self['binstart']
        bstop =self['binstop']
        npts  =self.attrs['npts']

        # Reformulate time to get histogram-type look.
        newtime=np.zeros(npts*24, dtype=object)
        newkp  =np.zeros(npts*24)

        # Set time range.
        if not time_range:
            time_range = newtime
        
        for i in range(npts*8):
            newtime[3*i  ] = bstart[i]
            newtime[3*i+1] = self['time'][i]
            newtime[3*i+2] = bstop[i]
            newkp[3*i:3*i+3] = self['kp'][i], self['kp'][i], self['kp'][i]
    

        fig, ax = set_target(target, figsize=(10,4), loc=loc)
        line=ax.plot(newtime, newkp, label=label, **kwargs)
        applySmartTimeTicks(ax, time_range, dolabel=True)

        return fig, ax
示例#14
0
    def add_cont(self, var, target=None, n=24, maxz=False, lines=True, 
                 cmap=False, add_cbar=False, label=None, loc=111,
                 xticksize=12, yticksize=12, **kwargs):
        '''
        Create a polar contour of variable *var*.  Plot will be either drawn
        on a new matplotlib figure and axes, or you can specify a plot target
        using the *target* kwarg.

        Parameters
        ==========
        var : str
           The name of the variable to plot.

        Returns
        =======
        fig : matplotlib figure object
        ax  : matplotlib axes object
        cnt : matplotlib contour object
        cb  : matplotlib colorbar object

        Other Parameters
        ================
        target : Figure or Axes
            If None (default), a new figure is generated from scratch.
            If a matplotlib Figure object, a new axis is created
            to fill that figure.
            If a matplotlib Axes object, the plot is placed
            into that axis.
        loc : int
            Use to specify the subplot placement of the axis
            (e.g. loc=212, etc.) Used if target is a Figure or None.
            Default 111 (single plot).
        n : int
            Set number of levels.  Should be a multiple of 3 for best match
            between filled and traced contours.  Default is 21.
        lines : bool
            Add unfilled black solid/dashed contours to plot for additional
            contrast.  Default is **True**.
        maxz : real
            Set the max/min value for the color bar.  Default is set by data.
        cmap : str
            Set the colormap.  Default is to autoselect using classic IE maps.
            Can be 'bwr', 'wr', or any name of a matplotlib colar map.
        add_cbar : bool
            Add colorbar to plot.  Default is **False** which will
            not add one to the plot.
        label : str or None
            Label to place at top of plot.  Defaults to variable name.

        Extra keywords are passed to the contourf routine.

        '''
        # Get only what we need to decrease runtime.
        from math import pi
        from numpy import linspace
        from matplotlib.colors import Normalize
        from matplotlib.ticker import MaxNLocator, MultipleLocator
        from matplotlib.pyplot import clabel, colorbar

        fig, ax = set_target(target, polar=True, loc=loc)
        
        hemi = var[:2]

        # Set levels and ticks:
        if label==None:
            label=tex_label(var)
        lt_labels = ['06',    label, '18',   '00']
        xticks    = [   0,   pi/2,   pi, 3*pi/2]
        lct = MultipleLocator(10)
        minz = self[var].min()
        if minz < 0.0:
            if not maxz:
                maxz = max([abs(minz),self[var].max()])
            crange = Normalize(vmin=-1.*maxz, vmax=maxz)
            levs = linspace(-1.*maxz, maxz, n)
        else:
            if not maxz:
                maxz = self[var].max()
            crange = Normalize(vmin=0., vmax=maxz)
            levs = linspace(0., maxz, n)

        # Get color map if not given:
        if not cmap:
            if self[var].min() >= 0.0:
                cmap=get_iono_cb('wr')
            else:
                cmap=get_iono_cb('bwr')

        # Set the latitude based on hemisphere:
        theta = self[hemi+'theta']
        if 's_' in hemi: theta = 180-self[hemi+'theta']

        # Create contour:
        cnt1 = ax.contourf(self[hemi+'psi']*pi/180.0+pi/2., theta,
                           np.array(self[var]), levs, norm=crange, cmap=cmap)
        # Set xtick label size, increase font of top label.
        labels = ax.get_xticklabels()
        for l in labels: l.set_size(xticksize)
        labels[1].set_size(xticksize*1.25)
        
        if lines:
            nk = int(round(n/3.0))
            cnt2 = ax.contour(self[hemi+'psi']*pi/180.0+pi/2., theta,
                              np.array(self[var]), nk, colors='k')
            #clabel(cnt2,fmt='%3i',fontsize=10)

        if add_cbar:
            cbarticks = MaxNLocator(7)
            cbar = colorbar(cnt1, ticks=cbarticks, shrink=0.75, pad=0.08)
            cbar.set_label(tex_label(self[var].attrs['units']))
        else:
            cbar=False
        ax.set_xticks(xticks)
        ax.set_xticklabels(lt_labels)
        ax.yaxis.set_major_locator(lct)
        ax.set_ylim([0,40])

        # Use text function to manually add pretty ticks.
        ax.set_yticklabels('') # old ticks off.
        opts = {'size':yticksize, 'rotation':-45, 'ha':'center', 'va':'center'}
        for theta in [80.,70.,60.]:
            txt = '{:02.0f}'.format(theta)+r'$^{\circ}$'
            ax.text(pi/4., 90.-theta, txt, color='w', weight='heavy', **opts)
            ax.text(pi/4., 90.-theta, txt, color='k', weight='light', **opts)

        return fig, ax, cnt1, cbar
示例#15
0
文件: dgcpm.py 项目: yugidoge/spacepy
    def add_separatrix(self,
                       target=None,
                       loc=111,
                       Lmax=None,
                       title=None,
                       **kwargs):
        '''
        Attempts to locate the separatrix (separator between closed and
        open drift paths) by finding the minimum velocity in the domain and
        tracing the path of constant potential that passes through that point.
        The figure, axes, and contour object containing the separatrix line
        are returned to the user.

        If kwarg **target** is None (default), a new figure is 
        generated from scratch.  If target is a matplotlib Figure
        object, a new axis is created to fill that figure at subplot
        location **loc**.  If **target** is a matplotlib Axes object, 
        the plot is placed into that axis.

        Four values are returned: the matplotlib Figure and Axes objects,
        the matplotlib contour object, and the matplotlib colorbar object
        (defaults to *False* if not used.)

        Kwargs that set line characteristics behave in the typical matplotlib
        manner (i.e. "colors" can be set to either a color name or a 
        hexidecimal specifier.)

        =========== ==========================================================
        Kwarg       Description
        ----------- ----------------------------------------------------------
        target      Set plot destination.  Defaults to new figure.
        loc         Set subplot location.  Defaults to 111.
        linewidths  Set width of plotted line.  Defaults to 3.0.
        colors      Set color of line.  Defaults to 'orange'.
        linestyles  Set line style.  Defaults to 'dashed'.
        ----------- ----------------------------------------------------------
        
        '''

        from numpy import linspace, pi, sqrt
        import matplotlib.pyplot as plt

        # Set default line behavior.
        if 'linewidths' not in kwargs:
            kwargs['linewidths'] = 3.0
        if 'colors' not in kwargs:
            kwargs['colors'] = 'orange'
        if 'linestyles' not in kwargs:
            kwargs['linestyles'] = 'solid'

        # Set ax and fig based on given target.
        fig, ax = set_target(target, figsize=(10.5, 8), loc=loc, polar=True)
        doAdjust = not target == ax

        # Find the stagnation point by looking for E = 0.
        # Get the potential value at that spot.
        # Exclude near-boundary points and limit azimuthal extent.
        if 'E' not in self:
            self.calc_E()
        i = np.arange(self['L'].size)[self['L'] < 9.75]
        j = np.arange(self['lon'].size)[(self['lon'] > 250.)
                                        & (self['lon'] < 360.)]
        pmin = self['pot'][self['E'] == self['E'][i[0]:i[-1],
                                                  j[0]:j[-1]].min()][0]

        # Create a contour that only follows that potential curve.
        phi = np.concatenate((self['lon'], [360.0])) * pi / 180. - pi / 2.
        z = np.concatenate(
            (self['pot'], np.array([self['pot'][:, 0]]).transpose()), 1)
        cnt = ax.contour(phi, self['L'], z, levels=[pmin], **kwargs)

        # Adjust plot appropriately.
        if doAdjust:
            if not Lmax:
                # Default to inside ghost cells.
                Lmax = self['L'][-3]
                if title:
                    ax.set_title(title + '\n' + self.attrs['time'].isoformat(),
                                 position=(0, 1),
                                 ha='left',
                                 size=14)
            _adjust_dialplot(ax, Lmax, labelsize=14)

        # Return bits to user.
        return fig, ax, cnt
示例#16
0
    def plotSummary(self,
                    timerange=None,
                    coord_sys=None,
                    fig_target=None,
                    spec=False,
                    orbit_params=(False, True),
                    **kwargs):
        """Generate summary plot of AE9/AP9/SPM data loaded
        
        spec : if True, plot spectrogram instead of flux/fluence lineplot, requires 'ecol' keyword
        """
        if timerange:
            if isinstance(timerange, spt.Ticktock):
                t1 = timerange.UTC[0]
                t2 = timerange.UTC[-1]
            elif isinstance(timerange[0], dt.datetime):
                t1 = timerange[0]
                t2 = timerange[-1]
            else:
                raise TypeError('Incorrect data type provided for timerange')
            # now select subset
            i_use = tb.tOverlapHalf([t1, t2], self['Epoch'])
            t_use = self['Epoch'][i_use]
            c_use = self['Coords'][i_use]
            f_use = self[self.attrs['varname']][i_use, ...]
        else:
            t_use = self['Epoch']
            c_use = self['Coords']
            f_use = self[self.attrs['varname']]

        if coord_sys and (coord_sys.upper() != c_use.attrs['COORD_SYS']):
            # TODO: We assume cartesian, make flexible so can take spherical
            cx = spc.Coords(c_use, c_use.attrs['COORD_SYS'], 'car')
            cx.ticks = spt.Ticktock(t_use)
            cx = cx.convert(coord_sys.upper(), 'car').data
        else:
            coord_sys = c_use.attrs['COORD_SYS']
            cx = c_use
        sys_subs = r'$_{' + coord_sys + r'}$'

        splot.style('spacepy')
        if orbit_params[0]:
            landscape = orbit_params[1]
            locs = [121, 122] if landscape else [211, 212]
        else:
            locs = [223, 224]
            landscape = True
        if fig_target:
            fig, ax1 = splot.set_target(fig_target, loc=locs[0])
        else:
            fig, ax1 = splot.set_target(fig_target,
                                        figsize=(8, 8),
                                        loc=locs[0])
        fig, ax2 = splot.set_target(fig, loc=locs[1])

        ax1 = self._makeOrbitAxis(cx[:, 0], cx[:, 1], ax1)
        ax2 = self._makeOrbitAxis(cx[:, 0], cx[:, 2], ax2)
        if landscape:
            ax1.set_xlabel('X{0} [{1}]'.format(sys_subs,
                                               self['Coords'].attrs['UNITS']))
        ax2.set_xlabel('X{0} [{1}]'.format(sys_subs,
                                           self['Coords'].attrs['UNITS']))
        ax1.set_ylabel('Y{0} [{1}]'.format(sys_subs,
                                           self['Coords'].attrs['UNITS']))
        ax2.set_ylabel('Z{0} [{1}]'.format(sys_subs,
                                           self['Coords'].attrs['UNITS']))
        ax1xl, ax1yl, ax2xl, ax2yl = ax1.get_xlim(), ax1.get_ylim(
        ), ax2.get_xlim(), ax2.get_ylim()
        maxabslim = np.max(np.abs([ax1xl, ax1yl, ax2xl, ax2yl]))
        if np.abs((ax1.get_xlim()[1] - ax1.get_xlim()[0])) < 1:
            refpt = maxabslim
            ax1.set_xlim([-1.25 * refpt, 1.25 * refpt])
            ax1.set_ylim(ax1.get_xlim())
            refpt = ax2.get_xlim()[0]
            ax2.set_xlim([-1.25 * refpt, 1.25 * refpt])
            ax2.set_ylim(ax1.get_xlim())
        else:
            ax1.set_xlim([-maxabslim, maxabslim])
            ax1.set_ylim([-maxabslim, maxabslim])
            ax2.set_xlim([-maxabslim, maxabslim])
        ax2.set_ylim(ax2.get_xlim())
        ax1.invert_yaxis()
        ax1.invert_xaxis()
        ax2.invert_xaxis()
        ax1.set_aspect('equal')
        ax2.set_aspect('equal')

        if not orbit_params[0]:
            ax3 = splot.plt.subplot2grid((2, 2), (0, 0), colspan=2)
            if not spec:
                l3 = ax3.semilogy(t_use, f_use)
                ylab = '{0} ['.format(self.attrs['varname']) + re.sub(
                    '(\^[\d|-]*)+', _grp2mathmode,
                    self[self.attrs['varname']].attrs['UNITS']) + ']'
                ax3.set_ylabel(ylab)
                for ll, nn in zip(l3, self['Energy']):
                    ll.set_label('{0} {1}'.format(
                        nn, self['Energy'].attrs['UNITS']))
                ncol = len(self['Energy']) // 2 if len(
                    self['Energy']) <= 6 else 3
                leg = ax3.legend(loc='center',
                                 bbox_to_anchor=(0.5, 1),
                                 ncol=ncol,
                                 frameon=True,
                                 framealpha=0.5)
                lims3 = ax3.get_ylim()
                newupper = 10**(np.log10(lims3[0]) +
                                (np.log10(lims3[1] / lims3[0]) * 1.125))
                ax3.set_ylim([lims3[0], newupper])
                splot.applySmartTimeTicks(ax3, t_use)
                fig.tight_layout()
                pos3 = ax3.get_position()
                ax3.set_position(
                    [pos3.x0, pos3.y0, pos3.width, pos3.height * 0.8])
                # fig.suptitle('{model_type}\n'.format(**self.attrs) +
                #             '{0} - {1}'.format(t_use[0].isoformat()[:19], t_use[-1].isoformat()[:19]))
            else:
                if timerange:
                    raise NotImplementedError(
                        'Time range selection not yet implemented for spectrograms'
                    )
                pos3 = ax3.get_position()
                ax3.set_position(
                    [pos3.x0, pos3.y0, pos3.width, pos3.height * 0.9])
                ecol = kwargs['ecol'] if 'ecol' in kwargs else 0
                ax3 = self.plotSpectrogram(target=ax3, ecol=ecol)
                splot.plt.subplots_adjust(wspace=0.3)
                pos1 = ax1.get_position()
                ax1.set_position([pos3.x0, pos1.y0, pos1.width, pos1.height])

        splot.revert_style()
        return fig
示例#17
0
文件: dgcpm.py 项目: yugidoge/spacepy
    def add_ltut(self,
                 target=None,
                 loc=111,
                 cmap='Greens_r',
                 zlim=[1, 1000],
                 add_cbar=True,
                 clabel='Density $cm^{-3}$',
                 xlabel='full',
                 ylim=[4, 20],
                 title=None,
                 grid=True,
                 ntick=5):
        '''
        Plot log(density) as a contour against local time (y-axis) and
        universal time (x-axis) using the PyBats *target* method of other
        standard plotting methods.  Four items are returned: the Matplotlib
        Figure, Axes, Mesh, and ColorBar objects used (if cbar is set to
        **False**, the returned ColorBar object is simply set to **False**.)

        ========== =======================================================
        Kwarg      Description
        ---------- -------------------------------------------------------
        target     Select plot destination.  Defaults to new figure/axis.
        loc        The location of any generated subplots.  Default is 111.
        add_cbar   Toggles the automatic colorbar.  Default is**True**.
        cmap       Selects Matplotlib color table.  Defaults to *Greens_r*.
        zlim       Limits for z-axis.  Defaults to [0.1, 1000]
        ylim       Sets the MLT range on the y-axis.  Defaults to [4,20].
        clabel     Sets colorbar label.  Defaults to units.
        xlabel     Sets x-axis labels, use 'full', 'ticks', or **None**.
        title      Sets axis title; defaults to **None**.
        grid       Show white dotted grid?  Defaults to **True**
        ntick      Number of attempted cbar ticks.  Defaults to 5.
        ========== =======================================================
        
        '''

        import matplotlib.pyplot as plt
        from matplotlib.ticker import LogLocator, LogFormatterMathtext
        from matplotlib.colors import LogNorm

        # Set ax and fig based on given target.
        fig, ax = set_target(target, loc=loc)
        # Enforce values to be within limits.
        z = np.where(self['n'] > zlim[0], self['n'], 1.01 * zlim[0])
        z[z > zlim[1]] = zlim[1]

        # Create plot:
        mesh = ax.pcolormesh(self._dtime,
                             self._y,
                             z.transpose(),
                             cmap=plt.get_cmap(cmap),
                             norm=LogNorm(),
                             vmin=zlim[0],
                             vmax=zlim[-1])

        # Use LT ticks and markers on y-axis:
        ax.set_yticks([6, 12, 18])
        ax.set_yticklabels(['Dawn', 'Noon', 'Dusk'])
        ax.set_ylim(ylim)

        # White ticks, slightly thicker:
        ax.tick_params(axis='both', which='both', color='w', width=1.2)

        # Grid marks:
        if grid: ax.grid(c='w')

        if title: ax.set_title(title)
        if xlabel == 'full':
            # Both ticks and label.
            applySmartTimeTicks(ax, self['time'], dolabel=True)
        elif xlabel == 'ticks':
            # Ticks, but no date label.
            applySmartTimeTicks(ax, self['time'], dolabel=False)
        else:
            # A blank x-axis is often useful.
            applySmartTimeTicks(ax, self['time'], dolabel=False)
            ax.set_xticklabels('')
        # Add cbar as necessary:
        if add_cbar:
            #lct = LogLocator
            cbar = plt.colorbar(mesh, ax=ax, pad=0.01,
                                shrink=0.85)  #, ticks=lct)
            cbar.set_label(clabel)
        else:
            cbar = None

        return fig, ax, mesh, cbar
示例#18
0
    def add_histplot(self,
                     target=False,
                     loc=111,
                     label='Kyoto $K_{p}$',
                     time_range=None,
                     filled=False,
                     level_kwargs={},
                     **kwargs):
        '''
        Make a quick histogram-style plot of the Kp data.

        Returns
        =======
        fig : matplotlib figure object
        ax  : matplotlib axes object

        Other Parameters
        ================
        target : Figure or Axes
            If None (default), a new figure is generated from scratch.
            If a matplotlib Figure object, a new axis is created
            to fill that figure.
            If a matplotlib Axes object, the plot is placed
            into that axis.
        
        loc : int
            Use to specify the subplot placement of the axis
            (e.g. loc=212, etc.) Used if target is a Figure or None.
            Default 111 (single plot).

        label : string
            The label applied to the line when a legend is added to the axes.
            Defaults to 'Kyoto $K_{p}$'.

        time_range : tuple of datetimes
            The time range to plot.  Only the first and last values in the
            tuple (or list) are used if the number of elements is greater than
            two.  Defaults to **None**, meaning that the full time range
            available is used.

        filled : Boolean
            If True, make a filled 'traffic light' plot of Kp using
            spacepy.plot.levelPlot. Extra keyword arguments for levelPlot can
            be supplied via level_kwargs.

        Extra keyword arguments are passed to :function:`matplotlib.pyplot.plot`
        to customize the line style (and are ignored if filled is True).

        Examples
        ========
        >>> import matplotlib.pyplot as plt
        >>> import spacepy.pybats.kyoto as kt
         >>> kp = kt.fetch('kp', (1981, 11), (1981, 11))
        >>> kp.add_histplot(lw=2.0, color='r', label='Example Kp')
        >>> ax = plt.gca()
        >>> kp.add_histplot(filled=True)

        '''
        import matplotlib.pyplot as plt

        if not time_range:
            time_range = self['time']

        fig, ax = set_target(target, figsize=(10, 4), loc=loc)
        if not filled:
            tvar = self['binstart'].tolist()
            tvar.append(tvar[-1] + dt.timedelta(hours=3))
            kpvar = self['kp'].tolist()
            kpvar.append(kpvar[-1])
            line = ax.plot(tvar,
                           kpvar,
                           label=label,
                           drawstyle='steps-post',
                           **kwargs)
        else:
            ax = levelPlot(self,
                           time='binstart',
                           var='kp',
                           target=ax,
                           **level_kwargs)
        applySmartTimeTicks(ax, time_range, dolabel=True)

        return fig, ax
示例#19
0
文件: pwom.py 项目: aglocer/spacepy
    def plot_df(self,
                var,
                time,
                nlev=31,
                zlim=None,
                xlim=None,
                ylim=None,
                target=None,
                loc=111,
                title=None,
                add_cbar=True,
                clabel=None,
                show_pts=False,
                dolog=False,
                add_body=True,
                figsize=(8.34, 7),
                *args,
                **kwargs):
        '''
        Create a plot of variable *var* at a given time.

        If kwarg **target** is None (default), a new figure is 
        generated from scratch.  If target is a matplotlib Figure
        object, a new axis is created to fill that figure at subplot
        location **loc**.  If **target** is a matplotlib Axes object, 
        the plot is placed into that axis.
        '''

        import matplotlib.pyplot as plt
        from matplotlib.colors import (LogNorm, Normalize)
        from matplotlib.patches import Circle
        from matplotlib.ticker import (LogLocator, LogFormatter,
                                       LogFormatterMathtext, MultipleLocator)
        from matplotlib.patches import Wedge

        # Grab the slice of data that we want:
        if type(time) == type(self['time'][0]):
            if time not in self['time']:
                raise ValueError('Time not in object')
            time = np.arange(self.attrs['nTime'])[self['time'] == time][0]

        fig, ax = set_target(target, loc=loc, figsize=figsize)
        ax.set_aspect('equal')

        # Grab values from correct time/location.
        x = self['Vperp[cm/s]'][time, :]
        y = self['Vpar[cm/s]'][time, :]
        value = self[var][time, :]

        # Get max/min if none given.
        if zlim == None:
            zlim = [0, 0]
            zlim[0] = value.min()
            zlim[1] = value.max()
            if dolog and zlim[0] <= 0:
                zlim[0] = np.min([0.0001, zlim[1] / 1000.0])

        # Create levels and set norm based on dolog.
        if dolog:
            levs = np.power(
                10, np.linspace(np.log10(zlim[0]), np.log10(zlim[1]), nlev))
            z = np.where(value > zlim[0], value, 1.01 * zlim[0])
            norm = LogNorm()
            ticks = LogLocator()
            fmt = LogFormatterMathtext()
        else:
            levs = np.linspace(zlim[0], zlim[1], nlev)
            z = value
            norm = None
            ticks = None
            fmt = None

        # Create contour plot.
        cont=ax.tricontourf(np.asarray(x), np.asarray(y), np.asarray(z), \
                            np.asarray(levs), *args, norm=norm, **kwargs)
        if show_pts:
            ax.plot(x, y, '+w')

        if xlim != None:
            ax.set_xlim(xlim[0], xlim[1])

        if ylim != None:
            ax.set_ylim(ylim[0], ylim[1])

        # Add cbar if necessary.
        if add_cbar:
            cbar = plt.colorbar(cont, ticks=ticks, format=fmt, pad=0.01)
            if clabel == None:
                clabel = "%s" % (var)
            cbar.set_label(clabel)
        else:
            cbar = None  # Need to return something, even if none.

        # Set title, labels, axis ranges (use defaults where applicable.)
        if title: ax.set_title(title)
        #ax.set_yticks([]), ax.set_xticks([])
        ax.set_xlabel('Vpar [cm/s]')
        ax.set_ylabel('Vperp [cm/s]')

        return fig, ax, cont, cbar
示例#20
0
    def add_cont(self, var, target=None, n=24, maxz=False, lines=True, 
                 cmap=False, add_cbar=False, label=None, loc=111,
                 xticksize=12, yticksize=12, max_colat=40, **kwargs):
        '''
        Create a polar contour of variable *var*.  Plot will be either drawn
        on a new matplotlib figure and axes, or you can specify a plot target
        using the *target* kwarg.

        Parameters
        ==========
        var : str
           The name of the variable to plot.

        Returns
        =======
        fig : matplotlib figure object
        ax  : matplotlib axes object
        cnt : matplotlib contour object
        cb  : matplotlib colorbar object

        Other Parameters
        ================
        target : Figure or Axes
            If None (default), a new figure is generated from scratch.
            If a matplotlib Figure object, a new axis is created
            to fill that figure.
            If a matplotlib Axes object, the plot is placed
            into that axis.
        loc : int
            Use to specify the subplot placement of the axis
            (e.g. loc=212, etc.) Used if target is a Figure or None.
            Default 111 (single plot).
        n : int
            Set number of levels.  Should be a multiple of 3 for best match
            between filled and traced contours.  Default is 21.
        lines : bool
            Add unfilled black solid/dashed contours to plot for additional
            contrast.  Default is **True**.
        maxz : real
            Set the max/min value for the color bar.  Default is set by data.
        max_colat : real
            Set the co-latitude range of the plot, in degrees.  Defaults to 40.
        cmap : str
            Set the colormap.  Default is to autoselect using classic IE maps.
            Can be 'bwr', 'wr', or any name of a matplotlib colar map.
        add_cbar : bool
            Add colorbar to plot.  Default is **False** which will
            not add one to the plot.
        label : str or None
            Label to place at top of plot.  Defaults to variable name.
        xticksize : int
            Size of longitude markers in text points.  Defaults to 12.
        yticksize : int
            Size of latitude markers in text points.  Defaults to 12.

        Extra keywords are passed to the contourf routine.

        '''
        # Get only what we need to decrease runtime.
        from math import pi
        from numpy import linspace
        from matplotlib.colors import Normalize
        from matplotlib.ticker import MaxNLocator, MultipleLocator
        from matplotlib.pyplot import clabel, colorbar

        fig, ax = set_target(target, polar=True, loc=loc)
        
        hemi = var[:2]

        # user defined variables may not have hemisphere marking.
        # Assume nothern hemi in those cases.
        if hemi!='n_' and hemi!='s_': hemi = 'n_'

        # Set levels and ticks:
        if label==None:
            label=tex_label(var)
        lt_labels = ['06',    label, '18',   '00']
        xticks    = [   0,   pi/2,   pi, 3*pi/2]
        lct = MultipleLocator(10)
        minz = self[var].min()
        if minz < 0.0:
            if not maxz:
                maxz = max([abs(minz),self[var].max()])
            crange = Normalize(vmin=-1.*maxz, vmax=maxz)
            levs = linspace(-1.*maxz, maxz, n)
        else:
            if not maxz:
                maxz = self[var].max()
            crange = Normalize(vmin=0., vmax=maxz)
            levs = linspace(0., maxz, n)

        # Get color map if not given:
        if not cmap:
            if self[var].min() >= 0.0:
                cmap=get_iono_cb('wr')
            else:
                cmap=get_iono_cb('bwr')

        # Set the latitude based on hemisphere:
        theta = self[hemi+'theta']
        if 's_' in hemi: theta = 180-self[hemi+'theta']

        # Create contour:
        cnt1 = ax.contourf(self[hemi+'psi']*pi/180.0+pi/2., theta,
                           np.array(self[var]), levs, norm=crange, cmap=cmap,
                           **kwargs)
        # Set xtick label size, increase font of top label.
        labels = ax.get_xticklabels()
        for l in labels: l.set_size(xticksize)
        labels[1].set_size(xticksize*1.25)
        
        if lines:
            nk = int(round(n/3.0))
            cnt2 = ax.contour(self[hemi+'psi']*pi/180.0+pi/2., theta,
                              np.array(self[var]), nk, colors='k')
            #clabel(cnt2,fmt='%3i',fontsize=10)

        if add_cbar:
            cbarticks = MaxNLocator(7)
            cbar = colorbar(cnt1, ticks=cbarticks, shrink=0.75, pad=0.08, ax=ax)
            cbar.set_label(tex_label(self[var].attrs['units']))
        else:
            cbar=False
        ax.set_xticks(xticks)
        ax.set_xticklabels(lt_labels)
        ax.yaxis.set_major_locator(lct)
        ax.set_ylim([0,max_colat])

        # Use text function to manually add pretty ticks.
        ax.set_yticklabels('') # old ticks off.
        opts = {'size':yticksize, 'rotation':-45, 'ha':'center', 'va':'center'}
        for theta in [80.,70.,60.]:
            txt = '{:02.0f}'.format(theta)+r'$^{\circ}$'
            ax.text(pi/4., 90.-theta, txt, color='w', weight='heavy', **opts)
            ax.text(pi/4., 90.-theta, txt, color='k', weight='light', **opts)

        return fig, ax, cnt1, cbar
示例#21
0
文件: ae9ap9.py 项目: spacepy/spacepy
    def plotSummary(self, timerange=None, coord_sys=None, fig_target=None, spec=False, orbit_params=(False, True),
                    **kwargs):
        """Generate summary plot of AE9/AP9/SPM data loaded
        
        spec : if True, plot spectrogram instead of flux/fluence lineplot, requires 'ecol' keyword
        """
        if timerange:
            if isinstance(timerange, spt.Ticktock):
                t1 = timerange.UTC[0]
                t2 = timerange.UTC[-1]
            elif isinstance(timerange[0], dt.datetime):
                t1 = timerange[0]
                t2 = timerange[-1]
            else:
                raise TypeError('Incorrect data type provided for timerange')
            # now select subset
            i_use = tb.tOverlapHalf([t1, t2], self['Epoch'])
            t_use = self['Epoch'][i_use]
            c_use = self['Coords'][i_use]
            f_use = self[self.attrs['varname']][i_use, ...]
        else:
            t_use = self['Epoch']
            c_use = self['Coords']
            f_use = self[self.attrs['varname']]

        if coord_sys and (coord_sys.upper() != c_use.attrs['COORD_SYS']):
            # TODO: We assume cartesian, make flexible so can take spherical
            cx = spc.Coords(c_use, c_use.attrs['COORD_SYS'], 'car')
            cx.ticks = spt.Ticktock(t_use)
            cx = cx.convert(coord_sys.upper(), 'car').data
        else:
            coord_sys = c_use.attrs['COORD_SYS']
            cx = c_use
        sys_subs = r'$_{' + coord_sys + r'}$'

        splot.style('spacepy')
        if orbit_params[0]:
            landscape = orbit_params[1]
            locs = [121, 122] if landscape else [211, 212]
        else:
            locs = [223, 224]
            landscape = True
        if fig_target:
            fig, ax1 = splot.set_target(fig_target, loc=locs[0])
        else:
            fig, ax1 = splot.set_target(fig_target, figsize=(8, 8), loc=locs[0])
        fig, ax2 = splot.set_target(fig, loc=locs[1])

        ax1 = self._makeOrbitAxis(cx[:, 0], cx[:, 1], ax1)
        ax2 = self._makeOrbitAxis(cx[:, 0], cx[:, 2], ax2)
        if landscape: ax1.set_xlabel('X{0} [{1}]'.format(sys_subs, self['Coords'].attrs['UNITS']))
        ax2.set_xlabel('X{0} [{1}]'.format(sys_subs, self['Coords'].attrs['UNITS']))
        ax1.set_ylabel('Y{0} [{1}]'.format(sys_subs, self['Coords'].attrs['UNITS']))
        ax2.set_ylabel('Z{0} [{1}]'.format(sys_subs, self['Coords'].attrs['UNITS']))
        ax1xl, ax1yl, ax2xl, ax2yl = ax1.get_xlim(), ax1.get_ylim(), ax2.get_xlim(), ax2.get_ylim()
        maxabslim = np.max(np.abs([ax1xl, ax1yl, ax2xl, ax2yl]))
        if np.abs((ax1.get_xlim()[1] - ax1.get_xlim()[0])) < 1:
            refpt = maxabslim
            ax1.set_xlim([-1.25 * refpt, 1.25 * refpt])
            ax1.set_ylim(ax1.get_xlim())
            refpt = ax2.get_xlim()[0]
            ax2.set_xlim([-1.25 * refpt, 1.25 * refpt])
            ax2.set_ylim(ax1.get_xlim())
        else:
            ax1.set_xlim([-maxabslim, maxabslim])
            ax1.set_ylim([-maxabslim, maxabslim])
            ax2.set_xlim([-maxabslim, maxabslim])
        ax2.set_ylim(ax2.get_xlim())
        ax1.invert_yaxis()
        ax1.invert_xaxis()
        ax2.invert_xaxis()
        ax1.set_aspect('equal')
        ax2.set_aspect('equal')

        if not orbit_params[0]:
            ax3 = splot.plt.subplot2grid((2, 2), (0, 0), colspan=2)
            if not spec:
                l3 = ax3.semilogy(t_use, f_use)
                ylab = '{0} ['.format(self.attrs['varname']) + re.sub('(\^[\d|-]*)+', _grp2mathmode,
                                                                      self[self.attrs['varname']].attrs['UNITS']) + ']'
                ax3.set_ylabel(ylab)
                for ll, nn in zip(l3, self['Energy']):
                    ll.set_label('{0} {1}'.format(nn, self['Energy'].attrs['UNITS']))
                ncol = len(self['Energy']) // 2 if len(self['Energy']) <= 6 else 3
                leg = ax3.legend(loc='center', bbox_to_anchor=(0.5, 1), ncol=ncol,
                                 frameon=True, framealpha=0.5)
                lims3 = ax3.get_ylim()
                newupper = 10 ** (np.log10(lims3[0]) + (np.log10(lims3[1] / lims3[0]) * 1.125))
                ax3.set_ylim([lims3[0], newupper])
                splot.applySmartTimeTicks(ax3, t_use)
                fig.tight_layout()
                pos3 = ax3.get_position()
                ax3.set_position([pos3.x0, pos3.y0, pos3.width, pos3.height * 0.8])
                # fig.suptitle('{model_type}\n'.format(**self.attrs) +
                #             '{0} - {1}'.format(t_use[0].isoformat()[:19], t_use[-1].isoformat()[:19]))
            else:
                if timerange: raise NotImplementedError('Time range selection not yet implemented for spectrograms')
                pos3 = ax3.get_position()
                ax3.set_position([pos3.x0, pos3.y0, pos3.width, pos3.height * 0.9])
                ecol = kwargs['ecol'] if 'ecol' in kwargs else 0
                ax3 = self.plotSpectrogram(target=ax3, ecol=ecol)
                splot.plt.subplots_adjust(wspace=0.3)
                pos1 = ax1.get_position()
                ax1.set_position([pos3.x0, pos1.y0, pos1.width, pos1.height])

        splot.revert_style()
        return fig
示例#22
0
文件: pwom.py 项目: spacepy/spacepy
    def add_slice(self, var, alt, time, nlev=31, zlim=None, target=None, 
                  loc=111, title=None, latoffset=1.05,
                  rlim=50., add_cbar=True, clabel=None,
                  show_pts=False, show_alt=True, dolog=False, 
                  lats=[75., 60.], colats=None, figsize=(8.34,7),
                  *args, **kwargs):
        '''
        Create a plot of variable *var* at altitude *alt*.

        If kwarg **target** is None (default), a new figure is 
        generated from scratch.  If target is a matplotlib Figure
        object, a new axis is created to fill that figure at subplot
        location **loc**.  If **target** is a matplotlib Axes object, 
        the plot is placed into that axis.
        '''

        import matplotlib.pyplot as plt
        from matplotlib.colors import (LogNorm, Normalize)
        from matplotlib.patches import Circle
        from matplotlib.ticker import (LogLocator, LogFormatter, 
                                       LogFormatterMathtext, MultipleLocator)

        # Grab the slice of data that we want:
        if type(time) == type(self['time'][0]):
            if time not in self['time']:
                raise ValueError('Time not in object')
            time = np.arange(self.attrs['nTime'])[self['time']==time][0]

        fig, ax = set_target(target, loc=loc, figsize=figsize)
        ax.set_aspect('equal')

        # Create values in Cartesian plane.
        self._get_cartXY()

        # Grab values from correct time/location.
        x = self._xLat[:,time, alt]
        y = self._yLat[:,time, alt]
        value = self[var][:, time, alt]

        # Get max/min if none given.
        if zlim==None:
            zlim=[0,0]
            zlim[0]=value.min(); zlim[1]=value.max()
            if dolog and zlim[0]<=0:
                zlim[0] = np.min( [0.0001, zlim[1]/1000.0] )

        # Create levels and set norm based on dolog.
        if dolog:
            levs = np.power(10, np.linspace(np.log10(zlim[0]), 
                                            np.log10(zlim[1]), nlev))
            z=np.where(value>zlim[0], value, 1.01*zlim[0])
            norm=LogNorm()
            ticks=LogLocator()
            fmt=LogFormatterMathtext()
        else:
            levs = np.linspace(zlim[0], zlim[1], nlev)
            z=value
            norm=None
            ticks=None
            fmt=None
        
        # Create contour plot.
        cont=ax.tricontourf(x, y, z, levs, *args, norm=norm, **kwargs)
        
        # Label altitude.
        if show_alt:
            ax.text(0.05, 0.05, r'Alt.={:.1f}$km/s$ ({:.2f}$R_E$)'.format(
                self['r'][alt], self['r'][alt]/6371.0+1), size=12, 
                    transform=ax.transAxes, bbox={'fc':'white', 'ec':'k'})

        if show_pts:
            ax.plot(x, y, '+w')

        # Add cbar if necessary.
        if add_cbar:
            cbar=plt.colorbar(cont, ticks=ticks, format=fmt, pad=0.01)
            if clabel==None: 
                clabel="%s (%s)" % (var, self[var].attrs['units'])
            cbar.set_label(clabel)
        else:
            cbar=None # Need to return something, even if none.
 
        # Set title, labels, axis ranges (use defaults where applicable.)
        if title: ax.set_title(title)
        ax.set_yticks([]), ax.set_xticks([])
        ax.set_ylabel(r'Sun $\rightarrow$')
        colat_lim = 90.-rlim
        ax.set_xlim([-1*colat_lim, colat_lim])
        ax.set_ylim([-1*colat_lim, colat_lim])

        if colats:
            for colat in colats:
                r = latoffset*colat/np.sqrt(2)
                ax.add_patch(Circle([0,0],colat,fc='none',ec='k',ls='dashed'))
                ax.text(r, r, '{:.0f}'.format(colat)+r'$^{\circ}$',
                        rotation=315,ha='center', va='center')
        else:
            for lat in lats:
                colat = 90 - lat
                r = latoffset*colat/np.sqrt(2)
                ax.add_patch(Circle([0,0],colat,fc='none',ec='k',ls='dashed'))
                ax.text(r, r, '{:.0f}'.format(lat)+r'$^{\circ}$', 
                        rotation=315,ha='center', va='center')
                

        return fig, ax, cont, cbar