hat*_*rix 36 python matplotlib
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
Run Code Online (Sandbox Code Playgroud)
设置宽高比适用于2d图:
ax = plt.axes()
ax.plot([0,1],[0,10])
ax.set_aspect('equal','box')
Run Code Online (Sandbox Code Playgroud)
但不适用于3D:
ax = plt.axes(projection='3d')
ax.plot([0,1],[0,1],[0,10])
ax.set_aspect('equal','box')
Run Code Online (Sandbox Code Playgroud)
是否有不同的3d案例语法,或者它没有实现?
小智 28
从 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)
Run Code Online (Sandbox Code Playgroud)
Ben*_*Ben 22
我没有尝试所有这些答案,但这个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)
Run Code Online (Sandbox Code Playgroud)
Dan*_*Dan 18
看起来这个功能已被添加,所以我想我会为将来通过这个帖子的人添加一个答案,就像我做的那样:
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')
Run Code Online (Sandbox Code Playgroud)
figaspect(0.5)这个数字是它的两倍宽.然后*1.5增加图的大小.标签等不会增加,因此这是一种使图形看起来不那么混乱的方法.
Jen*_*man 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')
Run Code Online (Sandbox Code Playgroud)
如果你知道边界,你也可以这样设置宽高比:
ax.auto_scale_xyz([minbound, maxbound], [minbound, maxbound], [minbound, maxbound])
Run Code Online (Sandbox Code Playgroud)
小智 8
我认为设置正确的“盒子方面”是一个很好的解决方案:
ax.set_box_aspect(aspect = (1,1,1))
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.gca(projection='3d')
ax.set_box_aspect(aspect = (1,1,1))
ax.plot(dataX,dataY,dataZ)
Run Code Online (Sandbox Code Playgroud)
从 matplotlib 3.6.0 开始,此功能已添加到ax.set_aspect. 使用:
ax.set_aspect('equal')
Run Code Online (Sandbox Code Playgroud)
其他选项包括'equalxy'、'equalxz'和'equalyz',仅将两个方向设置为相等的长宽比。这会更改数据限制,如下例。
在即将推出的 3.7.0 中,您将能够通过以下方式更改绘图框的纵横比而不是数据限制:
ax.set_aspect('equal', adjustable='box')
Run Code Online (Sandbox Code Playgroud)
(感谢@tfpf 在另一个答案中实现了这一点!)要获得原始行为,请使用adjustable='datalim'.
马特·潘泽 (Matt Panzer) 的回答的后续行动。(这最初是对上述答案的评论。)
limits = np.array([getattr(ax, f'get_{axis}lim')() for axis in 'xyz'])
ax.set_box_aspect(np.ptp(limits, axis=1))
Run Code Online (Sandbox Code Playgroud)
现在这个拉取请求已经合并,当 Matplotlib 的下一个版本发布时,您应该能够使用ax.set_aspect('equal'). 当这种情况发生时,我会尽力记住并更新这个答案。
更新:Matplotlib 3.6 已发布;ax.set_aspect('equal')现在将按预期工作。
小智 5
例如,当需要更新现有的图形时,另一个有用的(希望如此)解决方案:
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]))
Run Code Online (Sandbox Code Playgroud)
我的理解基本上是,这还没有实现(请参阅GitHub 中的此错误)。我也希望它能够尽快实施。请参阅此链接以获取可能的解决方案(我自己尚未测试过)。
| 归档时间: |
|
| 查看次数: |
24454 次 |
| 最近记录: |