Beispiel #1
0
def profile_p(p, x, ax=None, **kwargs):
    """Plot atmospheric profile against pressure in linear space.

    Parameters:
        p (ndarray): Pressure [Pa].
        x (ndarray): Atmospheric property.
        ax (AxesSubplot): Axes to plot in.
        **kwargs: Additional keyword arguments passed to `plt.plot`.

    See also:
            :func:`~typhon.plots.profile_p_log`
                Plot profile against pressure in log space.
            :func:`~typhon.plots.profile_z`
                Plot profile against height.

    Examples:

    .. plot::
        :include-source:

        import numpy as np
        import matplotlib.pyplot as plt
        import typhon.plots

        p = typhon.math.nlogspace(1000e2, 0.1e2, 50)  # pressure in Pa.
        x = np.exp(p / p[0])

        fig, ax = plt.subplots()
        typhon.plots.profile_p(p, x, ax=ax)

        plt.show()

    """
    if ax is None:
        ax = plt.gca()

    # Label and format for yaxis.
    formatter.set_yaxis_formatter(formatter.HectoPascalFormatter(), ax=ax)
    if ax.get_subplotspec().is_first_col():
        ax.set_ylabel('Pressure [hPa]')

    # Actual plot.
    ret = ax.plot(x, p, **kwargs)

    if hasattr(ax.yaxis, 'set_inverted'):
        # Matplotlib >=3.1.0
        # In matplotlib==3.1.0 the yaxis has to be inverted after actual plot
        # (https://github.com/matplotlib/matplotlib/issues/14615)
        ax.yaxis.set_inverted(True)
    elif not ax.yaxis_inverted():
        # Matplotlib <=3.0.3
        ax.invert_yaxis()

    return ret
Beispiel #2
0
def profile_z(z, x, ax=None, **kwargs):
    """Plot atmospheric profile of arbitrary property against height (in km).

    Parameters:
        z (ndarray): Height [m].
        x (ndarray): Atmospheric property.
        ax (AxesSubplot): Axes to plot in.
        **kwargs: Additional keyword arguments passed to `plt.plot`.

    See also:
            :func:`~typhon.plots.profile_p`
                Plot profile against pressure in linear space.
            :func:`~typhon.plots.profile_p_log`
                Plot profile against pressure in log space.

    Examples:

    .. plot::
        :include-source:

        import numpy as np
        import matplotlib.pyplot as plt
        import typhon.plots

        z = np.linspace(0, 80e3, 50)
        x = np.sin(z / 5e3)

        fig, ax = plt.subplots()
        typhon.plots.profile_z(z, x, ax=ax)

        plt.show()
    """
    if ax is None:
        ax = plt.gca()

    # Determine min/max pressure of data in plot. The current axis limits are
    # also taken into account. This ensures complete data coverage when using
    # the function iteratively on the same axis.
    zmin = np.min((np.min(z), *ax.get_ylim()))
    zmax = np.max((np.max(z), *ax.get_ylim()))
    ax.set_ylim(zmin, zmax)

    # Label and format for yaxis.
    if ax.is_first_col():
        ax.set_ylabel('Height [km]')

    # Actual plot.
    ret = ax.plot(x, z, **kwargs)

    formatter.set_yaxis_formatter(formatter.ScalingFormatter('kilo', '{x:g}'),
                                  ax=ax)

    return ret
