Skip to content

Commit 95db12f

Browse files
leakyHrcomer
andauthored
[fix] Spine.set_bounds() does not take parameter **None** as expected (#30330)
* extract a _get_bounds_or_viewLim function, which is used both in set_bounds and _adjust_location * add tests * add doc str for _get_bounds_or_viewLim * Update lib/matplotlib/tests/test_spines.py Set appropriate bottom_bound in the test. Co-authored-by: Ruth Comer <10599679+rcomer@users.noreply.github.com> * Update lib/matplotlib/spines.py The error is mainly raised for user- or third party-defined spines. 'circle' is already handled in two function callers. Co-authored-by: Ruth Comer <10599679+rcomer@users.noreply.github.com> * regroup spine tests --------- Co-authored-by: Ruth Comer <10599679+rcomer@users.noreply.github.com>
1 parent fec45c6 commit 95db12f

File tree

2 files changed

+46
-7
lines changed

2 files changed

+46
-7
lines changed

lib/matplotlib/spines.py

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -232,20 +232,30 @@ def _clear(self):
232232
"""
233233
self._position = None # clear position
234234

235-
def _adjust_location(self):
236-
"""Automatically set spine bounds to the view interval."""
237-
238-
if self.spine_type == 'circle':
239-
return
235+
def _get_bounds_or_viewLim(self):
236+
"""
237+
Get the bounds of the spine.
240238
239+
If self._bounds is None, return self.axes.viewLim.intervalx
240+
or self.axes.viewLim.intervaly based on self.spine_type
241+
"""
241242
if self._bounds is not None:
242243
low, high = self._bounds
243244
elif self.spine_type in ('left', 'right'):
244245
low, high = self.axes.viewLim.intervaly
245246
elif self.spine_type in ('top', 'bottom'):
246247
low, high = self.axes.viewLim.intervalx
247248
else:
248-
raise ValueError(f'unknown spine spine_type: {self.spine_type}')
249+
raise ValueError(f'spine_type: {self.spine_type} not supported')
250+
return low, high
251+
252+
def _adjust_location(self):
253+
"""Automatically set spine bounds to the view interval."""
254+
255+
if self.spine_type == 'circle':
256+
return
257+
258+
low, high = self._get_bounds_or_viewLim()
249259

250260
if self._patch_type == 'arc':
251261
if self.spine_type in ('bottom', 'top'):
@@ -424,7 +434,7 @@ def set_bounds(self, low=None, high=None):
424434
'set_bounds() method incompatible with circular spines')
425435
if high is None and np.iterable(low):
426436
low, high = low
427-
old_low, old_high = self.get_bounds() or (None, None)
437+
old_low, old_high = self._get_bounds_or_viewLim()
428438
if low is None:
429439
low = old_low
430440
if high is None:

lib/matplotlib/tests/test_spines.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,3 +166,32 @@ def test_arc_spine_inner_no_axis():
166166
assert ax.spines["inner"].axis is None
167167

168168
fig.draw_without_rendering()
169+
170+
171+
def test_spine_set_bounds_with_none():
172+
"""Test that set_bounds(None, ...) uses original axis view limits."""
173+
fig, ax = plt.subplots()
174+
175+
# Plot some data to set axis limits
176+
x = np.linspace(0, 10, 100)
177+
y = np.sin(x)
178+
ax.plot(x, y)
179+
180+
xlim = ax.viewLim.intervalx
181+
ylim = ax.viewLim.intervaly
182+
# Use modified set_bounds with None
183+
ax.spines['bottom'].set_bounds(2, None)
184+
ax.spines['left'].set_bounds(None, None)
185+
186+
# Check that get_bounds returns correct numeric values
187+
bottom_bound = ax.spines['bottom'].get_bounds()
188+
assert bottom_bound[1] is not None, "Higher bound should be numeric"
189+
assert np.isclose(bottom_bound[0], 2), "Lower bound should match provided value"
190+
assert np.isclose(bottom_bound[1],
191+
xlim[1]), "Upper bound should match original value"
192+
193+
left_bound = ax.spines['left'].get_bounds()
194+
assert (left_bound[0] is not None) and (left_bound[1] is not None), \
195+
"left bound should be numeric"
196+
assert np.isclose(left_bound[0], ylim[0]), "Lower bound should match original value"
197+
assert np.isclose(left_bound[1], ylim[1]), "Upper bound should match original value"

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy