codexpast-exam-of-the-physics-1-paper-of-the-university-of-oxford2021-potential-and-force.py
past-exam-of-the-physics-1-paper-of-the-university-of-oxford/2021-potential-and-force.py
"""Plot Oxford Physics 1 (2021), question 3. Python 3.14; NumPy, Matplotlib."""
from pathlib import Path
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import numpy as np
def main():
plt.rcParams.update({'font.size': 12, 'figure.facecolor': 'white', 'axes.facecolor': 'white'})
x = np.linspace(-5, 5, 2001)
potential = -x / (1 + x**2)
force = (1 - x**2) / (1 + x**2)**2
fig, axes = plt.subplots(1, 2, figsize=(10.8, 4.1), layout='constrained')
for ax in axes:
ax.axhline(0, color='0.35', linewidth=0.8)
ax.axvline(0, color='0.35', linewidth=0.8)
ax.set(xlim=(-5, 5), xlabel=r'$x/A$, where $A=|a|>0$')
ax.grid(alpha=0.18)
ax = axes[0]
ax.plot(x, potential, color='#2166ac', linewidth=2.3)
ax.set(title=r'Potential energy ($k>0$)', ylabel=r'$AU/k$')
ax.scatter([-1, 1], [0.5, -0.5], c=['#b2182b', '#1b7837'], s=48, zorder=3)
ax.annotate('Unstable equilibrium', (-1, 0.5), xytext=(-4.7, 0.63),
arrowprops={'arrowstyle': '->', 'color': '#b2182b'}, color='#b2182b')
ax.annotate('Stable equilibrium', (1, -0.5), xytext=(0.5, -0.73),
arrowprops={'arrowstyle': '->', 'color': '#1b7837'}, color='#1b7837')
ax.set(ylim=(-0.85, 0.85), yticks=[-0.5, 0, 0.5])
ax = axes[1]
ax.plot(x, force, color='#762a83', linewidth=2.3)
ax.scatter([-1, 1], [0, 0], c=['#b2182b', '#1b7837'], s=40, zorder=3)
ax.scatter([-np.sqrt(3), 0, np.sqrt(3)], [-1/8, 1, -1/8], color='#762a83', s=27, zorder=3)
ax.annotate(r'$F(0)=k/A^2$', (0, 1), xytext=(0.7, 1.02))
ax.annotate(r'Minima at $x=\pm\sqrt{3}A$', (-np.sqrt(3), -1/8), xytext=(-4.7, -0.42),
arrowprops={'arrowstyle': '->', 'color': '#762a83'})
ax.set(title=r'Force: $F=-dU/dx$', ylabel=r'$A^2F/k$', ylim=(-0.55, 1.25), yticks=[-0.125, 0, 0.5, 1])
output = Path.cwd() / Path(__file__).with_suffix('.png').name
fig.savefig(output, dpi=110, facecolor='white', transparent=False,
metadata={'Software': 'Oxford Physics 1 (2021) figure generator'})
plt.close(fig)
if __name__ == '__main__':
main()