codexpast-exam-of-the-plant-sciences-course-of-the-university-of-cambridge2024paper-plm1-clock-gating.py
past-exam-of-the-plant-sciences-course-of-the-university-of-cambridge/2024/paper-plm1-clock-gating.py
"""Original stipulated gating model; Python 3.14, numpy and matplotlib.
No experimental data. PNG output is a literal basename in the current directory.
"""
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import numpy as np
phase = np.linspace(0, 24, 241)
baseline = 1 + 0.25*np.cos(2*np.pi*phase/24)
fixed_gain = np.full_like(phase, 0.5)
gated_gain = 0.5 + 0.35*np.cos(2*np.pi*(phase-6)/24)
pulse_phase = np.array([0., 6., 12., 18.])
fig, axes = plt.subplots(2, 2, figsize=(9.0, 6.3), sharex=True, layout='constrained')
fig.patch.set_facecolor('white')
for col, gain in enumerate([fixed_gain, gated_gain]):
top, bottom = axes[:,col]
top.plot(phase, baseline, color='#6e7781', ls='--', label='Untreated baseline')
top.plot(phase, baseline+gain, color='#277b83', label='With identical stimulus')
top.scatter(pulse_phase, np.interp(pulse_phase,phase,baseline+gain), color='#277b83', s=32)
top.set(ylim=(0.55,2.25), title=['Constant sensitivity','Circadian gating'][col])
bottom.plot(phase, gain, color='#98581d', lw=2)
bottom.scatter(pulse_phase,np.interp(pulse_phase,phase,gain), color='#98581d', s=32)
bottom.set(ylim=(0,1.0), xlabel='Internal phase (h)')
for ax in [top,bottom]:
ax.set_xticks([0,6,12,18,24])
ax.set_xlim(0,24)
ax.grid(alpha=0.2)
ax.spines[['top','right']].set_visible(False)
axes[0,0].set_ylabel('Absolute response (arbitrary units)')
axes[1,0].set_ylabel('Response above baseline')
axes[0,0].legend(fontsize=8.5, loc='upper right')
fig.suptitle('Same stimulus, different internal phase\nIllustrative response curves for separate timed treatments', fontsize=14)
fig.savefig('paper-plm1-clock-gating.png', dpi=160, facecolor='white')
plt.close(fig)