首先完全免责声明,我是python的新手,我的问题可能很愚蠢,但据我的研究告诉我,matplotlib
中似乎没有支持的方法可以完成我想要的事情。 / p>
我必须绘制“三体问题”的轨迹,并且尝试使用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')
。这些都不起作用。
我发现的第一个最接近的东西是这个answer,它基本上会创建一个盒子,以便所有轴的尺寸都相同。这可以解决问题,但是在我的情况下,其中一个维度比其他维度大得多,这会导致大量的空间浪费:
Plot with the solution that creates a box
最后,我能找到的最好的东西是here中的解决方案,它需要修改文件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]))
结果为this。如果仔细观察,图不会居中,并且根据方向,并非所有数据都在绘图区域内。现在,我将使用最后一种方法,但是在完成所有研究之后,我仍然无法相信绘图工具不应该支持像这样的东西(就我而言,这在其他所有方面都很棒)知道),因此我的问题是:我是否遗漏了明显的东西?
预先感谢:)