Beispiel #3
0
def profile_p(p, x, ax=None, **kwargs):
    """Plot atmospheric profile against pressure in linear space.

    Parameters:
        p (ndarray): Pressure [Pa].
        x (ndarray): Atmospheric property.
        ax (AxesSubplot): Axes to plot in.
        **kwargs: Additional keyword arguments passed to `plt.plot`.

    See also:
            :func:`~typhon.plots.profile_p_log`
                Plot profile against pressure in log space.
            :func:`~typhon.plots.profile_z`
                Plot profile against height.

    Examples:

    .. plot::
        :include-source:

        import numpy as np
        import matplotlib.pyplot as plt
        import typhon.plots

        p = typhon.math.nlogspace(1000e2, 0.1e2, 50)  # pressure in Pa.
        x = np.exp(p / p[0])

        fig, ax = plt.subplots()
        typhon.plots.profile_p(p, x, ax=ax)

        plt.show()

    """
    if ax is None:
        ax = plt.gca()

    # Determine min/max pressure of data in plot. The current axis limits are
    # also taken into account. This ensures complete data coverage when using
    # the function iteratively on the same axis.
    pmin = np.min((np.min(p), *ax.get_ylim()))
    pmax = np.max((np.max(p), *ax.get_ylim()))
    ax.set_ylim(pmax, pmin)  # implicitly invert yaxis

    # Label and format for yaxis.
    formatter.set_yaxis_formatter(formatter.HectoPascalFormatter(), ax=ax)
    if ax.is_first_col():
        ax.set_ylabel('Pressure [hPa]')

    # Actual plot.
    return ax.plot(x, p, **kwargs)
Beispiel #4
0
def profile_p_log(p, x, ax=None, **kwargs):
    """Plot atmospheric profile against pressure in log space.

    This function is a wrapper for :func:`~typhon.plots.profile_p`:
    The input values as well as additional keyword arguments are passed through
    and the yscale is set to "log".

    Parameters:
        p (ndarray): Pressure [Pa].
        x (ndarray): Atmospheric property.
        ax (AxesSubplot): Axes to plot in.
        **kwargs: Additional keyword arguments passed to `plt.plot`.

    See also:
            :func:`~typhon.plots.profile_p`
                Plot profile against pressure in linear space.
            :func:`~typhon.plots.profile_z`
                Plot profile against height.

    Examples:

    .. plot::
        :include-source:

        import numpy as np
        import matplotlib.pyplot as plt
        import typhon.plots

        p = typhon.math.nlogspace(1000e2, 0.1e2, 50)
        x = np.exp(p / p[0])

        fig, ax = plt.subplots()
        typhon.plots.profile_p_log(p, x, ax=ax)

        plt.show()

    """
    if ax is None:
        ax = plt.gca()

    # Call ``set_yscale`` before plot to prevent reset of axis inverting in
    # matplotlib 3.1.0 (https://github.com/matplotlib/matplotlib/issues/14620)
    ax.set_yscale('log')
    ret = profile_p(p, x, ax=ax, **kwargs)

    # Set logarithmic scale.
    formatter.set_yaxis_formatter(formatter.HectoPascalLogFormatter(), ax=ax)

    return ret
