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

Skip to content

Commit c8b6105

Browse files
authored
Merge pull request #14579 from anntzer/3dinvert
Fix inversion of 3d axis.
2 parents b88d6b5 + 0e41317 commit c8b6105

File tree

3 files changed

+82
-83
lines changed

3 files changed

+82
-83
lines changed

lib/matplotlib/axis.py

Lines changed: 38 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1890,6 +1890,36 @@ def get_minpos(self):
18901890
raise NotImplementedError()
18911891

18921892

1893+
def _make_getset_interval(method_name, lim_name, attr_name):
1894+
"""
1895+
Helper to generate ``get_{data,view}_interval`` and
1896+
``set_{data,view}_interval`` implementations.
1897+
"""
1898+
1899+
def getter(self):
1900+
# docstring inherited.
1901+
return getattr(getattr(self.axes, lim_name), attr_name)
1902+
1903+
def setter(self, vmin, vmax, ignore=False):
1904+
# docstring inherited.
1905+
if ignore:
1906+
setattr(getattr(self.axes, lim_name), attr_name, (vmin, vmax))
1907+
else:
1908+
oldmin, oldmax = getter(self)
1909+
if oldmin < oldmax:
1910+
setter(self, min(vmin, vmax, oldmin), max(vmin, vmax, oldmax),
1911+
ignore=True)
1912+
else:
1913+
setter(self, max(vmin, vmax, oldmax), min(vmin, vmax, oldmin),
1914+
ignore=True)
1915+
self.stale = True
1916+
1917+
getter.__name__ = f"get_{method_name}_interval"
1918+
setter.__name__ = f"set_{method_name}_interval"
1919+
1920+
return getter, setter
1921+
1922+
18931923
class XAxis(Axis):
18941924
__name__ = 'xaxis'
18951925
axis_name = 'x'
@@ -2133,39 +2163,14 @@ def get_ticks_position(self):
21332163
"default": "default", "unknown": "unknown"}[
21342164
self._get_ticks_position()]
21352165

2136-
def get_view_interval(self):
2137-
# docstring inherited
2138-
return self.axes.viewLim.intervalx
2139-
2140-
def set_view_interval(self, vmin, vmax, ignore=False):
2141-
# docstring inherited
2142-
if ignore:
2143-
self.axes.viewLim.intervalx = vmin, vmax
2144-
else:
2145-
Vmin, Vmax = self.get_view_interval()
2146-
if Vmin < Vmax:
2147-
self.axes.viewLim.intervalx = (min(vmin, vmax, Vmin),
2148-
max(vmin, vmax, Vmax))
2149-
else:
2150-
self.axes.viewLim.intervalx = (max(vmin, vmax, Vmin),
2151-
min(vmin, vmax, Vmax))
2166+
get_view_interval, set_view_interval = _make_getset_interval(
2167+
"view", "viewLim", "intervalx")
2168+
get_data_interval, set_data_interval = _make_getset_interval(
2169+
"data", "dataLim", "intervalx")
21522170

21532171
def get_minpos(self):
21542172
return self.axes.dataLim.minposx
21552173

2156-
def get_data_interval(self):
2157-
# docstring inherited
2158-
return self.axes.dataLim.intervalx
2159-
2160-
def set_data_interval(self, vmin, vmax, ignore=False):
2161-
# docstring inherited
2162-
if ignore:
2163-
self.axes.dataLim.intervalx = vmin, vmax
2164-
else:
2165-
Vmin, Vmax = self.get_data_interval()
2166-
self.axes.dataLim.intervalx = min(vmin, Vmin), max(vmax, Vmax)
2167-
self.stale = True
2168-
21692174
def set_default_intervals(self):
21702175
# docstring inherited
21712176
xmin, xmax = 0., 1.
@@ -2460,40 +2465,14 @@ def get_ticks_position(self):
24602465
"default": "default", "unknown": "unknown"}[
24612466
self._get_ticks_position()]
24622467

2463-
def get_view_interval(self):
2464-
# docstring inherited
2465-
return self.axes.viewLim.intervaly
2466-
2467-
def set_view_interval(self, vmin, vmax, ignore=False):
2468-
# docstring inherited
2469-
if ignore:
2470-
self.axes.viewLim.intervaly = vmin, vmax
2471-
else:
2472-
Vmin, Vmax = self.get_view_interval()
2473-
if Vmin < Vmax:
2474-
self.axes.viewLim.intervaly = (min(vmin, vmax, Vmin),
2475-
max(vmin, vmax, Vmax))
2476-
else:
2477-
self.axes.viewLim.intervaly = (max(vmin, vmax, Vmin),
2478-
min(vmin, vmax, Vmax))
2479-
self.stale = True
2468+
get_view_interval, set_view_interval = _make_getset_interval(
2469+
"view", "viewLim", "intervaly")
2470+
get_data_interval, set_data_interval = _make_getset_interval(
2471+
"data", "dataLim", "intervaly")
24802472

24812473
def get_minpos(self):
24822474
return self.axes.dataLim.minposy
24832475

