From 0e5b23aa24917bdf26f5530210253355fc6a41e3 Mon Sep 17 00:00:00 2001 From: Eric Teunis de Boone Date: Thu, 24 Feb 2022 18:19:40 +0100 Subject: [PATCH] Figure Reference clocks with two Signals --- figures/clocks/reference-clock.pdf | Bin 0 -> 37773 bytes figures/clocks/src/reference-clock.py | 176 ++++++++++++++++++++++++++ 2 files changed, 176 insertions(+) create mode 100644 figures/clocks/reference-clock.pdf create mode 100755 figures/clocks/src/reference-clock.py diff --git a/figures/clocks/reference-clock.pdf b/figures/clocks/reference-clock.pdf new file mode 100644 index 0000000000000000000000000000000000000000..1016fd77a701f6f222a081587da9ed9fa79e3597 GIT binary patch literal 37773 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 aboLI0b`A%x90DmUgdkvLl~t1?`2PSiGNH2o literal 0 HcmV?d00001 diff --git a/figures/clocks/src/reference-clock.py b/figures/clocks/src/reference-clock.py new file mode 100755 index 0000000..42b1d66 --- /dev/null +++ b/figures/clocks/src/reference-clock.py @@ -0,0 +1,176 @@ +#!/usr/bin/env python3 + +__doc__ = \ +""" +Generate a figure showing the alignment of an external clock +referenced to a WR clock as could be seen on an oscilloscope. +""" + +import matplotlib.pyplot as plt +import numpy as np +import scipy.signal as sig + +### Functions + +def plot_signal( ax, t, t_edge, s_edge, name=None, box_kw={'hatch': '/'}, line_kw={}, annotate_t_edge=True,**plot_kw): + """ + Plot a signal directly on an axis. + Uses t_edge to trigger height + """ + lower = (t > t_edge) + upper = (t > t_edge + s_edge) + + # merge dictionaries correctly + line_kw = { **plot_kw, **line_kw } + + # plot lower and upper lines + l = ax.plot(t, lower, **line_kw) + + ## update colour when plot_kw was empty + plot_kw = { **plot_kw, **{'color': l[0].get_color()} } + line_kw = { **plot_kw, **line_kw } + box_kw = { **plot_kw, **box_kw } + + + l2 = ax.plot(t, upper, **line_kw) + + # plot the shaded box of width t_sigma + + l3 = ax.fill_between(t, upper, lower, **box_kw) + + # annotations + if name is not None: + if annotate_t_edge: + # annotate t_edge + y = 1 + ax.annotate("$t_\mathrm{{{}}}$".format(name), + xy=(t_edge, y), xytext=(t_edge-3, y), + va='top', ha='center' + ) + + # annotate s_edge + y = 0.3 + annotate_width(ax, "$\sigma_\mathrm{{{}}}$".format(name), t_edge, t_edge+s_edge, y) + + return [l, l2, l3] + +def plot_diff_time(ax, name, t_1, t_2, y, vline_kw={}, va='bottom'): + ax.axvline(t_1, **vline_kw) + ax.axvline(t_2, **vline_kw) + + arrow_kw = { + 'va':va, + } + + annotate_width(ax, name, t_1, t_2, y) + +def annotate_width(ax, name, x1, x2, y, text_kw={}, arrow_kw={}): + default_arrow_kw = dict( + xy = (x1, y), + xytext = (x2,y), + arrowprops = dict( + arrowstyle="<->", + shrinkA=False, + shrinkB=False + ), + ) + + default_text_kw = dict( + va='bottom', + ha='center', + xy=((x1+x2)/2, y) + ) + + an1 = ax.annotate("", **{**default_arrow_kw, **arrow_kw}) + an2 = ax.annotate(name, **{**default_text_kw, **text_kw}) + + return [an1, an2] + + +## Main +def main(): + """ + Create a figure with two signals at times t1 and t2 (accuracy s1, s2) + as compared to a reference timer tr (sr), with annotations. + """ + + t = np.linspace(0, 100, 1e3) + + t_A = 40 + t_B = 70 + t_ref = 10 + + s_A = 10 + s_B = 10 + s_ref = 5 + + box_kw = { + "alpha": 0.3, + "hatch": '\\', + } + line_kw = { + } + + vline_kw = { + "linestyle": '--', + "color": "k", + } + + fig, axs = plt.subplots(3,1,sharex=True, gridspec_kw={'hspace': 0}); + + # Overall styling + axs[-1].set_xticks([]) + axs[-1].set_xticklabels([]) + for ax in axs: + ax.set_ylim(-0.2, 1.2) + ax.set_yticks([]) + ax.set_yticklabels([]) + ax.grid() + + # Create the plots + i = -1 + + # Signal A + i+=1 + y = 0.6 + axs[i].set_ylabel("Signal A") + plot_diff_time(axs[i], "$t_\\mathrm{A}}$", t_ref, t_A, y, vline_kw=vline_kw) + plot_signal(axs[i], t, t_A, s_A, name="A", box_kw=box_kw, line_kw=line_kw, annotate_t_edge=False) + + # Reference + i+=1 + axs[i].set_ylabel("Reference") + axs[i].axvline(t_ref, **vline_kw) + plot_signal(axs[i], t, t_ref, s_ref, name="ref", box_kw=box_kw, line_kw=line_kw, color='g') + plot_diff_time(axs[i], "$t_\\mathrm{C}$", t_A, t_B, 0.3, vline_kw=vline_kw) + + # Signal B + i+=1 + axs[i].set_ylabel("Signal B") + plot_diff_time(axs[i], "$t_\\mathrm{B}}$", t_ref, t_B, y, vline_kw=vline_kw) + plot_signal(axs[i], t, t_B, s_B, name="B", box_kw=box_kw, line_kw=line_kw, color='purple', annotate_t_edge=False) + + + 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() +