首先,完全免责声明,我是 python 新手,我的问题可能很愚蠢,但据我的研究告诉我,似乎没有支持的方式matplotlib来做我想做的事。
我必须绘制三体问题的轨迹,并且我正在尝试使用 python 来减少对它的依赖Matlab(这是他们在我的大学教授的内容)。在这些图中,地球和月球都出现了,对我来说重要的是它们看起来是球形的。下一个代码给出了一个我必须绘制的基本示例:
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D, proj3d # Needed to 3Dplots
plt.close('all') # Close plots of previous scripts
#Data
Er = 0.0166 # Earth radius
Mr = 0.0045 # Moon radius
mu = 0.01215 # Mass parameter
#
def plotCC(ax,rad,pos): # Plot celestial bodies
u = np.linspace(0, 2 * np.pi, 53)
v = np.linspace(0, np.pi, 53)
x = pos + rad * np.outer(np.cos(u), np.sin(v))
y = rad * np.outer(np.sin(u), np.sin(v))
z = rad * np.outer(np.ones(np.size(u)), np.cos(v))
ax.plot_surface(x, y, z)
# Dummy Halo orbit
u = np.linspace(0, 2 * np.pi, 30)
xh = (1-mu)*np.ones(len(u))
yh = 20*Mr*np.sin(u)
zh = 0.12 + 30*Mr*np.cos(u)
# Dummy trajectory
xt = np.linspace(1-mu,-mu,20)
yt = (xt-(1-mu))*(xt+mu)*-1.2
zt = (xt-(1-mu))*(xt+mu)*-0.8
使用它我可以绘制我需要的所有内容:
# Plots
fig = plt.figure(figsize=(8,8))
ax = fig.gca(projection='3d',proj_type = 'ortho')
ax.plot(xh,yh,zh, lw=1.2) # Plot Halo orbit
ax.plot(xt,yt,zt, lw=1.2) # Plot trajectory
plotCC(ax,Mr,1-mu) # Plot Moon
plotCC(ax,Er,-mu) # Plot Earth
结果是:
这远远不是我需要的,因为没有一个天体被表示为球体。我认为可以将纵横比配置为与表示的数据相匹配,但我发现的所有受支持的方法似乎都不能做到这一点。这些方法是:ax.axis('equal'), ax.set_aspect('equal'), ax.axis('scaled'), ax.set_aspect('equal', adjustable='box'), ax.set_aspect('equal', adjustable='datalim'). 这些都不行。
我发现的第一个最接近的东西是这个答案,它基本上创建了一个框,以便所有轴测量相同。这可以解决问题,但在我的情况下,其中一个维度比其他维度大得多,这会导致大量空间浪费:
最后,我能找到的最好的东西是这里的解决方案,它需要修改文件axes.py以便get_proj()接受你给它的纵横比:
ay = (ax.get_ylim3d()[1]-ax.get_ylim3d()[0])/(ax.get_xlim3d()[1]-ax.get_xlim3d()[0])
az = (ax.get_zlim3d()[1]-ax.get_zlim3d()[0])/(ax.get_xlim3d()[1]-ax.get_xlim3d()[0])
ax.pbaspect = list(1.8*np.array([1,ay,az]))
结果是这样的。如果您仔细观察,该图并未居中,并且根据方向,并非所有数据都在绘图区域内。现在我将使用最后一种方法,但是经过我所做的所有研究后,我仍然无法相信绘图工具不支持这样的东西(就我而言,这在其他所有方面都很棒知道),因此我的问题是:我是否遗漏了一些明显的东西?
提前致谢 :)