2484-
def get_data_interval(self):
2485-
# docstring inherited
2486-
return self.axes.dataLim.intervaly
2487-
2488-
def set_data_interval(self, vmin, vmax, ignore=False):
2489-
# docstring inherited
2490-
if ignore:
2491-
self.axes.dataLim.intervaly = vmin, vmax
2492-
else:
2493-
Vmin, Vmax = self.get_data_interval()
2494-
self.axes.dataLim.intervaly = min(vmin, Vmin), max(vmax, Vmax)
2495-
self.stale = True
2496-
24972476
def set_default_intervals(self):
24982477
# docstring inherited
24992478
ymin, ymax = 0., 1.

lib/mpl_toolkits/mplot3d/axis3d.py

Lines changed: 32 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,6 @@ def __init__(self, adir, v_intervalx, d_intervalx, axes, *args,
6868
rotate_label=None, **kwargs):
6969
# adir identifies which axes this is
7070
self.adir = adir
71-
# data and viewing intervals for this direction
72-
self.d_interval = d_intervalx
73-
self.v_interval = v_intervalx
7471

7572
# This is a temporary member variable.
7673
# Do not depend on this existing in future releases!
@@ -105,6 +102,10 @@ def __init__(self, adir, v_intervalx, d_intervalx, axes, *args,
105102
})
106103

107104
maxis.XAxis.__init__(self, axes, *args, **kwargs)
105+
106+
# data and viewing intervals for this direction
107+
self.d_interval = d_intervalx
108+
self.v_interval = v_intervalx
108109
self.set_rotate_label(rotate_label)
109110

110111
def init3d(self):
@@ -420,42 +421,49 @@ def draw(self, renderer):
420421
renderer.close_group('axis3d')
421422
self.stale = False
422423

423-
def get_view_interval(self):
424-
# docstring inherited
425-
return self.v_interval
426-
427-
def set_view_interval(self, vmin, vmax, ignore=False):
428-
# docstring inherited
429-
if ignore:
430-
self.v_interval = vmin, vmax
431-
else:
432-
Vmin, Vmax = self.get_view_interval()
433-
self.v_interval = min(vmin, Vmin), max(vmax, Vmax)
434-
435424
# TODO: Get this to work properly when mplot3d supports
436425
# the transforms framework.
437426
def get_tightbbox(self, renderer):
438427
# Currently returns None so that Axis.get_tightbbox
439428
# doesn't return junk info.
440429
return None
441430

431+
@property
432+
def d_interval(self):
433+
return self.get_data_interval()
434+
435+
@d_interval.setter
436+
def d_interval(self, minmax):
437+
return self.set_data_interval(*minmax)
438+
439+
@property
440+
def v_interval(self):
441+
return self.get_view_interval()
442+
443+
@d_interval.setter
444+
def v_interval(self, minmax):
445+
return self.set_view_interval(*minmax)
446+
442447

443448
# Use classes to look at different data limits
444449

445450

446451
class XAxis(Axis):
447-
def get_data_interval(self):
448-
# docstring inherited
449-
return self.axes.xy_dataLim.intervalx
452+
get_view_interval, set_view_interval = maxis._make_getset_interval(
453+
"view", "xy_viewLim", "intervalx")
454+
get_data_interval, set_data_interval = maxis._make_getset_interval(
455+
"data", "xy_dataLim", "intervalx")
450456

451457

452458
class YAxis(Axis):
453-
def get_data_interval(self):
454-
# docstring inherited
455-
return self.axes.xy_dataLim.intervaly
459+
get_view_interval, set_view_interval = maxis._make_getset_interval(
460+
"view", "xy_viewLim", "intervaly")
461+
get_data_interval, set_data_interval = maxis._make_getset_interval(
462+
"data", "xy_dataLim", "intervaly")
456463

457464

458465
class ZAxis(Axis):
459-
def get_data_interval(self):
460-
# docstring inherited
461-
return self.axes.zz_dataLim.intervalx
466+
get_view_interval, set_view_interval = maxis._make_getset_interval(
467+
"view", "zz_viewLim", "intervalx")
468+
get_data_interval, set_data_interval = maxis._make_getset_interval(
469+
"data", "zz_dataLim", "intervalx")

lib/mpl_toolkits/tests/test_mplot3d.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -801,6 +801,18 @@ def test_line3d_set_get_data_3d():
801801
np.testing.assert_array_equal((x2, y2, z2), line.get_data_3d())
802802

803803

804+
@check_figures_equal(extensions=["png"])
805+
def test_inverted(fig_test, fig_ref):
806+
# Plot then invert.
807+
ax = fig_test.add_subplot(projection="3d")
808+
ax.plot([1, 1, 10, 10], [1, 10, 10, 10], [1, 1, 1, 10])
809+
ax.invert_yaxis()
810+
# Invert then plot.
811+
ax = fig_ref.add_subplot(projection="3d")
812+
ax.invert_yaxis()
813+
ax.plot([1, 1, 10, 10], [1, 10, 10, 10], [1, 1, 1, 10])
814+
815+
804816
def test_inverted_cla():
805817
# Github PR #5450. Setting autoscale should reset
806818
# axes to be non-inverted.

0 commit comments

Comments
 (0)