Source code for pyaerocom.vertical_profile

from typing import Optional

import matplotlib.pyplot as plt
import numpy as np
import numpy.typing as npt

from pyaerocom._lowlevel_helpers import BrowseDict


[docs] class VerticalProfile: """Object representing single variable profile data""" def __init__( self, data: npt.ArrayLike, altitude: npt.ArrayLike, dtime, var_name: str, data_err: Optional[npt.ArrayLike], var_unit: str, altitude_unit: str, ): self.var_name = var_name self.dtime = dtime self.data = data self.data_err = data_err self.altitude = altitude self.var_info = BrowseDict() self.var_info["altitude"] = dict(units=altitude_unit) self.var_info[self.var_name] = dict(units=var_unit) # Guard against having data (and data errors) with missing asociated altitude info if hasattr(self.data_err, "__len__"): assert len(self.data) == len(self.data_err) == len(self.altitude) else: assert len(self.data) == len(self.altitude) @property def data(self): """Array containing data values corresponding to data""" return self._data @data.setter def data(self, val): if isinstance(val, list): val = np.asarray(val) self._data = val @property def data_err(self): """Array containing data values corresponding to data""" return self._data_err @data_err.setter def data_err(self, val): if isinstance(val, list): val = np.asarray(val) self._data_err = val @property def altitude(self): """Array containing altitude values corresponding to data""" return self._altitude @altitude.setter def altitude(self, val): if isinstance(val, list): val = np.asarray(val) self._altitude = val # ToDo: complete docstring
[docs] def plot( self, plot_errs=True, whole_alt_range=False, rot_xlabels=30, errs_shaded=True, errs_alpha=0.1, add_vertbar_zero=True, figsize=None, ax=None, **kwargs, ): # pragma: no cover """Simple plot method for vertical profile""" if figsize is None: figsize = (4, 8) if ax is None: _, ax = plt.subplots(1, 1, figsize=figsize) p = ax.plot(self.data, self.altitude, "-x", **kwargs) c = p[0].get_color() if rot_xlabels: for lbl in ax.get_xticklabels(): lbl.set_rotation(rot_xlabels) unit = self.var_info[self.var_name]["units"] aunit = self.var_info["altitude"]["units"] xlab = f"{self.var_name} [{unit}]" ylab = f"Altitude [{aunit}]" ax.set_xlabel(xlab) ax.set_ylabel(ylab) if whole_alt_range: ax.set_ylim([np.min([0, self.altitude.min()]), self.altitude.max()]) if plot_errs: lower = self.data - self.data_err upper = self.data + self.data_err if errs_shaded: ax.fill_betweenx(self.altitude, lower, upper, color=c, alpha=errs_alpha) else: ax.errorbar( self.data, self.altitude, xerr=self.data_err, ls=" ", marker=" ", color="#cccccc", ) if add_vertbar_zero: xl = ax.get_xlim() if xl[0] < 0 < xl[1]: ax.plot([0, 0], ax.get_ylim(), "--", color="#cccccc") ax.figure.tight_layout() return ax