Skip to content

Commit 62d8d65

Browse files
authored
Merge pull request #8896 from eric-wieser/fix-mplot3d-projection
Fix mplot3d projection
2 parents cb904b1 + 0492b88 commit 62d8d65

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+98
-50
lines changed

lib/matplotlib/axes/_base.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -1499,9 +1499,9 @@ def apply_aspect(self, position=None):
14991499
"""
15001500
Adjust the Axes for a specified data aspect ratio.
15011501
1502-
Depending on `.get_adjustable` this will modify either the Axes box
1503-
(position) or the view limits. In the former case, `.get_anchor`
1504-
will affect the position.
1502+
Depending on `.get_adjustable` this will modify either the
1503+
Axes box (position) or the view limits. In the former case,
1504+
`~matplotlib.axes.Axes.get_anchor` will affect the position.
15051505
15061506
Notes
15071507
-----

lib/mpl_toolkits/mplot3d/axes3d.py

+19-2
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,20 @@ def tunit_edges(self, vals=None, M=None):
255255
(tc[7], tc[4])]
256256
return edges
257257

258+
def apply_aspect(self, position=None):
259+
if position is None:
260+
position = self.get_position(original=True)
261+
262+
# in the superclass, we would go through and actually deal with axis
263+
# scales and box/datalim. Those are all irrelevant - all we need to do
264+
# is make sure our coordinate system is square.
265+
figW, figH = self.get_figure().get_size_inches()
266+
fig_aspect = figH / figW
267+
box_aspect = 1
268+
pb = position.frozen()
269+
pb1 = pb.shrunk_to_aspect(box_aspect, pb, fig_aspect)
270+
self.set_position(pb1.anchored(self.get_anchor(), pb), 'active')
271+
258272
@artist.allow_rasterization
259273
def draw(self, renderer):
260274
# draw the background patch
@@ -950,6 +964,9 @@ def get_proj(self):
950964
951965
dist is the distance of the eye viewing point from the object point.
952966
"""
967+
# chosen for similarity with the initial view before gh-8896
968+
pb_aspect = np.array([4, 4, 3]) / 3.5
969+
953970
relev, razim = np.pi * self.elev/180, np.pi * self.azim/180
954971

955972
xmin, xmax = self.get_xlim3d()
@@ -959,10 +976,10 @@ def get_proj(self):
959976
# transform to uniform world coordinates 0-1, 0-1, 0-1
960977
worldM = proj3d.world_transformation(xmin, xmax,
961978
ymin, ymax,
962-
zmin, zmax)
979+
zmin, zmax, pb_aspect=pb_aspect)
963980

964981
# look into the middle of the new coordinates
965-
R = np.array([0.5, 0.5, 0.5])
982+
R = pb_aspect / 2
966983

967984
xp = R[0] + np.cos(razim) * np.cos(relev) * self.dist
968985
yp = R[1] + np.sin(razim) * np.cos(relev) * self.dist

lib/mpl_toolkits/mplot3d/proj3d.py

+14-2
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,20 @@ def _line2d_seg_dist(p1, p2, p0):
3030

3131
def world_transformation(xmin, xmax,
3232
ymin, ymax,
33-
zmin, zmax):
34-
dx, dy, dz = (xmax-xmin), (ymax-ymin), (zmax-zmin)
33+
zmin, zmax, pb_aspect=None):
34+
"""
35+
produce a matrix that scales homogenous coords in the specified ranges
36+
to [0, 1], or [0, pb_aspect[i]] if the plotbox aspect ratio is specified
37+
"""
38+
dx = xmax - xmin
39+
dy = ymax - ymin
40+
dz = zmax - zmin
41+
if pb_aspect is not None:
42+
ax, ay, az = pb_aspect
43+
dx /= ax
44+
dy /= ay
45+
dz /= az
46+
3547
return np.array([[1/dx, 0, 0, -xmin/dx],
3648
[0, 1/dy, 0, -ymin/dy],
3749
[0, 0, 1/dz, -zmin/dz],

0 commit comments

Comments
 (0)