Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,12 @@ matrix:
env:
- TASK="coverage"
- VERSIONS="git+git://github.com/hgrecco/pint@master#egg=pint git+git://github.com/pydata/xarray@master#egg=xarray"
- EXTRA_PACKAGES="$EXTRA_PACKAGES setuptools_scm[toml]"
- python: "3.8-dev"
env:
- TASK="docs"
- VERSIONS="git+git://github.com/hgrecco/pint@master#egg=pint git+git://github.com/pydata/xarray@master#egg=xarray"
- EXTRA_PACKAGES="$EXTRA_PACKAGES setuptools_scm[toml]"
allow_failures:
- python: "3.8-dev"
- python: nightly
Expand Down
2 changes: 1 addition & 1 deletion docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -143,4 +143,4 @@ Related Projects
.. _netCDF: https://www.unidata.ucar.edu/software/netcdf/
.. _siphon: https://unidata.github.io/siphon/
.. _Unidata Python Gallery: https://unidata.github.io/python-training/gallery/gallery-home
__ https://www.unidata.ucar.edu/software/thredds/current/tds/
__ https://www.unidata.ucar.edu/software/tds/current/
11 changes: 6 additions & 5 deletions docs/references.rst
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,8 @@ References
doi:`10.1175/1520-0426(1987)004%3C0239:DOTPCO%3E2.0.CO;2
<https://doi.org/10.1175/1520-0426(1987)004%3C0239:DOTPCO%3E2.0.CO;2>`_.

.. [FCMR192003] Federal Coordinator for Meteorological Services and Supporting Research: Report on
Wind Chill Temperature and Extreme Heat Indices: Evaluation and Improvement
.. [FCMR192003] Federal Coordinator for Meteorological Services and Supporting Research: Report
on Wind Chill Temperature and Extreme Heat Indices: Evaluation and Improvement
Projects. Washington, DC: Office of the Federal Coordinator for Meteorological
Services and Supporting Research, 2003.
`FCM-R19-2003 <_static/FCM-R19-2003-WindchillReport.pdf>`_, 75 pp.
Expand All @@ -92,7 +92,8 @@ References
.. [Garratt1994] Garratt, J.R., 1994: *The Atmospheric Boundary Layer*. Cambridge
University Press, 316 pp.

.. [Holton2004] Holton, J. R., 2004: *An Introduction to Dynamic Meteorology*. 4th ed. Academic Press, 535 pp.
.. [Holton2004] Holton, J. R., 2004: *An Introduction to Dynamic Meteorology*. 4th ed.
Academic Press, 535 pp.

.. [Koch1983] Koch, S. E., M. DesJardins, and P. J. Kocin, 1983: An interactive Barnes
objective map analysis scheme for use with satellite and conventional data.
Expand Down Expand Up @@ -122,8 +123,8 @@ References
.. [Rochette2006] Rochette, Scott M., and Patrick S. Market. "A primer on the
ageostrophic wind." Natl. Weather Dig. 30 (2006): 17-28.

.. [Rothfusz1990] Rothfusz, L.P.: *The Heat Index "Equation"*. Fort Worth, TX: Scientific Services
Division, NWS Southern Region Headquarters, 1990.
.. [Rothfusz1990] Rothfusz, L.P.: *The Heat Index "Equation"*. Fort Worth, TX: Scientific
Services Division, NWS Southern Region Headquarters, 1990.
`SR90-23 <_static/rothfusz-1990-heat-index-equation.pdf>`_, 2 pp.

