""" Mars Express PVAT related plotting.
Prepared panels for matplotlib quick plot are prepared.
"""
import datetime as _datetime
import numpy as _np
import matplotlib.pyplot as _plt
from irfpy.util import utc as _utc
from irfpy.mars import mpb
from irfpy.mars import bowshock
from irfpy.mars import rm
#rm = 3394.0
from irfpy.mexpvat import mexspice as _ms
#_ms.init()
from irfpy.mexpvat import orbnum as _orbnum
_onr = _orbnum.default_orbnum()
from matplotlib.patches import Circle as _Circle, Wedge as _Wedge
[docs]def basic_axis(unit='km', ax=None, marscolor='r', bscolor='r', mpbcolor='r', bslinestyle=':', mpblienstyle='dotted'):
""" Return the axis that contains Mars, default bow shock, and MPB.
:return: The axis object.
"""
if ax is None:
ax = _plt.gca()
if unit.lower() == 'km':
_rm = rm
x0 = -10000
x1 = 10000
elif unit.lower() == 'rm':
_rm = 1.0
x0 = -3
x1 = 3
### Mars bowshock/mpb
bsxr = bowshock.BowshockVignes().xr() * _rm
ax.plot(bsxr[0], bsxr[1], color=bscolor, linestyle=bslinestyle)
ax.plot(bsxr[0], -bsxr[1], color=bscolor, linestyle=bslinestyle)
mpbxr = mpb.MpbVignes().mpb_xr() * _rm
ax.plot(mpbxr[0], mpbxr[1], color=mpbcolor, linestyle=mpblienstyle)
ax.plot(mpbxr[0], -mpbxr[1], color=mpbcolor, linestyle=mpblienstyle)
### Mars body
mars = _Circle((0, 0), _rm, color=marscolor)
ax.add_patch(mars)
mars_n = _Wedge((0, 0), _rm, 90, 270, color='k', alpha=0.7)
ax.add_patch(mars_n)
### Default looking. User can change using ax.set_ method afterword.
ax.set_ylabel('Y [km]')
ax.set_xlabel('X [km]')
ax.set_xlim(x0, x1)
ax.set_ylim(x0, x1)
ax.set_aspect(1)
return ax
[docs]def xr_orbit(onr, target='MEX', frame='MSO', ax=None):
_ms.init() # Note it runs only once.
if ax is None:
fig = _plt.figure()
ax = fig.add_subplot(111)
t0 = _onr.get_start(onr)
t1 = _onr.get_stop(onr)
### Every 20 min, ticks.
t0t = t0.replace(minute=0, second=0) # From the previous 0 minutes
t1t = t1.replace(minute=59, second=59) + _datetime.timedelta(seconds=1) # To the next 0 minutes
tlist = _utc.dtrange(t0t, t1t, _datetime.timedelta(minutes=20))
tlist = [_t for _t in tlist if (_t >= t0 and _t <= t1)] # Filter the time
poses = _ms.get_positions(tlist, target=target, origin='MARS', frame=frame) # (N, 3) shape
x = poses[:, 0]
r = _np.sqrt(poses[:, 1] ** 2 + poses[:, 2] ** 2)
ax.plot(x, r, 'b.')
#### Every 1 hour, label
tlist = _utc.dtrange(t0t, t1t, _datetime.timedelta(hours=1))
tlist = [_t for _t in tlist if (_t >= t0 and _t <= t1)] # Filter the time
poses = _ms.get_positions(tlist, target=target, origin='MARS', frame=frame) # (N, 3) shape
x = poses[:, 0]
r = _np.sqrt(poses[:, 1] ** 2 + poses[:, 2] ** 2)
for _x, _r, _t in zip(x, r, tlist):
ax.text(_x, _r, '{:%H:%M}'.format(_t))
### Every 1 min plot as continuous
dt = _datetime.timedelta(minutes=1)
tlist = _utc.dtrange(t0, t1, dt)
poses = _ms.get_positions(tlist, target=target, origin='MARS', frame=frame) # (N, 3) shape
x = poses[:, 0]
r = _np.sqrt(poses[:, 1] ** 2 + poses[:, 2] ** 2)
ax.plot(x, r, 'b')
### Pericenter marked
tp = _onr.get_pericenter(onr)
poses = _ms.get_position(tp, target=target, origin='MARS', frame=frame)
x = poses[0]
r = _np.sqrt(poses[1] ** 2 + poses[2] ** 2)
ax.plot(x, r, 'bx')
### Mars bowshock/mpb
bsxr = bowshock.BowshockVignes().xr() * rm
ax.plot(bsxr[0], bsxr[1], 'r:')
mpbxr = mpb.MpbVignes().mpb_xr() * rm
ax.plot(mpbxr[0], mpbxr[1], 'r:')
### Mars body
bodyx = rm * _np.cos(_np.linspace(0, _np.pi, 100))
bodyr = rm * _np.sin(_np.linspace(0, _np.pi, 100))
ax.plot(bodyx, bodyr, 'r')
### Default looking. User can change using ax.set_ method afterword.
ax.set_title('Orbit {} / PERI={:%FT%T}'.format(onr, tp))
ax.set_ylabel('R [km]')
ax.set_xlabel('X [km]')
ax.set_xlim(10000, -10000)
ax.set_ylim(0, 20000)
ax.set_aspect(1)
return ax