Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit32ec60d

Browse files
authored
Add explicit converter setting to Axis (#28970)
* Add explicit converter setting to AxisCloses#19229The replacement is the get/set_converter method.This includes changes to use the getter and the private setter in the qtfigure options dialog menu.The choice to use the private setter was a defensive one as the publicsetter prevents being called multiple times (though does short circuitif an identical input is provided, which I think is actually true here,therefore the public one is probably functional (and a no-op).)It is not clear to me on analysis how the unit information is or waslost. A quick test commenting out the two lines which resetconverter/units displayed no obvious detrimental effect to removingthose, suggesting that even if once they were necessary, they may nolonger be.These lines were last touched in#24141, though that really only generalizedthe code into a loop rather than copy/pasted x and y behavior.The original inclusion of resetting was in#4909, which indicated thatthe dialog reset unit info. AFAICT, that is no longer true, though Ihave not rigorously proved that.
1 parentc52cb41 commit32ec60d

File tree

6 files changed

+100
-24
lines changed

6 files changed

+100
-24
lines changed

‎doc/api/axis_api.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,8 @@ Units
169169
Axis.convert_units
170170
Axis.set_units
171171
Axis.get_units
172+
Axis.set_converter
173+
Axis.get_converter
172174
Axis.update_units
173175

174176

‎lib/matplotlib/axis.py

Lines changed: 61 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -600,6 +600,10 @@ class Axis(martist.Artist):
600600
# The class used in _get_tick() to create tick instances. Must either be
601601
# overwritten in subclasses, or subclasses must reimplement _get_tick().
602602
_tick_class=None
603+
converter=_api.deprecate_privatize_attribute(
604+
"3.10",
605+
alternative="get_converter and set_converter methods"
606+
)
603607

604608
def__str__(self):
605609
return"{}({},{})".format(
@@ -656,7 +660,8 @@ def __init__(self, axes, *, pickradius=15, clear=True):
656660
ifclear:
657661
self.clear()
658662
else:
659-
self.converter=None
663+
self._converter=None
664+
self._converter_is_explicit=False
660665
self.units=None
661666

662667
self._autoscale_on=True
@@ -886,7 +891,8 @@ def clear(self):
886891
mpl.rcParams['axes.grid.which']in ('both','minor'))
887892
self.reset_ticks()
888893

889-
self.converter=None
894+
self._converter=None
895+
self._converter_is_explicit=False
890896
self.units=None
891897
self.stale=True
892898

@@ -1738,16 +1744,20 @@ def grid(self, visible=None, which='major', **kwargs):
17381744
defupdate_units(self,data):
17391745
"""
17401746
Introspect *data* for units converter and update the
1741-
``axis.converter`` instance if necessary. Return *True*
1747+
``axis.get_converter`` instance if necessary. Return *True*
17421748
if *data* is registered for unit conversion.
17431749
"""
1744-
converter=munits.registry.get_converter(data)
1750+
ifnotself._converter_is_explicit:
1751+
converter=munits.registry.get_converter(data)
1752+
else:
1753+
converter=self._converter
1754+
17451755
ifconverterisNone:
17461756
returnFalse
17471757

1748-
neednew=self.converter!=converter
1749-
self.converter=converter
1750-
default=self.converter.default_units(data,self)
1758+
neednew=self._converter!=converter
1759+
self._set_converter(converter)
1760+
default=self._converter.default_units(data,self)
17511761
ifdefaultisnotNoneandself.unitsisNone:
17521762
self.set_units(default)
17531763

@@ -1761,10 +1771,10 @@ def _update_axisinfo(self):
17611771
Check the axis converter for the stored units to see if the
17621772
axis info needs to be updated.
17631773
"""
1764-
ifself.converterisNone:
1774+
ifself._converterisNone:
17651775
return
17661776

1767-
info=self.converter.axisinfo(self.units,self)
1777+
info=self._converter.axisinfo(self.units,self)
17681778

17691779
ifinfoisNone:
17701780
return
@@ -1791,25 +1801,58 @@ def _update_axisinfo(self):
17911801
self.set_default_intervals()
17921802

17931803
defhave_units(self):
1794-
returnself.converterisnotNoneorself.unitsisnotNone
1804+
returnself._converterisnotNoneorself.unitsisnotNone
17951805

17961806
defconvert_units(self,x):
17971807
# If x is natively supported by Matplotlib, doesn't need converting
17981808
ifmunits._is_natively_supported(x):
17991809
returnx
18001810

1801-
ifself.converterisNone:
1802-
self.converter=munits.registry.get_converter(x)
1811+
ifself._converterisNone:
1812+
self._set_converter(munits.registry.get_converter(x))
18031813

1804-
ifself.converterisNone:
1814+
ifself._converterisNone:
18051815
returnx
18061816
try:
1807-
ret=self.converter.convert(x,self.units,self)
1817+
ret=self._converter.convert(x,self.units,self)
18081818
exceptExceptionase:
18091819
raisemunits.ConversionError('Failed to convert value(s) to axis '
18101820
f'units:{x!r}')frome
18111821
returnret
18121822

1823+
defget_converter(self):
1824+
"""
1825+
Get the unit converter for axis.
1826+
1827+
Returns
1828+
-------
1829+
`~matplotlib.units.ConversionInterface` or None
1830+
"""
1831+
returnself._converter
1832+
1833+
defset_converter(self,converter):
1834+
"""
1835+
Set the unit converter for axis.
1836+
1837+
Parameters
1838+
----------
1839+
converter : `~matplotlib.units.ConversionInterface`
1840+
"""
1841+
self._set_converter(converter)
1842+
self._converter_is_explicit=True
1843+
1844+
def_set_converter(self,converter):
1845+
ifself._converter==converter:
1846+
return
1847+
ifself._converter_is_explicit:
1848+
raiseRuntimeError("Axis already has an explicit converter set")
1849+
elifself._converterisnotNone:
1850+
_api.warn_external(
1851+
"This axis already has a converter set and "
1852+
"is updating to a potentially incompatible converter"
1853+
)
1854+
self._converter=converter
1855+
18131856
defset_units(self,u):
18141857
"""
18151858
Set the units for axis.
@@ -2529,8 +2572,8 @@ def set_default_intervals(self):
25292572
# not changed the view:
25302573
if (notself.axes.dataLim.mutatedx()and
25312574
notself.axes.viewLim.mutatedx()):
2532-
ifself.converterisnotNone:
2533-
info=self.converter.axisinfo(self.units,self)
2575+
ifself._converterisnotNone:
2576+
info=self._converter.axisinfo(self.units,self)
25342577
ifinfo.default_limitsisnotNone:
25352578
xmin,xmax=self.convert_units(info.default_limits)
25362579
self.axes.viewLim.intervalx=xmin,xmax
@@ -2759,8 +2802,8 @@ def set_default_intervals(self):
27592802
# not changed the view:
27602803
if (notself.axes.dataLim.mutatedy()and
27612804
notself.axes.viewLim.mutatedy()):
2762-
ifself.converterisnotNone:
2763-
info=self.converter.axisinfo(self.units,self)
2805+
ifself._converterisnotNone:
2806+
info=self._converter.axisinfo(self.units,self)
27642807
ifinfo.default_limitsisnotNone:
27652808
ymin,ymax=self.convert_units(info.default_limits)
27662809
self.axes.viewLim.intervaly=ymin,ymax

‎lib/matplotlib/axis.pyi

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ from matplotlib.text import Text
1515
frommatplotlib.tickerimportLocator,Formatter
1616
frommatplotlib.transformsimportTransform,Bbox
1717
frommatplotlib.typingimportColorType
18+
frommatplotlib.unitsimportConversionInterface
1819

1920

2021
GRIDLINE_INTERPOLATION_STEPS:int
@@ -207,6 +208,8 @@ class Axis(martist.Artist):
207208
defupdate_units(self,data): ...
208209
defhave_units(self)->bool: ...
209210
defconvert_units(self,x): ...
211+
defget_converter(self)->ConversionInterface|None: ...
212+
defset_converter(self,converter:ConversionInterface)->None: ...
210213
defset_units(self,u)->None: ...
211214
defget_units(self): ...
212215
defset_label_text(

‎lib/matplotlib/backends/qt_editor/figureoptions.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ def convert_limits(lim, converter):
4242
axis_map=axes._axis_map
4343
axis_limits= {
4444
name:tuple(convert_limits(
45-
getattr(axes,f'get_{name}lim')(),axis.converter
45+
getattr(axes,f'get_{name}lim')(),axis.get_converter()
4646
))
4747
forname,axisinaxis_map.items()
4848
}
@@ -66,7 +66,7 @@ def convert_limits(lim, converter):
6666

6767
# Save the converter and unit data
6868
axis_converter= {
69-
name:axis.converter
69+
name:axis.get_converter()
7070
forname,axisinaxis_map.items()
7171
}
7272
axis_units= {
@@ -209,7 +209,7 @@ def apply_callback(data):
209209
axis.set_label_text(axis_label)
210210

211211
# Restore the unit data
212-
axis.converter=axis_converter[name]
212+
axis._set_converter(axis_converter[name])
213213
axis.set_units(axis_units[name])
214214

215215
# Set / Curves

‎lib/matplotlib/tests/test_dates.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -668,10 +668,12 @@ def test_concise_converter_stays():
668668
fig,ax=plt.subplots()
669669
ax.plot(x,y)
670670
# Bypass Switchable date converter
671-
ax.xaxis.converter=conv=mdates.ConciseDateConverter()
671+
conv=mdates.ConciseDateConverter()
672+
withpytest.warns(UserWarning,match="already has a converter"):
673+
ax.xaxis.set_converter(conv)
672674
assertax.xaxis.unitsisNone
673675
ax.set_xlim(*x)
674-
assertax.xaxis.converter==conv
676+
assertax.xaxis.get_converter()==conv
675677

676678

677679
deftest_offset_changes():

‎lib/matplotlib/tests/test_units.py

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
importmatplotlib.pyplotasplt
66
frommatplotlib.testing.decoratorsimportcheck_figures_equal,image_comparison
77
importmatplotlib.unitsasmunits
8-
frommatplotlib.categoryimportUnitData
8+
frommatplotlib.categoryimportStrCategoryConverter,UnitData
99
importnumpyasnp
1010
importpytest
1111

@@ -236,6 +236,32 @@ def test_shared_axis_categorical():
236236
assert"c"inax2.xaxis.get_units()._mapping.keys()
237237

238238

239+
deftest_explicit_converter():
240+
d1= {"a":1,"b":2}
241+
str_cat_converter=StrCategoryConverter()
242+
str_cat_converter_2=StrCategoryConverter()
243+
244+
# Explicit is set
245+
fig1,ax1=plt.subplots()
246+
ax1.xaxis.set_converter(str_cat_converter)
247+
assertax1.xaxis.get_converter()==str_cat_converter
248+
# Explicit not overridden by implicit
249+
ax1.plot(d1.keys(),d1.values())
250+
assertax1.xaxis.get_converter()==str_cat_converter
251+
# No error when called twice with equivalent input
252+
ax1.xaxis.set_converter(str_cat_converter)
253+
# Error when explicit called twice
254+
withpytest.raises(RuntimeError):
255+
ax1.xaxis.set_converter(str_cat_converter_2)
256+
257+
# Warn when implicit overridden
258+
fig2,ax2=plt.subplots()
259+
ax2.plot(d1.keys(),d1.values())
260+
261+
withpytest.warns():
262+
ax2.xaxis.set_converter(str_cat_converter)
263+
264+
239265
deftest_empty_default_limits(quantity_converter):
240266
munits.registry[Quantity]=quantity_converter
241267
fig,ax1=plt.subplots()

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp