Skip to content

Commit 651ba19

Browse files
committed
Do not clear Axis when registering spine
1 parent 0b8bd96 commit 651ba19

File tree

8 files changed

+61
-45
lines changed

8 files changed

+61
-45
lines changed

galleries/examples/specialty_plots/radar_chart.py

+8-6
Original file line numberDiff line numberDiff line change
@@ -99,15 +99,17 @@ def _gen_axes_spines(self):
9999
return super()._gen_axes_spines()
100100
elif frame == 'polygon':
101101
# spine_type must be 'left'/'right'/'top'/'bottom'/'circle'.
102-
spine = Spine(axes=self,
103-
spine_type='circle',
104-
path=Path.unit_regular_polygon(num_vars))
102+
polar_spine = Spine(axes=self,
103+
spine_type='circle',
104+
path=Path.unit_regular_polygon(num_vars))
105105
# unit_regular_polygon gives a polygon of radius 1 centered at
106106
# (0, 0) but we want a polygon of radius 0.5 centered at (0.5,
107107
# 0.5) in axes coordinates.
108-
spine.set_transform(Affine2D().scale(.5).translate(.5, .5)
109-
+ self.transAxes)
110-
return {'polar': spine}
108+
polar_spine.set_transform(Affine2D().scale(.5).translate(.5, .5)
109+
+ self.transAxes)
110+
# Must have a dummy spine for 'inner'
111+
inner_spine = Spine.linear_spine(self, 'bottom')
112+
return {'polar': polar_spine, 'inner': inner_spine}
111113
else:
112114
raise ValueError("Unknown value for 'frame': %s" % frame)
113115

lib/matplotlib/axes/_base.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -814,10 +814,10 @@ def get_window_extent(self, renderer=None):
814814

815815
def _init_axis(self):
816816
# This is moved out of __init__ because non-separable axes don't use it
817-
self.xaxis = maxis.XAxis(self)
817+
self.xaxis = maxis.XAxis(self, clear=False)
818818
self.spines.bottom.register_axis(self.xaxis)
819819
self.spines.top.register_axis(self.xaxis)
820-
self.yaxis = maxis.YAxis(self)
820+
self.yaxis = maxis.YAxis(self, clear=False)
821821
self.spines.left.register_axis(self.yaxis)
822822
self.spines.right.register_axis(self.yaxis)
823823

@@ -1275,7 +1275,7 @@ def __clear(self):
12751275
for axis in self._axis_map.values():
12761276
axis.clear() # Also resets the scale to linear.
12771277
for spine in self.spines.values():
1278-
spine.clear()
1278+
spine._clear() # Use _clear to not clear Axis again
12791279

