Skip to content

Commit

Permalink
Backport PR matplotlib#12468: Fix set_ylim unit handling
Browse files Browse the repository at this point in the history
  • Loading branch information
dopplershift authored and MeeseeksDev[bot] committed Oct 10, 2018
1 parent 2e10154 commit 28bc96f
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 11 deletions.
1 change: 1 addition & 0 deletions lib/matplotlib/axes/_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -3461,6 +3461,7 @@ def set_ylim(self, bottom=None, top=None, emit=True, auto=False,
raise TypeError('Cannot pass both `ymax` and `top`')
top = ymax

self._process_unit_info(ydata=(bottom, top))
bottom = self._validate_converted_limits(bottom, self.convert_yunits)
top = self._validate_converted_limits(top, self.convert_yunits)

Expand Down
45 changes: 34 additions & 11 deletions lib/matplotlib/tests/test_units.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import numpy as np
import datetime
import platform
import pytest


# Basic class that wraps numpy array and has units
Expand Down Expand Up @@ -38,12 +39,8 @@ def __array__(self):
return np.asarray(self.magnitude)


# Tests that the conversion machinery works properly for classes that
# work as a facade over numpy arrays (like pint)
@image_comparison(baseline_images=['plot_pint'],
tol={'aarch64': 0.02}.get(platform.machine(), 0.0),
extensions=['png'], remove_text=False, style='mpl20')
def test_numpy_facade():
@pytest.fixture
def quantity_converter():
# Create an instance of the conversion interface and
# mock so we can check methods called
qc = munits.ConversionInterface()
Expand All @@ -60,12 +57,29 @@ def convert(value, unit, axis):
else:
return Quantity(value, axis.get_units()).to(unit).magnitude

def default_units(value, axis):
if hasattr(value, 'units'):
return value.units
elif np.iterable(value):
for v in value:
if hasattr(v, 'units'):
return v.units
return None

qc.convert = MagicMock(side_effect=convert)
qc.axisinfo = MagicMock(side_effect=lambda u, a: munits.AxisInfo(label=u))
qc.default_units = MagicMock(side_effect=lambda x, a: x.units)
qc.default_units = MagicMock(side_effect=default_units)
return qc


# Tests that the conversion machinery works properly for classes that
# work as a facade over numpy arrays (like pint)
@image_comparison(baseline_images=['plot_pint'],
tol={'aarch64': 0.02}.get(platform.machine(), 0.0),
extensions=['png'], remove_text=False, style='mpl20')
def test_numpy_facade(quantity_converter):
# Register the class
munits.registry[Quantity] = qc
munits.registry[Quantity] = quantity_converter

# Simple test
y = Quantity(np.linspace(0, 30), 'miles')
Expand All @@ -79,9 +93,9 @@ def convert(value, unit, axis):
ax.yaxis.set_units('inches')
ax.xaxis.set_units('seconds')

assert qc.convert.called
assert qc.axisinfo.called
assert qc.default_units.called
assert quantity_converter.convert.called
assert quantity_converter.axisinfo.called
assert quantity_converter.default_units.called


# Tests gh-8908
Expand All @@ -97,6 +111,15 @@ def test_plot_masked_units():
ax.plot(data_masked_units)


def test_empty_set_limits_with_units(quantity_converter):
# Register the class
munits.registry[Quantity] = quantity_converter

fig, ax = plt.subplots()
ax.set_xlim(Quantity(-1, 'meters'), Quantity(6, 'meters'))
ax.set_ylim(Quantity(-1, 'hours'), Quantity(16, 'hours'))


@image_comparison(baseline_images=['jpl_bar_units'], extensions=['png'],
savefig_kwarg={'dpi': 120}, style='mpl20')
def test_jpl_bar_units():
Expand Down

0 comments on commit 28bc96f

Please sign in to comment.