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

Appearance settings

Commit c8b6105

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

File tree

Expand file treeCollapse file tree

3 files changed

+82
-83
lines changed
Filter options
Expand file treeCollapse file tree

3 files changed

+82
-83
lines changed

‎lib/matplotlib/axis.py

Copy file name to clipboardExpand all lines: lib/matplotlib/axis.py
+38-59Lines 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

Copy file name to clipboardExpand all lines: lib/mpl_toolkits/mplot3d/axis3d.py
+32-24Lines 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

Copy file name to clipboardExpand all lines: lib/mpl_toolkits/tests/test_mplot3d.py
+12Lines 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 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.