"""Plot the ideal axial pulsed-Doppler depth/speed timing bound. Python 3.14, NumPy and Matplotlib as declared in pyproject.toml. Run from the mirrored _media directory; output is written to the cwd. """ import numpy as np import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt sound_speed = 1540.0 centimetres = np.linspace(5.0, 35.0, 401) metres = centimetres / 100.0 fig, ax = plt.subplots(figsize=(9.6, 4.2), dpi=100, facecolor='white') ax.set_facecolor('white') for frequency, color in [(2.5e6, '#1261a0'), (5.0e6, '#d46216')]: boundary = sound_speed**2 / (8.0 * frequency * metres) ax.plot(centimetres, boundary, color=color, linewidth=2.5, label=f'{frequency / 1e6:g} MHz transmitted') speed = sound_speed**2 / (8.0 * frequency * 0.15) ax.plot([15.0], [speed], 'o', color=color) ax.annotate(f'{speed:.3f} m/s at 15 cm', (15.0, speed), xytext=(12, 7), textcoords='offset points', color=color) ax.set(xlabel='Maximum uniquely localized depth (cm)', ylabel='Axial Nyquist speed (m/s)', xlim=(5, 35), ylim=(0, 2.6), title='Pulsed Doppler: greater depth reduces the unaliased speed range') ax.grid(alpha=0.22) ax.legend(frameon=False, loc='upper right') fig.text(0.5, 0.025, 'Ideal single-depth timing; c = 1540 m/s; beam-parallel motion. Usable speeds lie below the curves.', ha='center', fontsize=9) fig.tight_layout(rect=(0, 0.055, 1, 1)) fig.savefig('pulsed-doppler-depth-velocity-limit.png', facecolor='white', dpi=100) plt.close(fig)