codex/past-exam-of-the-physics-of-the-earth-as-a-planet-course-of-the-university-of-cambridge/2013/paper-1-pep-notes.py

past-exam-of-the-physics-of-the-earth-as-a-planet-course-of-the-university-of-cambridge/2013/paper-1-pep-notes.py
"""Original explanatory figure; Python 3.14, NumPy and Matplotlib."""
from pathlib import Path
import numpy as np
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
plt.rcParams.update({'font.size':10,'figure.facecolor':'white','axes.facecolor':'white','savefig.facecolor':'white'})

fig,axs=plt.subplots(2,2,figsize=(9,7),layout='constrained')
ax=axs[0,0];edges=[0,.45,1.3,1.8,2.9,3.5,4.2]
for j in range(len(edges)-1):
 for sign in [-1,1]:
  lo,hi=sorted([sign*edges[j],sign*edges[j+1]]);ax.axvspan(lo,hi,color=['#b45e57','#93b7d1'][j%2],alpha=.9)
ax.axvline(0,color='k');ax.annotate('',xy=(-3.6,.5),xytext=(-.3,.5),arrowprops={'arrowstyle':'->','lw':2});ax.annotate('',xy=(3.6,.5),xytext=(.3,.5),arrowprops={'arrowstyle':'->','lw':2})
ax.set(xlim=(-4.2,4.2),ylim=(0,1),yticks=[],xlabel='distance from ridge (arbitrary scale)',title='Paired rock-polarity bands, schematic');ax.text(-.5,.12,'ridge',fontsize=8);ax.text(-4,.85,'alternating polarity; widths need not be equal',fontsize=8)
ax=axs[0,1];x=np.linspace(0,2,120);z=np.linspace(0,1,80);X,Z=np.meshgrid(x,z);U=np.pi*np.sin(np.pi*X)*np.cos(np.pi*Z);W=-np.pi*np.cos(np.pi*X)*np.sin(np.pi*Z)
ax.contourf(X,Z,1-Z,levels=25,cmap='coolwarm');ax.streamplot(x,z,U,W,color='k',density=.65,linewidth=.8,arrowsize=1)
ax.set(xlim=(0,2),ylim=(0,1),xticks=[],yticks=[],title='Convection rolls, schematic');ax.text(.04,.03,'hot bottom',fontsize=8);ax.text(.04,.9,'cold top',fontsize=8)
ax=axs[1,0];event=np.array([.25,.2]);stations=[(-.65,-.55),(.7,-.5),(.5,.85)];theta=np.linspace(0,2*np.pi,500)
for st,col in zip(stations,['#3b6f9c','#ba654d','#57975a']):
 st=np.array(st);r=np.linalg.norm(event-st);ax.plot(st[0]+r*np.cos(theta),st[1]+r*np.sin(theta),color=col,lw=1);ax.plot(*st,'^',color=col)
ax.plot(*event,'k*',ms=12);ax.set(xlim=(-1.2,1.2),ylim=(-1,1.2),aspect='equal',xticks=[],yticks=[],title='Ideal distance constraints in a plane');ax.text(-1.15,-.93,'triangles: stations; star: source',fontsize=8)
ax=axs[1,1];t=np.array([0,1,1,2,2,3,3]);stress=np.array([.25,1,.25,1,.25,1,.25]);ax.plot(t,stress,color='#5c608d',lw=2)
ax.set(xlabel='time (arbitrary scale)',ylabel='shear stress (arbitrary scale)',ylim=(0,1.15),title='Idealized elastic loading and release');ax.text(.12,.95,'slow loading',fontsize=8);ax.annotate('rapid release',xy=(1,.6),xytext=(1.4,.1),fontsize=8,arrowprops={'arrowstyle':'->'});ax.grid(alpha=.15)
fig.suptitle('Original concept diagrams; no measured anomaly, flow or earthquake data')

fig.savefig(Path(__file__).stem+'.png',dpi=150,bbox_inches='tight',facecolor='white');plt.close(fig)