设置matplotlib 3d绘图长宽比?

时间:2011-11-15 02:35:28

标签: python matplotlib

import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

设置宽高比适用于2d图:

ax = plt.axes()
ax.plot([0,1],[0,10])
ax.set_aspect('equal','box')

但不适用于3D:

ax = plt.axes(projection='3d')
ax.plot([0,1],[0,1],[0,10])
ax.set_aspect('equal','box')

是否有不同的3d案例语法,或者没有实现?

8 个答案:

答案 0 :(得分:21)

我没有尝试所有这些答案,但这个kludge为我做了这个:

def axisEqual3D(ax):
    extents = np.array([getattr(ax, 'get_{}lim'.format(dim))() for dim in 'xyz'])
    sz = extents[:,1] - extents[:,0]
    centers = np.mean(extents, axis=1)
    maxsize = max(abs(sz))
    r = maxsize/2
    for ctr, dim in zip(centers, 'xyz'):
        getattr(ax, 'set_{}lim'.format(dim))(ctr - r, ctr + r)

答案 1 :(得分:15)

看起来这个功能已被添加,所以我想为未来的人提供一个答案,就像我一样:

fig = plt.figure(figsize=plt.figaspect(0.5)*1.5) #Adjusts the aspect ratio and enlarges the figure (text does not enlarge)
ax = fig.gca(projection='3d')

figaspect(0.5)使得这个数字的高度是它的两倍。然后*1.5增加了数字的大小。标签等不会增加,因此这是一种使图形看起来不那么混乱的方法。

答案 2 :(得分:11)

如果你知道边界,例如。 + -3以(0,0,0)为中心,你可以添加这样的不可见点:

import numpy as np
import pylab as pl
from mpl_toolkits.mplot3d import Axes3D
fig = pl.figure()
ax = fig.gca(projection='3d')
ax.set_aspect('equal')
MAX = 3
for direction in (-1, 1):
    for point in np.diag(direction * MAX * np.array([1,1,1])):
        ax.plot([point[0]], [point[1]], [point[2]], 'w')

答案 3 :(得分:10)

从matplotlib 3.3.0开始,Axes3D.set_box_aspect似乎是推荐的方法。

import numpy as np
import matplotlib.pyplot as plt

xs, ys, zs = ...
ax = plt.axes(projection='3d')

ax.set_box_aspect((np.ptp(xs), np.ptp(ys), np.ptp(zs)))  # aspect ratio is 1:1:1 in data space

ax.plot(xs, ys, zs)

答案 4 :(得分:7)

如果你知道界限,你也可以这样设置纵横比:

ax.auto_scale_xyz([minbound, maxbound], [minbound, maxbound], [minbound, maxbound])

答案 5 :(得分:4)

我认为设置正确的“盒子方面”是一个很好的解决方案:

ax.set_box_aspect(aspect = (1,1,1))

ID     DATE START      DATE END
1      2020-10-16     2020-12-11
1      2020-11-09     2021-01-02     
1      2020-12-11     2021-01-19
1      2021-01-02     2020-12-11
1      2021-01-19     2050-12-31

https://matplotlib.org/stable/api/_as_gen/mpl_toolkits.mplot3d.axes3d.Axes3D.html?highlight=3d%20set_box_aspect#mpl_toolkits.mplot3d.axes3d.Axes3D.set_box_aspect

答案 6 :(得分:3)

我的理解基本上还没有实现。我也希望很快就能实施。请参阅This link了解可能的解决方案(我自己没有测试过)。

答案 7 :(得分:1)

另一个有用(希望)的解决方案,例如,当有必要更新已经存在的图形时:

world_limits = ax.get_w_lims()
ax.set_box_aspect((world_limits[1]-world_limits[0],world_limits[3]-world_limits[2],world_limits[5]-world_limits[4]))

get_w_lims()

set_box_aspect()