.. [Salby1996] Salby, M. L., 1996: *Fundamentals of Atmospheric Physics*.
Expand Down
12 changes: 6 additions & 6 deletions examples/meteogram_metpy.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,10 @@ def plot_winds(self, ws, wd, wsmax, plot_range=None):
ax7.set_ylabel('Wind\nDirection\n(degrees)', multialignment='center')
ax7.set_ylim(0, 360)
ax7.set_yticks(np.arange(45, 405, 90), ['NE', 'SE', 'SW', 'NW'])
lns = ln1 + ln2 + ln3
labs = [l.get_label() for l in lns]
lines = ln1 + ln2 + ln3
labs = [line.get_label() for line in lines]
ax7.xaxis.set_major_formatter(mpl.dates.DateFormatter('%d/%H UTC'))
ax7.legend(lns, labs, loc='upper center',
ax7.legend(lines, labs, loc='upper center',
bbox_to_anchor=(0.5, 1.2), ncol=3, prop={'size': 12})

def plot_thermo(self, t, td, plot_range=None):
Expand Down Expand Up @@ -111,11 +111,11 @@ def plot_thermo(self, t, td, plot_range=None):

ax_twin = self.ax2.twinx()
ax_twin.set_ylim(plot_range[0], plot_range[1], plot_range[2])
lns = ln4 + ln5
labs = [l.get_label() for l in lns]
lines = ln4 + ln5
labs = [line.get_label() for line in lines]
ax_twin.xaxis.set_major_formatter(mpl.dates.DateFormatter('%d/%H UTC'))

self.ax2.legend(lns, labs, loc='upper center',
self.ax2.legend(lines, labs, loc='upper center',
bbox_to_anchor=(0.5, 1.2), ncol=2, prop={'size': 12})

def plot_rh(self, rh, plot_range=None):
Expand Down
2 changes: 1 addition & 1 deletion src/metpy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,6 @@
os.environ['PINT_ARRAY_PROTOCOL_FALLBACK'] = '0'

from ._version import get_version # noqa: E402
from .xarray import * # noqa: F401, F403
from .xarray import * # noqa: F401, F403, E402
__version__ = get_version()
del get_version
3 changes: 1 addition & 2 deletions src/metpy/calc/basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,7 @@ def wind_components(speed, wind_direction):
--------
>>> from metpy.units import units
>>> metpy.calc.wind_components(10. * units('m/s'), 225. * units.deg)
(<Quantity(7.071067811865475, 'meter / second')>,
<Quantity(7.071067811865477, 'meter / second')>)
(<Quantity(7.07106781, 'meter / second')>, <Quantity(7.07106781, 'meter / second')>)

"""
wind_direction = _check_radians(wind_direction, max_radians=4 * np.pi)
Expand Down
2 changes: 1 addition & 1 deletion src/metpy/calc/thermo.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ def potential_temperature(pressure, temperature):
--------
>>> from metpy.units import units
>>> metpy.calc.potential_temperature(800. * units.mbar, 273. * units.kelvin)
<Quantity(290.9665329591884, 'kelvin')>
<Quantity(290.966533, 'kelvin')>

"""
return temperature / exner_function(pressure)
Expand Down
11 changes: 9 additions & 2 deletions src/metpy/plots/_mpl.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,12 @@ def scattertext(self, x, y, texts, loc=(0, 0), **kw):

# Add it to the axes and update range
self.add_artist(text_obj)

# Matplotlib at least up to 3.2.2 does not properly clip text with paths, so
# work-around by setting to the bounding box of the Axes
# TODO: Remove when fixed in our minimum supported version of matplotlib
text_obj.clipbox = self.bbox

self.update_datalim(text_obj.get_datalim(self.transData))
self.autoscale_view()
return text_obj
Expand Down Expand Up @@ -219,8 +225,9 @@ def draw(self, renderer):
if renderer.flipy():
y = canvash - y

# Can simplify next two lines once support for matplotlib<3.1 is dropped
check_line = getattr(self, '_preprocess_math', self.is_math_text)
# Can simplify next three lines once support for matplotlib<3.1 is dropped
is_math_text = getattr(self, 'is_math_text', False)
check_line = getattr(self, '_preprocess_math', is_math_text)
clean_line, ismath = check_line(line)

if self.get_path_effects():
Expand Down
21 changes: 16 additions & 5 deletions src/metpy/plots/cartopy_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,39 @@
# SPDX-License-Identifier: BSD-3-Clause
"""Cartopy specific mapping utilities."""

import cartopy.crs as ccrs
import cartopy.feature as cfeature

from ..cbook import get_test_data


class MetPyMapFeature(cfeature.NaturalEarthFeature):
"""A simple interface to US County shapefiles."""
class MetPyMapFeature(cfeature.Feature):
"""A simple interface to MetPy-included shapefiles."""

def __init__(self, name, scale, **kwargs):
"""Create USCountiesFeature instance."""
super().__init__('', name, scale, **kwargs)
"""Create MetPyMapFeature instance."""
super().__init__(ccrs.PlateCarree(), **kwargs)
self.name = name

if isinstance(scale, str):
scale = cfeature.Scaler(scale)
self.scaler = scale

def geometries(self):
"""Return an iterator of (shapely) geometries for this feature."""
import cartopy.io.shapereader as shapereader
# Ensure that the associated files are in the cache
fname = '{}_{}'.format(self.name, self.scale)
fname = '{}_{}'.format(self.name, self.scaler.scale)
for extension in ['.dbf', '.shx']:
get_test_data(fname + extension)
path = get_test_data(fname + '.shp', as_file_obj=False)
return iter(tuple(shapereader.Reader(path).geometries()))

def intersecting_geometries(self, extent):
"""Return geometries that intersect the extent."""
self.scaler.scale_from_extent(extent)
return super().intersecting_geometries(extent)

def with_scale(self, new_scale):
"""
Return a copy of the feature with a new scale.
Expand Down
7 changes: 6 additions & 1 deletion src/metpy/plots/skewt.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"""

from contextlib import ExitStack
import warnings

import matplotlib
from matplotlib.axes import Axes
Expand Down Expand Up @@ -126,7 +127,11 @@ class SkewXAxis(maxis.XAxis):
"""

def _get_tick(self, major):
return SkewXTick(self.axes, None, '', major=major)
# Warning stuff can go away when we only support Matplotlib >=3.3
with warnings.catch_warnings():
warnings.simplefilter('ignore', getattr(
matplotlib, 'MatplotlibDeprecationWarning', DeprecationWarning))
return SkewXTick(self.axes, None, label=None, major=major)

# Needed to properly handle tight bbox
def _get_tick_bboxes(self, ticks, renderer):
Expand Down
4 changes: 2 additions & 2 deletions src/metpy/plots/wx_symbols.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,13 +106,13 @@ def __init__(self, num, font_start, font_jumps=None, char_jumps=None):
font_point += 1

@staticmethod
def _safe_pop(l):
def _safe_pop(lst):
"""Safely pop from a list.

Returns None if list empty.

"""
return l.pop(0) if l else None
return lst.pop(0) if lst else None

def __call__(self, code):
"""Return the Unicode code point corresponding to `code`."""
Expand Down
11 changes: 0 additions & 11 deletions src/metpy/testing.py
Original file line number Diff line number Diff line change
Expand Up @@ -199,17 +199,6 @@ def set_agg_backend():
plt.switch_backend(prev_backend)


@pytest.fixture(autouse=True)
def patch_round(monkeypatch):
"""Fixture to patch builtin round using numpy's.

This works around the fact that built-in round changed between Python 2 and 3. This
is probably not needed once we're testing on matplotlib 2.0, which has been updated
to use numpy's throughout.
"""
monkeypatch.setitem(__builtins__, 'round', np.round)


def check_and_silence_warning(warn_type):
"""Decorate a function to swallow some warning type, making sure they are present.

Expand Down
4 changes: 2 additions & 2 deletions tests/calc/test_thermo.py
Original file line number Diff line number Diff line change
Expand Up @@ -808,6 +808,7 @@ def test_most_unstable_parcel():
assert_almost_equal(ret[2], 19.0 * units.degC, 6)


@pytest.mark.filterwarnings('ignore:invalid value:RuntimeWarning')
def test_isentropic_pressure():
"""Test calculation of isentropic pressure function."""
lev = [100000., 95000., 90000., 85000.] * units.Pa
Expand All @@ -819,8 +820,7 @@ def test_isentropic_pressure():
tmp[:, :, -1] = np.nan
tmpk = tmp * units.kelvin
isentlev = [296.] * units.kelvin
with pytest.warns(RuntimeWarning, match='invalid value'):
isentprs = isentropic_interpolation(isentlev, lev, tmpk)
isentprs = isentropic_interpolation(isentlev, lev, tmpk)
trueprs = np.ones((1, 5, 5)) * (1000. * units.hPa)
trueprs[:, :, -1] = np.nan
assert isentprs[0].shape == (1, 5, 5)
Expand Down
Binary file modified tests/plots/baseline/test_arrow_projection.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified tests/plots/baseline/test_barb_projection.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified tests/plots/baseline/test_colorfill.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified tests/plots/baseline/test_colorfill_horiz_colorbar.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified tests/plots/baseline/test_colorfill_no_colorbar.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified tests/plots/baseline/test_declarative_contour_convert_units.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified tests/plots/baseline/test_declarative_contour_options.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion tests/plots/test_cartopy_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

from metpy.plots import USCOUNTIES, USSTATES
# Fixtures to make sure we have the right backend and consistent round
from metpy.testing import patch_round, set_agg_backend # noqa: F401, I202
from metpy.testing import set_agg_backend # noqa: F401, I202

MPL_VERSION = matplotlib.__version__[:3]

Expand Down
26 changes: 21 additions & 5 deletions tests/plots/test_declarative.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import cartopy.crs as ccrs
import cartopy.feature as cfeature
import matplotlib
import numpy as np
import pandas as pd
import pytest
from traitlets import TraitError
Expand Down Expand Up @@ -77,8 +78,22 @@ def test_declarative_contour():
return pc.figure


@pytest.fixture
def fix_is_closed_polygon(monkeypatch):
"""Fix matplotlib.contour._is_closed_polygons for tests.

Needed because for Matplotlib<3.3, the internal matplotlib.contour._is_closed_polygon
uses strict floating point equality. This causes the test below to yield different
results for macOS vs. Linux/Windows.

"""
monkeypatch.setattr(matplotlib.contour, '_is_closed_polygon',
lambda X: np.allclose(X[0], X[-1], rtol=1e-10, atol=1e-13),
raising=False)


@pytest.mark.mpl_image_compare(remove_text=True, tolerance=0.035)
def test_declarative_contour_options():
def test_declarative_contour_options(fix_is_closed_polygon):
"""Test making a contour plot."""
data = xr.open_dataset(get_test_data('narr_example.nc', as_file_obj=False))

Expand Down Expand Up @@ -107,7 +122,7 @@ def test_declarative_contour_options():


@pytest.mark.mpl_image_compare(remove_text=True, tolerance=0.035)
def test_declarative_contour_convert_units():
def test_declarative_contour_convert_units(fix_is_closed_polygon):
"""Test making a contour plot."""
data = xr.open_dataset(get_test_data('narr_example.nc', as_file_obj=False))

Expand Down Expand Up @@ -419,7 +434,7 @@ def test_declarative_barb_earth_relative():
return pc.figure


@pytest.mark.mpl_image_compare(remove_text=True, tolerance=0.346)
@pytest.mark.mpl_image_compare(remove_text=True, tolerance=0.347)
def test_declarative_barb_gfs():
"""Test making a contour plot."""
data = xr.open_dataset(get_test_data('GFS_test.nc', as_file_obj=False))
Expand Down Expand Up @@ -542,7 +557,7 @@ def test_declarative_sfc_obs_changes():
return pc.figure


@pytest.mark.mpl_image_compare(remove_text=True, tolerance=0)
@pytest.mark.mpl_image_compare(remove_text=True, tolerance=0.00586)
def test_declarative_colored_barbs():
"""Test making a surface plot with a colored barb (gh-1274)."""
data = pd.read_csv(get_test_data('SFC_obs.csv', as_file_obj=False),
Expand Down Expand Up @@ -575,7 +590,8 @@ def test_declarative_colored_barbs():


@pytest.mark.mpl_image_compare(remove_text=True,
tolerance={'3.1': 9.771, '2.1': 9.771}.get(MPL_VERSION, 0.))
tolerance={'3.1': 9.771,
'2.1': 9.771}.get(MPL_VERSION, 0.00651))
def test_declarative_sfc_obs_full():
"""Test making a full surface observation plot."""
data = pd.read_csv(get_test_data('SFC_obs.csv', as_file_obj=False),
Expand Down
2 changes: 1 addition & 1 deletion tests/plots/test_skewt.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

from metpy.plots import Hodograph, SkewT
# Fixtures to make sure we have the right backend and consistent round
from metpy.testing import patch_round, set_agg_backend # noqa: F401, I202
from metpy.testing import set_agg_backend # noqa: F401, I202
from metpy.units import units


Expand Down
10 changes: 5 additions & 5 deletions tests/plots/test_station_plot.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from metpy.plots import (current_weather, high_clouds, nws_layout, simple_layout,
sky_cover, StationPlot, StationPlotLayout)
# Fixtures to make sure we have the right backend and consistent round
from metpy.testing import patch_round, set_agg_backend # noqa: F401, I202
from metpy.testing import set_agg_backend # noqa: F401, I202
from metpy.units import units


Expand Down Expand Up @@ -279,30 +279,30 @@ def wind_plot():
return u, v, x, y


@pytest.mark.mpl_image_compare(tolerance=0.00323, remove_text=True)
@pytest.mark.mpl_image_compare(tolerance=0.00434, remove_text=True)
def test_barb_projection(wind_plot):
"""Test that barbs are properly projected (#598)."""
u, v, x, y = wind_plot

# Plot and check barbs (they should align with grid lines)
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1, projection=ccrs.LambertConformal())
ax.gridlines(xlocs=[-135, -120, -105, -90, -75, -60, -45])
ax.gridlines(xlocs=[-120, -105, -90, -75, -60], ylocs=np.arange(24, 55, 6))
sp = StationPlot(ax, x, y, transform=ccrs.PlateCarree())
sp.plot_barb(u, v)

return fig


@pytest.mark.mpl_image_compare(tolerance=0.00205, remove_text=True)
@pytest.mark.mpl_image_compare(tolerance=0.00382, remove_text=True)
def test_arrow_projection(wind_plot):
"""Test that arrows are properly projected."""
u, v, x, y = wind_plot

# Plot and check barbs (they should align with grid lines)
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1, projection=ccrs.LambertConformal())
ax.gridlines(xlocs=[-135, -120, -105, -90, -75, -60, -45])
ax.gridlines(xlocs=[-120, -105, -90, -75, -60], ylocs=np.arange(24, 55, 6))
sp = StationPlot(ax, x, y, transform=ccrs.PlateCarree())
sp.plot_arrow(u, v)
sp.plot_arrow(u, v) # plot_arrow used twice to hit removal if statement
Expand Down