12801280
self.ignore_existing_data_limits = True
12811281
self.callbacks = cbook.CallbackRegistry(

lib/matplotlib/axis.py

+25-18
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,12 @@
3232
_gridline_param_names = ['grid_' + name
3333
for name in _line_param_names + _line_param_aliases]
3434

35+
_MARKER_DICT = {
36+
'out': (mlines.TICKDOWN, mlines.TICKUP),
37+
'in': (mlines.TICKUP, mlines.TICKDOWN),
38+
'inout': ('|', '|'),
39+
}
40+
3541

3642
class Tick(martist.Artist):
3743
"""
@@ -87,11 +93,10 @@ def __init__(
8793
super().__init__()
8894

8995
if gridOn is None:
90-
if major and (mpl.rcParams['axes.grid.which']
91-
in ('both', 'major')):
96+
which = mpl.rcParams['axes.grid.which']
97+
if major and (which in ('both', 'major')):
9298
gridOn = mpl.rcParams['axes.grid']
93-
elif (not major) and (mpl.rcParams['axes.grid.which']
94-
in ('both', 'minor')):
99+
elif (not major) and (which in ('both', 'minor')):
95100
gridOn = mpl.rcParams['axes.grid']
96101
else:
97102
gridOn = False
@@ -209,7 +214,8 @@ def _apply_tickdir(self, tickdir):
209214
# further updates ticklabel positions using the new pads.
210215
if tickdir is None:
211216
tickdir = mpl.rcParams[f'{self.__name__}.direction']
212-
_api.check_in_list(['in', 'out', 'inout'], tickdir=tickdir)
217+
else:
218+
_api.check_in_list(['in', 'out', 'inout'], tickdir=tickdir)
213219
self._tickdir = tickdir
214220
self._pad = self._base_pad + self.get_tick_padding()
215221

@@ -436,11 +442,7 @@ def _get_text2_transform(self):
436442
def _apply_tickdir(self, tickdir):
437443
# docstring inherited
438444
super()._apply_tickdir(tickdir)
439-
mark1, mark2 = {
440-
'out': (mlines.TICKDOWN, mlines.TICKUP),
441-
'in': (mlines.TICKUP, mlines.TICKDOWN),
442-
'inout': ('|', '|'),
443-
}[self._tickdir]
445+
mark1, mark2 = _MARKER_DICT[self._tickdir]
444446
self.tick1line.set_marker(mark1)
445447
self.tick2line.set_marker(mark2)
446448

@@ -632,7 +634,7 @@ def __str__(self):
632634
return "{}({},{})".format(
633635
type(self).__name__, *self.axes.transAxes.transform((0, 0)))
634636

635-
def __init__(self, axes, *, pickradius=15):
637+
def __init__(self, axes, *, pickradius=15, clear=True):
636638
"""
637639
Parameters
638640
----------
@@ -641,6 +643,8 @@ def __init__(self, axes, *, pickradius=15):
641643
pickradius : float
642644
The acceptance radius for containment tests. See also
643645
`.Axis.contains`.
646+
clear : bool, default: True
647+
Whether to clear the Axis on creation.
644648
"""
645649
super().__init__()
646650
self._remove_overlapping_locs = True
@@ -674,7 +678,12 @@ def __init__(self, axes, *, pickradius=15):
674678
self._major_tick_kw = dict()
675679
self._minor_tick_kw = dict()
676680

677-
self.clear()
681+
if clear:
682+
self.clear()
683+
else:
684+
self.converter = None
685+
self.units = None
686+
678687
self._autoscale_on = True
679688

680689
@property
@@ -2353,8 +2362,6 @@ def set_ticks_position(self, position):
23532362
can be used if you don't want any ticks. 'none' and 'both'
23542363
affect only the ticks, not the labels.
23552364
"""
2356-
_api.check_in_list(['top', 'bottom', 'both', 'default', 'none'],
2357-
position=position)
23582365
if position == 'top':
23592366
self.set_tick_params(which='both', top=True, labeltop=True,
23602367
bottom=False, labelbottom=False)
@@ -2377,7 +2384,8 @@ def set_ticks_position(self, position):
23772384
self._tick_position = 'bottom'
23782385
self.offsetText.set_verticalalignment('top')
23792386
else:
2380-
assert False, "unhandled parameter not caught by _check_in_list"
2387+
_api.check_in_list(['top', 'bottom', 'both', 'default', 'none'],
2388+
position=position)
23812389
self.stale = True
23822390

23832391
def tick_top(self):
@@ -2599,8 +2607,6 @@ def set_ticks_position(self, position):
25992607
can be used if you don't want any ticks. 'none' and 'both'
26002608
affect only the ticks, not the labels.
26012609
"""
2602-
_api.check_in_list(['left', 'right', 'both', 'default', 'none'],
2603-
position=position)
26042610
if position == 'right':
26052611
self.set_tick_params(which='both', right=True, labelright=True,
26062612
left=False, labelleft=False)
@@ -2619,7 +2625,8 @@ def set_ticks_position(self, position):
26192625
self.set_tick_params(which='both', right=True, labelright=False,
26202626
left=True, labelleft=True)
26212627
else:
2622-
assert False, "unhandled parameter not caught by _check_in_list"
2628+
_api.check_in_list(['left', 'right', 'both', 'default', 'none'],
2629+
position=position)
26232630
self.stale = True
26242631

26252632
def tick_right(self):

lib/matplotlib/axis.pyi

+2-1
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,8 @@ class Axis(martist.Artist):
105105
offsetText: Text
106106
labelpad: float
107107
pickradius: float
108-
def __init__(self, axes, *, pickradius: float = ...) -> None: ...
108+
def __init__(self, axes, *, pickradius: float = ...,
109+
clear: bool = ...) -> None: ...
109110
@property
110111
def isDefault_majloc(self) -> bool: ...
111112
@isDefault_majloc.setter

lib/matplotlib/projections/geo.py

+3-5
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,9 @@ def __call__(self, x, pos=None):
3030
RESOLUTION = 75
3131

3232
def _init_axis(self):
33-
self.xaxis = maxis.XAxis(self)
34-
self.yaxis = maxis.YAxis(self)
35-
# Do not register xaxis or yaxis with spines -- as done in
36-
# Axes._init_axis() -- until GeoAxes.xaxis.clear() works.
37-
# self.spines['geo'].register_axis(self.yaxis)
33+
self.xaxis = maxis.XAxis(self, clear=False)
34+
self.yaxis = maxis.YAxis(self, clear=False)
35+
self.spines['geo'].register_axis(self.yaxis)
3836

3937
def clear(self):
4038
# docstring inherited

lib/matplotlib/projections/polar.py

+4-5
Original file line numberDiff line numberDiff line change
@@ -846,11 +846,10 @@ def clear(self):
846846

847847
def _init_axis(self):
848848
# This is moved out of __init__ because non-separable axes don't use it
849-
self.xaxis = ThetaAxis(self)
850-
self.yaxis = RadialAxis(self)
851-
# Calling polar_axes.xaxis.clear() or polar_axes.yaxis.clear()
852-
# results in weird artifacts. Therefore we disable this for now.
853-
# self.spines['polar'].register_axis(self.yaxis)
849+
self.xaxis = ThetaAxis(self, clear=False)
850+
self.yaxis = RadialAxis(self, clear=False)
851+
self.spines['inner'].register_axis(self.xaxis)
852+
self.spines['polar'].register_axis(self.yaxis)
854853

855854
def _set_lim_and_transforms(self):
856855
# A view limit where the minimum radius can be locked if the user

lib/matplotlib/spines.py

+10-3
Original file line numberDiff line numberDiff line change
@@ -214,16 +214,23 @@ def register_axis(self, axis):
214214
properties when needed.
215215
"""
216216
self.axis = axis
217-
if self.axis is not None:
218-
self.axis.clear()
219217
self.stale = True
220218

221219
def clear(self):
222220
"""Clear the current spine."""
223-
self._position = None # clear position
221+
self._clear()
224222
if self.axis is not None:
225223
self.axis.clear()
226224

225+
def _clear(self):
226+
"""
227+
Clear things directly related to the spine.
228+
229+
In this way it is possible to avoid clearing the Axis as well when calling
230+
from library code.
231+
"""
232+
self._position = None # clear position
233+
227234
def _adjust_location(self):
228235
"""Automatically set spine bounds to the view interval."""
229236

lib/matplotlib/text.py

+6-4
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,6 @@ def __init__(self,
136136
super().__init__()
137137
self._x, self._y = x, y
138138
self._text = ''
139-
self._antialiased = mpl.rcParams['text.antialiased']
140139
self._reset_visual_defaults(
141140
text=text,
142141
color=color,
@@ -191,8 +190,8 @@ def _reset_visual_defaults(
191190
linespacing = 1.2 # Maybe use rcParam later.
192191
self.set_linespacing(linespacing)
193192
self.set_rotation_mode(rotation_mode)
194-
if antialiased is not None:
195-
self.set_antialiased(antialiased)
193+
self.set_antialiased(antialiased if antialiased is not None else
194+
mpl.rcParams['text.antialiased'])
196195

197196
def update(self, kwargs):
198197
# docstring inherited
@@ -307,7 +306,10 @@ def set_rotation_mode(self, m):
307306
aligned according to their horizontal and vertical alignments. If
308307
``"anchor"``, then alignment occurs before rotation.
309308
"""
310-
_api.check_in_list(["anchor", "default", None], rotation_mode=m)
309+
if m is None:
310+
m = "default"
311+
else:
312+
_api.check_in_list(("anchor", "default"), rotation_mode=m)
311313
self._rotation_mode = m
312314
self.stale = True
313315

0 commit comments

Comments
 (0)