Beispiel #5
0
def plot_from_konrad_diff(variable,exps,exp_ref,
                          same=False,
                          delta=10,
                          delta_ref=5,
                          xrefline=0,
                          xrefline_ref=None,
                          title=None,
                          labels=None,
                          styles=None,
                          label_ref=None,
                          style_ref=None
                         ):
 """Plots variable profiles from several `konrad` experiments in relation to a
 given reference experiment.
 
 Parameters
 ----------
 
 variable       : str
                  Variable name in the output file.
 exps           : list
                  List of strings describing the paths to the output files.
 exp_ref        : str
                  String describing the path to the output file for the
                  reference experiment.
 same           : bool, optional
                  If `True`, profiles are plotted in the same pair of axes.
                  Otherwise, there are as many pairs of axes as profiles
                  (`False` is the default). Reference profile has always its own
                  pair of axes.
 delta          : scalar, optional
                  Offset added to the extrema of the data.
 delta_ref      : scalar, optional
                  Offset added to the extrema of the reference data.
 xrefline       : scalar, optional
                  If `same` is `True`, plots a vertical reference line at the
                  given scalar value. If `same` is `False`, plots vertical
                  reference lines at each axis. By default the lines are zero
                  lines.
 xrefline_ref   : scalar or `None` optional
                  Plots a vertical reference line at the given scalar value. If
                  `None`, no reference line is plotted: this is the default.
 title          : str or `None`, optional
                  An overarching title for the figure (`None` is the default).
 labels, styles : dict or `None`, optional
                  Dictionaries containing profile labels and line styles.
                  Usually created by zipping two lists, e.g.
                  `labels = dict(zip(exps,labels))`. The `styles` dictionaries
                  are passed as keyword arguments to the `plt.plot` function. If
                  `None`, one gets default styles and/or labels.
 label_ref      : str or `None`, optional
                  String containing reference profile label.
 style_ref      : dict or `None`, optional
                  Dictionary containing reference profile line styles.
 
 Returns
 -------
 
 fig            : matplotlib.Figure
                  Figure with the plots.
 axes           : matplotlib.Axes
                  Axes for the figure.
                  
 """
 
 (p,
  data,minimum_diff,maximum_diff,
  minimum_ref,maximum_ref
 ) = get_from_konrad_ref(variable,exps,exp_ref)            # Gets the data
 n = len(list(data.keys()))                                # Experiment count
 ext_exps = list(data.keys())                              # Experiment list
 
 width = 2                                                 # Width (two pairs)
 height = 5                                                # Height
 
 if same:
  
  fig = plt.figure(dpi=300,figsize=(width*2,height))
  axes = {
   "ref"  : fig.add_subplot(1,2,1),
   "diff" : fig.add_subplot(1,2,2)
  }
  
  for e in data:                                           # Plotting
   ax = axes["diff"]
   labelsd = labels
   stylesd = styles
   if e == exp_ref:
    ax = axes["ref"]
    labelsd = label_ref
    stylesd = style_ref
    if isinstance(label_ref,str):
     labelsd = { e : label_ref }
    if isinstance(style_ref,dict):
     stylesd = { e : style_ref }
   if labelsd == None:
    if stylesd == None:
     ax.plot(data[e],p)
    elif stylesd[e] == None:
     ax.plot(data[e],p)
    else:
     ax.plot(data[e],p,**stylesd[e])
   elif labelsd[e] == None:
    if stylesd == None:
     ax.plot(data[e],p)
    elif stylesd[e] == None:
     ax.plot(data[e],p)
    else:
     ax.plot(data[e],p,**stylesd[e])
   else:
    if stylesd == None:
     ax.plot(data[e],p,label=labelsd[e])
    elif stylesd[e] == None:
     ax.plot(data[e],p,label=labelsd[e])
    else:
     labels_and_styles=stylesd[e]
     labels_and_styles["label"]=labelsd[e]
     ax.plot(data[e],p,**labels_and_styles)
  
  for e in axes:
   ax=axes[e]
   
   ax.invert_yaxis()                                       # Settings for y-axes
   ax.set_yscale("log")
   if e != "ref":
    ax.tick_params(axis='y',which='both',labelleft=False)
   if e == "ref":
    formatter.set_yaxis_formatter(formatter.HectoPascalLogFormatter(),
                                  ax=ax)
    ax.tick_params(axis='y',which='both',labelsize=6)
    ax.set_ylabel(p_a,fontsize=6)
   
   if e != "ref":                                          # Settings for x-axes
    ax.set_xlim(minimum_diff - delta,maximum_diff + delta)
    ax.set_xlabel(Dvariable_label[variable],fontsize=6)
   if e == "ref":
    ax.set_xlim(minimum_ref - delta_ref,maximum_ref + delta_ref)
    ax.set_xlabel(variable_label[variable],fontsize=6)
   ax.tick_params(axis='x',which='both',labeltop=False,labelsize=6)
   
   ax.minorticks_off()                                     # Unsets minor ticks
   
   if e != "ref":                                          # Reference line
    ax.axvline(x=xrefline,lw=0.7,color=(0,0,0))
   if ( e == "ref" and xrefline_ref != None ):
    ax.axvline(x=xrefline_ref,lw=0.7,color=(0,0,0))
   
   if e != "ref":
    ax.legend(fontsize=5)                                  # Legend
   if ( e == "ref" and label_ref != None ):
    ax.set_title(label_ref,fontsize=5)
 
 else:
  
  fig = plt.figure(dpi=300,figsize=(width*n,height))
  axes = { ext_exps[i-1] : fig.add_subplot(1,n,i) for i in range(1,n+1) }
  
  for e in axes:                                           # Plotting
   ax = axes[e]
   labelsd = labels
   stylesd = styles
   if e == exp_ref:
    labelsd = label_ref
    stylesd = style_ref
    if isinstance(label_ref,str):
     labelsd = { e : label_ref }
    if isinstance(style_ref,dict):
     stylesd = { e : style_ref }
   if labelsd == None:
    if stylesd == None:
     ax.plot(data[e],p)
    elif stylesd[e] == None:
     ax.plot(data[e],p)
    else:
     ax.plot(data[e],p,**stylesd[e])
   elif labelsd[e] == None:
    if stylesd == None:
     ax.plot(data[e],p)
    elif stylesd[e] == None:
     ax.plot(data[e],p)
    else:
     ax.plot(data[e],p,**stylesd[e])
   else:
    if stylesd == None:
     ax.plot(data[e],p,label=labelsd[e])
    elif stylesd[e] == None:
     ax.plot(data[e],p,label=labelsd[e])
    else:
     labels_and_styles=stylesd[e]
     labels_and_styles["label"]=labelsd[e]
     ax.plot(data[e],p,**labels_and_styles)
     
   ax.invert_yaxis()                                       # Settings for y-axes
   ax.set_yscale("log")
   if e != exp_ref:
    ax.tick_params(axis='y',which='both',labelleft=False)
   if e == exp_ref:
    formatter.set_yaxis_formatter(formatter.HectoPascalLogFormatter(),
                                  ax=ax)
    ax.tick_params(axis='y',which='both',labelsize=6)
    ax.set_ylabel(p_a,fontsize=6)
   
   if e != exp_ref:                                        # Settings for x-axes
    ax.set_xlim(minimum_diff - delta,maximum_diff + delta)
   if e == exp_ref:
    ax.set_xlim(minimum_ref - delta_ref,maximum_ref + delta_ref)
   if e != exp_ref:
    ax.set_xlabel(Dvariable_label[variable],fontsize=6)
   if e == exp_ref:
    ax.set_xlabel(variable_label[variable],fontsize=6)
   ax.tick_params(axis='x',which='both',labeltop=False,labelsize=6)
   
   ax.minorticks_off()                                     # Unsets minor ticks
   
   if e != exp_ref:                                        # Reference line
    ax.axvline(x=xrefline,lw=0.7,color=(0,0,0))
   if ( e == exp_ref and xrefline_ref != None ):
    ax.axvline(x=xrefline_ref,lw=0.7,color=(0,0,0))
   
   if e != exp_ref:                                        # Set axes titles
    ax.set_title(labels[e],fontsize=5)
   if ( e == exp_ref and label_ref != None ):
    ax.set_title(label_ref,fontsize=5)
 
 if title != None:                                         # Title settings
  fig.suptitle(title,fontsize=5,y=0.95)
 
 fig.set_tight_layout("tight")                             # Other settings
 
 return (fig,axes)
Beispiel #6
0
def plot_from_konrad(variable,exps,
                     same=False,
                     delta=10,
                     xrefline=None,
                     title=None,
                     labels=None,
                     styles=None
                    ):
 """Plots variable profiles from several `konrad` experiments.
 
 Parameters
 ----------
 
 variable       : str
                  Variable name in the output file.
 exps           : list
                  List of strings describing the paths to the output files.
 same           : bool, optional
                  If `True`, profiles are plotted in the same pair of axes.
                  Otherwise, there are as many pairs of axes as profiles
                  (`False` is the default).
 delta          : scalar, optional
                  Offset added to the extrema of the data.
 xrefline       : scalar or `None`, optional
                  If `same` is `True`, plots a vertical reference line at the
                  given scalar value. If `same` is `False`, plots vertical
                  reference lines at each axis. If `None`, plots no vertical
                  reference lines (`None` is the default).
 title          : str or `None`, optional
                  An overarching title for the figure (`None` is the default).
 labels, styles : dict or `None`, optional
                  Dictionaries containing profile labels and line styles.
                  Usually created by zipping two lists, e.g.
                  `labels = dict(zip(exps,labels))`. The `styles` dictionaries
                  are passed as keyword arguments to the `plt.plot` function.
                  If `None`, one gets default styles and/or labels.
 
 Returns
 -------
 
 fig            : matplotlib.Figure
                  Figure with the plots.
 axes           : matplotlib.Axes
                  Axes for the figure.
                  
 """
 
 (p,data,minimum,maximum) = get_from_konrad(variable,exps) # Gets the data
 n = len(exps)                                             # Experiment count
 
 width = 1                                                 # Width (one pair)
 height = 5                                                # Height
 
 if same:
  
  fig = plt.figure(dpi=300,figsize=(3*width,height))
  axes = fig.add_subplot(1,1,1)
  
  for e in data:                                           # Plotting
   ax = axes
   if labels == None:
    if styles == None:
     ax.plot(data[e],p)
    elif styles[e] == None:
     ax.plot(data[e],p)
    else:
     ax.plot(data[e],p,**styles[e])
   elif labels[e] == None:
    if styles == None:
     ax.plot(data[e],p)
    elif styles[e] == None:
     ax.plot(data[e],p)
    else:
     ax.plot(data[e],p,**styles[e])
   else:
    if styles == None:
     ax.plot(data[e],p,label=labels[e])
    elif styles[e] == None:
     ax.plot(data[e],p,label=labels[e])
    else:
     labels_and_styles = styles[e]
     labels_and_styles["label"] = labels[e]
     ax.plot(data[e],p,**labels_and_styles)
  
  ax = axes
  ax.invert_yaxis()                                        # Settings for y-axis
  ax.set_yscale("log")
  formatter.set_yaxis_formatter(formatter.HectoPascalLogFormatter(),
                                ax=ax)
  ax.tick_params(axis='y',which='both',labelsize=6)
  ax.set_ylabel(p_a,fontsize=6)
  
  ax.set_xlim(minimum - delta,maximum + delta)             # Settings for x-axis
  ax.tick_params(axis='x',which='both',labeltop=False,labelsize=6)
  ax.set_xlabel(variable_label[variable],fontsize=6)
  
  ax.minorticks_off()                                      # Unsets minor ticks
  
  if xrefline != None:                                     # Reference line
   ax.axvline(x=xrefline,lw=0.7,color=(0,0,0))
  
  ax.legend(fontsize=5)                                    # Legend
 
 else:
  
  fig = plt.figure(dpi=300,figsize=(n*width,height))
  axes = { exps[i-1] : fig.add_subplot(1,n,i) for i in range(1,n+1) }
  
  for e in axes:                                           # Plotting
   ax = axes[e]
   if labels == None:
    if styles == None:
     ax.plot(data[e],p)
    elif styles[e] == None:
     ax.plot(data[e],p)
    else:
     ax.plot(data[e],p,**styles[e])
   elif labels[e] == None:
    if styles == None:
     ax.plot(data[e],p)
    elif styles[e] == None:
     ax.plot(data[e],p)
    else:
     ax.plot(data[e],p,**styles[e])
   else:
    if styles == None:
     ax.plot(data[e],p,label=labels[e])
    elif styles[e] == None:
     ax.plot(data[e],p,label=labels[e])
    else:
     labels_and_styles = styles[e]
     labels_and_styles["label"] = labels[e]
     ax.plot(data[e],p,**labels_and_styles)
   
   ax.invert_yaxis()                                       # Settings for y-axes
   ax.set_yscale("log")
   if e != exps[0]:
    ax.tick_params(axis='y',which='both',labelleft=False)
   if e == exps[0]:
    formatter.set_yaxis_formatter(formatter.HectoPascalLogFormatter(),
                                  ax=ax)
    ax.tick_params(axis='y',which='both',labelsize=6)
    ax.set_ylabel(p_a,fontsize=6)
   
   ax.set_xlim(minimum - delta,maximum + delta)            # Settings for x-axes
   ax.tick_params(axis='x',which='both',labeltop=False,labelsize=6)
   ax.set_xlabel(variable_label[variable],fontsize=6)
   
   ax.minorticks_off()                                     # Unsets minor ticks
   
   if xrefline != None:                                    # Reference line
    ax.axvline(x=xrefline,lw=0.7,color=(0,0,0))
    
   ax.set_title(labels[e],fontsize=5)                      # Sets axes titles
   
 if title != None:                                         # Title settings
  fig.suptitle(title,fontsize=5,y=0.95)
 
 fig.set_tight_layout("tight")                             # Other settings
 
 return (fig,axes)