codexcrash-pulse-equal-velocity-change.py
crash-pulse-equal-velocity-change.py
"""Own idealized stopping pulses; write the PNG to the current directory.
Tested with Python 3.14.4, NumPy 2.3.5 and Matplotlib 3.10.7.
The pulses are synthetic examples, not reconstructions of crash-test data.
"""
from pathlib import Path
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
import numpy as np
duration = 0.100 # seconds
time = np.linspace(0.0, duration, 1001)
constant = np.full_like(time, 80.0)
triangular = 160.0 * (1.0 - np.abs(2.0 * time / duration - 1.0))
assert np.isclose(np.trapezoid(constant, time), 8.0)
assert np.isclose(np.trapezoid(triangular, time), 8.0)
assert np.isclose(constant.max(), 80.0)
assert np.isclose(triangular.max(), 160.0)
plt.rcParams.update({"font.size": 11, "figure.facecolor": "white"})
fig, axes = plt.subplots(1, 2, figsize=(8.5, 4.2), dpi=100, sharey=True)
fig.subplots_adjust(left=0.085, right=0.985, bottom=0.19, top=0.77, wspace=0.18)
fig.suptitle("Same velocity change, different peak deceleration", y=0.96, fontsize=14)
for ax, values, title, peak, color in [
(axes[0], constant, "Constant pulse", 80, "#1766a0"),
(axes[1], triangular, "Triangular pulse", 160, "#b04d13"),
]:
ax.fill_between(time * 1000, values, color=color, alpha=0.18)
ax.plot(time * 1000, values, color=color, linewidth=2.5)
ax.vlines([0, 100], [0, 0], [values[0], values[-1]], color=color, linewidth=2.5)
ax.set_title(title, fontsize=12)
ax.text(0.04, 0.91, f"Peak = {peak} m/s²", transform=ax.transAxes, fontsize=10)
ax.text(0.5, 0.10, "Area = 8 m/s", ha="center", transform=ax.transAxes)
ax.set(xlim=(-2, 102), ylim=(0, 180), xlabel="Time (ms)")
ax.set_xticks([0, 25, 50, 75, 100])
ax.set_yticks([0, 40, 80, 120, 160])
ax.grid(alpha=0.18)
ax.spines[["top", "right"]].set_visible(False)
axes[0].set_ylabel("Deceleration magnitude (m/s²)")
fig.text(0.5, 0.045, "Synthetic 100 ms stopping pulses; shaded area is speed lost.",
ha="center", fontsize=10)
fig.savefig(Path("crash-pulse-equal-velocity-change.png"), facecolor="white")
plt.close(fig)