#!/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.9, 0] ant1_loc = [0.2, 0] ant2_loc = [0.3, -0.4] ########################### fig, ax = plt.subplots(1,1,sharex=True, gridspec_kw={'hspace': 0}, figsize=(5,2)) # 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='bottom', ha='left')), dict(text_kw=dict(va='top', ha='right')) ] 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"$d_{i}$", trans_loc, loc, text_dx=(0,0.001), **{**default_annot_kwargs, **annot_kwargs, **annoti_kwargs[i-1]} ) if True: ax.annotate(f"$A_{i}$", xy=loc, ha='left', va=['bottom', 'top'][i-1]) # Distance between two antennas _annotate_width(ax, f"$d_{{12}}$", ant1_loc, ant2_loc, text_dx=(0.01,0), text_kw=dict(ha='left', 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()