Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit d266e71

Browse files
authored
Merge pull request #17828 from tacaswell/fix_none_units
API: treat xunits=None and yunits=None as "default"
2 parents e2d0fa2 + 444eaa4 commit d266e71

File tree

3 files changed

+59
-3
lines changed

3 files changed

+59
-3
lines changed
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
xunits=None and yunits=None passed as kwargs are treated as "no action"
2+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3+
4+
Many (but not all) of the methods on `~.axes.Axes` take the (undocumented)
5+
kwargs *xunits* and *yunits* that will update the units on the given
6+
Axis by calling `.Axis.set_units` and `.Axis.update_units`.
7+
8+
Previously if `None` was passed it would clear the value stored in
9+
``.Axis.units`` which will in turn break converters (notably
10+
`.StrCategoryConverter`) which rely on the value in
11+
``.Axis.units`` to work properly.
12+
13+
This changes the semantics of ``ax.meth(..., xunits=None,
14+
yunits=None)`` from "please clear the units" to "do the default thing
15+
as if they had not been passed" which is consistent with the standard
16+
behavior of Matplotlib keyword arguments.
17+
18+
If you were relying on passing ``xuints=None`` to plotting methods to
19+
clear the ``.Axes.units`` attribute, directly call `.Axis.set_units` (and
20+
`.Axis.update_units` if you also require the converter to be updated).

lib/matplotlib/axes/_base.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2172,7 +2172,15 @@ def update_datalim_bounds(self, bounds):
21722172
self.dataLim.set(mtransforms.Bbox.union([self.dataLim, bounds]))
21732173

21742174
def _process_unit_info(self, xdata=None, ydata=None, kwargs=None):
2175-
"""Look for unit *kwargs* and update the axis instances as necessary"""
2175+
"""
2176+
Look for unit *kwargs* and update the axis instances as necessary
2177+
2178+
2179+
.. warning ::
2180+
2181+
This method may mutate the dictionary passed in an kwargs and
2182+
the Axis instances attached to this Axes.
2183+
"""
21762184

21772185
def _process_single_axis(data, axis, unit_name, kwargs):
21782186
# Return if there's no axis set
@@ -2188,10 +2196,12 @@ def _process_single_axis(data, axis, unit_name, kwargs):
21882196
if kwargs is not None:
21892197
units = kwargs.pop(unit_name, axis.units)
21902198
if self.name == 'polar':
2199+
# handle special casing to allow the kwargs
2200+
# thetaunits and runits to be used with polar
21912201
polar_units = {'xunits': 'thetaunits', 'yunits': 'runits'}
21922202
units = kwargs.pop(polar_units[unit_name], units)
21932203

2194-
if units != axis.units:
2204+
if units != axis.units and units is not None:
21952205
axis.set_units(units)
21962206
# If the units being set imply a different converter,
21972207
# we need to update.
@@ -3780,7 +3790,7 @@ def set_navigate_mode(self, b):
37803790
"""
37813791
Set the navigation toolbar button status;
37823792
3783-
.. warning::
3793+
.. warning ::
37843794
this is not a user-API function.
37853795
37863796
"""

lib/matplotlib/tests/test_category.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from matplotlib.axes import Axes
66
import matplotlib.pyplot as plt
77
import matplotlib.category as cat
8+
from matplotlib.testing.decorators import check_figures_equal
89

910

1011
class TestUnitData:
@@ -269,3 +270,28 @@ def test_mixed_type_update_exception(self, ax, plotter, xdata):
269270
with pytest.raises(TypeError):
270271
plotter(ax, [0, 3], [1, 3])
271272
plotter(ax, xdata, [1, 2])
273+
274+
275+
@pytest.mark.style('default')
276+
@check_figures_equal(extensions=["png"])
277+
def test_overriding_units_in_plot(fig_test, fig_ref):
278+
from datetime import datetime
279+
280+
t0 = datetime(2018, 3, 1)
281+
t1 = datetime(2018, 3, 2)
282+
t2 = datetime(2018, 3, 3)
283+
t3 = datetime(2018, 3, 4)
284+
285+
ax_test = fig_test.subplots()
286+
ax_ref = fig_ref.subplots()
287+
for ax, kwargs in zip([ax_test, ax_ref],
288+
({}, dict(xunits=None, yunits=None))):
289+
# First call works
290+
ax.plot([t0, t1], ["V1", "V2"], **kwargs)
291+
x_units = ax.xaxis.units
292+
y_units = ax.yaxis.units
293+
# this should not raise
294+
ax.plot([t2, t3], ["V1", "V2"], **kwargs)
295+
# assert that we have not re-set the units attribute at all
296+
assert x_units is ax.xaxis.units
297+
assert y_units is ax.yaxis.units

0 commit comments

Comments
 (0)