def testClosestValAbove(self): val = util.closest_val(20., self.array) assert val == 2
def testClosestValInternalNegative(self): val = util.closest_val(-3.5, -1 * self.array) assert val == 1
def testClosestValInternal(self): val = util.closest_val(3.5, self.array) assert val == 1
def testClosestValBelow(self): val = util.closest_val(-5., self.array) assert val == 0
def testValueErrorOnEmptyArray(self): util.closest_val(1., np.array([]))
def testClosestValSingle(self): val = util.closest_val(1., np.array([50.])) assert val == 0
def testValueErrorOnEmptyList(self): util.closest_val(1., [])
def testClosestValAboveList(self): val = util.closest_val(20., self.list) assert val == 2
def testClosestValBelowList(self): val = util.closest_val(-5., self.list) assert val == 0
def testClosestValInternalList(self): val = util.closest_val(3.5, self.list) assert val == 1
def plot_moist_adiabats(self, p=None, thetaes=None, **kwargs): r'''Plot moist adiabats. Adds saturated pseudo-adiabats (lines of constant equivalent potential temperature) to the plot. The default style of these lines is dashed blue lines with an alpha value of 0.5. These can be overridden using keyword arguments. Parameters ---------- p : array_like, optional 1-dimensional array of pressure values to be included in the moist adiabats. If not specified, they will be linearly distributed across the current plotted pressure range. thetaes : array_like, optional 1-dimensional array of saturation equivalent potential temperature values for moist adiabats. By default these will be generated based on the current temperature limits. kwargs Other keyword arguments to pass to `matplotlib.collections.LineCollection` See Also -------- plot_dry_adiabats `matplotlib.collections.LineCollection` `metpy.calc.moist_lapse` ''' for artist in self._moist_adiabats: artist.remove() self._moist_adiabats = [] thetaes = thetaes # port workaround, can refactor at any time def dT_dp(y, p0): return calculate( 'Gammam', T=y, p=p0, RH=100., p_units='hPa', T_units='degC') / (g0 * calculate( 'rho', T=y, p=p0, p_units='hPa', T_units='degC', RH=100.)) * 100. if thetaes is None and p is None: if (self.get_xlim() == self.default_xlim and self.get_ylim() == self.default_ylim): data = np.load( resource_filename(__name__, 'data/default_moist_adiabat_data.npz')) p = data['p'] thetaes = data['t0'] t = data['t'] else: # Determine set of starting temps if necessary if thetaes is None: xmin, xmax = self.get_xlim() thetaes = np.concatenate( (np.arange(xmin, 0, 5), np.arange(0, xmax + 51, 5))) # Get pressure levels based on ylims if necessary if p is None: p = np.linspace(*self.get_ylim()) thetaes_base = odeint(dT_dp, thetaes, np.array([1e3, p[0]], dtype=np.float64))[-1, :] # Assemble into data for plotting result = odeint(dT_dp, thetaes_base, p) t = result.T linedata = [np.vstack((ti, p)).T for ti in t] # Add to plot kwargs.setdefault('colors', '#166916') kwargs.setdefault('linestyles', '-') kwargs.setdefault('alpha', 1) kwargs.setdefault('linewidth', 0.5) kwargs.setdefault('zorder', 1.1) collection = LineCollection(linedata, **kwargs) self._moist_adiabats.append(collection) self.add_collection(collection) label_index = closest_val(240., p) T_label = t[:, label_index].flatten() for i in range(len(thetaes)): t = self.text(T_label[i], p[label_index], '{:.0f}'.format(thetaes[i]), fontsize=8, ha='left', va='center', rotation=-65, color='#166916', bbox={ 'facecolor': 'w', 'edgecolor': 'w', 'alpha': 0, }, zorder=1.2) t.set_clip_on(True) self._moist_adiabats.append(t)