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

Skip to content

Commit cd70bba

Browse files
committed
Changed axis selection when zooming datalim-adjustable fixed-aspect axes
When aspect is set and adjustable="datalim", should we change the x limits or the y limits to get the correct aspect? The old code used some complex conditions, which I actually haven't managed to fully understand, to either expand or shrink one of the axises. Instead, just choose to always expand (rather than shrink) one of the axises, which will avoid sending artists out-of-bounds. (The sole exception is in care of shared axes, which we do not touch as explained in the comment.) This patch caused a change in the autolimiting of test_axes.py::test_pie_frame_grid which was buggy anyways, I forced the old behavior by setting x/ylims manually (after checking that the default is to expand the limits).
1 parent 303873f commit cd70bba

File tree

2 files changed

+35
-41
lines changed

2 files changed

+35
-41
lines changed

lib/matplotlib/axes/_base.py

Lines changed: 28 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1898,55 +1898,42 @@ def apply_aspect(self, position=None):
18981898
box_aspect = fig_aspect * (position.height / position.width)
18991899
data_ratio = box_aspect / aspect
19001900

1901-
y_expander = data_ratio * xsize / ysize - 1
1902-
# If y_expander > 0, the dy/dx viewLim ratio needs to increase
1903-
if abs(y_expander) < 0.005:
1901+
y_expander = data_ratio * xsize / ysize
1902+
# If y_expander > 1, the dy/dx viewLim ratio needs to increase
1903+
if abs(y_expander - 1) < 0.005:
19041904
return
19051905

1906-
dL = self.dataLim
1907-
x0, x1 = x_trf.transform(dL.intervalx)
1908-
y0, y1 = y_trf.transform(dL.intervaly)
1909-
xr = 1.05 * (x1 - x0)
1910-
yr = 1.05 * (y1 - y0)
1911-
1912-
xmarg = xsize - xr
1913-
ymarg = ysize - yr
1914-
Ysize = data_ratio * xsize
1915-
Xsize = ysize / data_ratio
1916-
Xmarg = Xsize - xr
1917-
Ymarg = Ysize - yr
1918-
# Setting these targets to, e.g., 0.05*xr does not seem to help.
1919-
xm = 0
1920-
ym = 0
1921-
1906+
# What axes do we adjust?
1907+
# - We can't adjust shared axes because it's too easy to break sharing
1908+
# given the sequential handling of axes (that may be possible if we
1909+
# first collected all the constraints on all axes and considered them
1910+
# all at once).
1911+
# - Assuming no constraints from sharing, prefer expanding axes rather
1912+
# than shrinking them, as the latter can hide plot elements.
19221913
shared_x = self in self._shared_x_axes
19231914
shared_y = self in self._shared_y_axes
1924-
# Not sure whether we need this check:
19251915
if shared_x and shared_y:
19261916
raise RuntimeError("adjustable='datalim' is not allowed when both "
19271917
"axes are shared")
1928-
1929-
# If y is shared, then we are only allowed to change x, etc.
1930-
if shared_y:
1931-
adjust_y = False
1932-
else:
1933-
if xmarg > xm and ymarg > ym:
1934-
adjy = ((Ymarg > 0 and y_expander < 0) or
1935-
(Xmarg < 0 and y_expander > 0))
1936-
else:
1937-
adjy = y_expander > 0
1938-
adjust_y = shared_x or adjy # (Ymarg > xmarg)
1939-
1940-
if adjust_y:
1941-
yc = 0.5 * (ymin + ymax)
1942-
y0 = yc - Ysize / 2.0
1943-
y1 = yc + Ysize / 2.0
1944-
self.set_ybound(y_trf.inverted().transform([y0, y1]))
1918+
if shared_x:
1919+
adjust = "y"
1920+
elif shared_y:
1921+
adjust = "x"
1922+
elif y_expander > 1:
1923+
adjust = "y"
1924+
else: # y_expander < 1
1925+
adjust = "x"
1926+
1927+
if adjust == "y":
1928+
yc = (ymin + ymax) / 2
1929+
ymin = yc - (yc - ymin) * y_expander
1930+
ymax = yc + (ymax - yc) * y_expander
1931+
self.set_ybound(*map(y_trf.inverted().transform, (ymin, ymax)))
19451932
else:
1946-
xc = 0.5 * (xmin + xmax)
1947-
x0 = xc - Xsize / 2.0
1948-
x1 = xc + Xsize / 2.0
1949-
self.set_xbound(x_trf.inverted().transform([x0, x1]))
1933+
xc = (xmin + xmax) / 2
1934+
xmin = xc - (xc - xmin) / y_expander
1935+
xmax = xc + (xmax - xc) / y_expander
1936+
self.set_xbound(*map(x_trf.inverted().transform, (xmin, xmax)))
19501937

19511938
def axis(self, *args, emit=True, **kwargs):
19521939
"""

lib/matplotlib/tests/test_axes.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5039,6 +5039,13 @@ def test_pie_frame_grid():
50395039
frame=True, center=(3, 5))
50405040
# Set aspect ratio to be equal so that pie is drawn as a circle.
50415041
plt.axis('equal')
5042+
plt.gcf().canvas.draw()
5043+
xmin, xmax = plt.xlim()
5044+
ymin, ymax = plt.ylim()
5045+
assert xmin < 0 and xmax > 7 and ymin == 0 and ymax == 7
5046+
# These limits reproduce an old, buggy implementation of axis("equal").
5047+
plt.xlim(0, 7)
5048+
plt.ylim(0.7903225806451615, 6.209677419354838)
50425049

50435050

50445051
@image_comparison(['pie_rotatelabels_true.png'])

0 commit comments

Comments
 (0)