From ad4f117902efc6d36b32ea29e6a49a9af4902857 Mon Sep 17 00:00:00 2001 From: Eric Teunis de Boone Date: Wed, 31 Aug 2022 14:31:51 +0200 Subject: [PATCH] figure: spatial time difference setup --- figures/beacon/Makefile | 3 + .../beacon_spatial_time_difference_setup.py | 172 ++++++++++++++++++ 2 files changed, 175 insertions(+) create mode 100755 figures/beacon/src/beacon_spatial_time_difference_setup.py diff --git a/figures/beacon/Makefile b/figures/beacon/Makefile index c7da1b7..46b9688 100644 --- a/figures/beacon/Makefile +++ b/figures/beacon/Makefile @@ -9,6 +9,9 @@ dist-clean: rm -v sine_beacon.* rm -v ttl_beacon.* +beacon_spatial_time_difference_setup.pdf: src/beacon_spatial_time_difference_setup.py + $< $@ + sine_beacon.%: src/single_beacon.py $< --periods 2 --with-rates sine $@ diff --git a/figures/beacon/src/beacon_spatial_time_difference_setup.py b/figures/beacon/src/beacon_spatial_time_difference_setup.py new file mode 100755 index 0000000..6e6e0db --- /dev/null +++ b/figures/beacon/src/beacon_spatial_time_difference_setup.py @@ -0,0 +1,172 @@ +#!/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() +