codexpast-exam-of-the-physics-b-course-of-the-university-of-cambridge2018paper-1-a1-crossed-charge-sheets.py
past-exam-of-the-physics-b-course-of-the-university-of-cambridge/2018/paper-1-a1-crossed-charge-sheets.py
#!/usr/bin/env python3
"""Plot the calculated crossed-sheet field; write the PNG basename to cwd.
Tested with Python 3.14.4, numpy 2.3.5 and matplotlib 3.10.7 (+dfsg1).
Dependencies are already listed in the repository pyproject.toml.
"""
from pathlib import Path
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
import numpy as np
def main():
axis = np.linspace(-2.65, 2.65, 17)
x, y = np.meshgrid(axis, axis)
keep = (abs(y) > .13) & (abs(y-x) > .15)
u = np.sign(y-x)/np.sqrt(2)
v = np.sign(y)-np.sign(y-x)/np.sqrt(2)
fig, ax = plt.subplots(figsize=(5.8, 5.5), dpi=120, facecolor="white")
ax.set_facecolor("white")
ax.quiver(x[keep], y[keep], u[keep], v[keep], color="#333333",
angles="xy", scale_units="xy", scale=5.7, width=.004)
ax.plot([-3, 3], [0, 0], color="#c84444", lw=2)
ax.plot([-3, 3], [-3, 3], color="#0072b2", lw=2)
ax.text(-2.85, .12, r"$+\sigma$ on $y=0$", color="#aa3030", fontsize=11)
ax.text(1.22, 1.82, r"$-\sigma$ on $y=x$", color="#0072b2", fontsize=11, rotation=45)
ax.set(xlim=(-3, 3), ylim=(-3, 3), aspect="equal", xlabel=r"$x$", ylabel=r"$y$",
title="Superposed fields of two oppositely charged sheets")
ax.spines[["top", "right"]].set_visible(False)
ax.text(0, -3.75, r"Arrow lengths are proportional to $|\mathbf{E}|$; sheet fields use $E_s=\sigma/(2\varepsilon_0)$.",
ha="center", fontsize=9)
fig.tight_layout()
fig.savefig(Path(__file__).stem+".png", facecolor="white")
plt.close(fig)
if __name__ == "__main__":
main()