173 lines
4.1 KiB
Python
173 lines
4.1 KiB
Python
|
#!/usr/bin/env python3
|
||
|
|
||
|
__doc__ = \
|
||
|
"""
|
||
|
Generate a figure showing why a single beacon does
|
||
|
not arrive at the same time at two antennas.
|
||
|
"""
|
||
|
|
||
|
import matplotlib.pyplot as plt
|
||
|
import numpy as np
|
||
|
import scipy.signal as sig
|
||
|
|
||
|
### Functions
|
||
|
|
||
|
def beacon_time_difference_setup_figure(
|
||
|
ax,
|
||
|
loc_trans, loc_antenna1, loc_antenna2,
|
||
|
trans_kwargs={}, ant_kwargs={}
|
||
|
):
|
||
|
"""
|
||
|
"""
|
||
|
return t, ants
|
||
|
|
||
|
|
||
|
def _annotate_width(
|
||
|
ax, name,
|
||
|
x1, x2, y1=None, y2=None,
|
||
|
text_dx=(0,0),
|
||
|
text_kw={}, arrow_kw={}
|
||
|
):
|
||
|
"""
|
||
|
Annotate a width between two points, with both an arrow between
|
||
|
the points, and a text between them.
|
||
|
|
||
|
Parameters:
|
||
|
-----------
|
||
|
ax: Axes
|
||
|
the Axes to plot on
|
||
|
name: str
|
||
|
text to put on top of the arrow
|
||
|
x1: float or tuple
|
||
|
(horizontal) location of the first point
|
||
|
x2: float or tuple
|
||
|
(horizontal) location of the first point
|
||
|
y1: float
|
||
|
vertical location of the first point
|
||
|
y2: float
|
||
|
vertical location of the first point
|
||
|
|
||
|
"""
|
||
|
if hasattr(x1, '__len__'):
|
||
|
if y1 is None:
|
||
|
y1 = x1[1]
|
||
|
x1 = x1[0]
|
||
|
|
||
|
if hasattr(x2, '__len__'):
|
||
|
if y2 is None:
|
||
|
y2 = x2[1]
|
||
|
x2 = x2[0]
|
||
|
|
||
|
y1 = 0 if y1 is None else y1
|
||
|
y2 = y1 if y2 is None else y2
|
||
|
|
||
|
default_arrow_kw = dict(
|
||
|
xy = (x1, y1),
|
||
|
xytext = (x2,y2),
|
||
|
arrowprops = dict(
|
||
|
arrowstyle="<->",
|
||
|
shrinkA=False,
|
||
|
shrinkB=False
|
||
|
),
|
||
|
)
|
||
|
|
||
|
default_text_kw = dict(
|
||
|
va='bottom',
|
||
|
ha='center',
|
||
|
xy=((x1+x2)/2 + text_dx[0], (y1+y2)/2 + text_dx[1])
|
||
|
)
|
||
|
|
||
|
an1 = ax.annotate("", **{**default_arrow_kw, **arrow_kw})
|
||
|
an2 = ax.annotate(name, **{**default_text_kw, **text_kw})
|
||
|
|
||
|
return [an1, an2]
|
||
|
|
||
|
|
||
|
## Main
|
||
|
def main():
|
||
|
"""
|
||
|
"""
|
||
|
|
||
|
trans_kwargs = {
|
||
|
'zorder': 4,
|
||
|
}
|
||
|
ant_kwargs = {
|
||
|
'zorder': 4,
|
||
|
}
|
||
|
annot_kwargs = {
|
||
|
}
|
||
|
|
||
|
trans_loc = [0.2, 0.9]
|
||
|
ant1_loc = [0.2, 0.4]
|
||
|
ant2_loc = [0.4, 0.2]
|
||
|
|
||
|
###########################
|
||
|
fig, ax = plt.subplots(1,1,sharex=True, gridspec_kw={'hspace': 0});
|
||
|
|
||
|
# Overall styling
|
||
|
if True:
|
||
|
ax.set_aspect('equal')
|
||
|
ax.spines['top'].set_visible(False)
|
||
|
ax.spines['right'].set_visible(False)
|
||
|
ax.spines['bottom'].set_visible(False)
|
||
|
ax.spines['left'].set_visible(False)
|
||
|
|
||
|
#ax.axis('off')
|
||
|
ax.set_xticks([])
|
||
|
ax.set_xticklabels([])
|
||
|
#ax.set_ylim(-0.2, 1.2)
|
||
|
#ax.set_xlim(0, 1)
|
||
|
#ax.set_ylim(0, 1)
|
||
|
ax.set_yticks([])
|
||
|
ax.set_yticklabels([])
|
||
|
|
||
|
# Transmitter
|
||
|
t = ax.plot(*trans_loc, '*', **trans_kwargs)
|
||
|
ax.annotate('T', xy=trans_loc, ha='right', va='bottom')
|
||
|
|
||
|
# Antenna
|
||
|
ants = []
|
||
|
annoti_kwargs = [
|
||
|
dict(text_kw=dict(va='center', ha='left')),
|
||
|
dict(text_kw=dict(ha='left'))
|
||
|
]
|
||
|
for i, loc in enumerate([ant1_loc, ant2_loc], start=1):
|
||
|
ants.append(
|
||
|
ax.plot(*loc, '*', **ant_kwargs)
|
||
|
)
|
||
|
|
||
|
## Distance between Antenna and Transmitter
|
||
|
default_annot_kwargs = {
|
||
|
}
|
||
|
_annotate_width(ax, f"$t_{i}$", trans_loc, loc, **{**default_annot_kwargs, **annot_kwargs, **annoti_kwargs[i-1]} )
|
||
|
|
||
|
if True:
|
||
|
ax.annotate(f"$A_{i}$", xy=loc, ha='right', va='top')
|
||
|
|
||
|
# Distance between two antennas
|
||
|
_annotate_width(ax, f"$t_d$", ant1_loc, ant2_loc, text_kw=dict(ha='right', va='top'))
|
||
|
|
||
|
return fig, 0
|
||
|
|
||
|
|
||
|
if __name__ == "__main__":
|
||
|
from argparse import ArgumentParser
|
||
|
import os.path as path
|
||
|
|
||
|
parser = ArgumentParser(description=__doc__)
|
||
|
parser.add_argument("fname", metavar="path/to/figure[/]", nargs="?", help="Location for generated figure, will append __file__ if a directory. If not supplied, figure is shown.")
|
||
|
|
||
|
args = parser.parse_args()
|
||
|
|
||
|
if args.fname is not None and path.isdir(args.fname):
|
||
|
args.fname = path.join(args.fname, path.splitext(path.basename(__file__))[0] + ".pdf")
|
||
|
|
||
|
###
|
||
|
fig, _ = main()
|
||
|
|
||
|
if args.fname is not None:
|
||
|
plt.savefig(args.fname)
|
||
|
else:
|
||
|
plt.show()
|
||
|
|