Linear Regression Plot
Photosynthesis Light Response
Plant physiology saturation curve with clean scientific styling
Output
Python
import matplotlib.pyplot as plt
import numpy as np
np.random.seed(555)
# Light response data
par = np.linspace(0, 2000, 50) # PAR μmol/m²/s
pmax = 25 # max photosynthesis
k = 300 # half-saturation
photo = (pmax * par) / (k + par) - 2 + np.random.normal(0, 1.5, 50)
photo = np.clip(photo, -2, 28)
# Theoretical curve
par_smooth = np.linspace(0, 2000, 200)
photo_smooth = (pmax * par_smooth) / (k + par_smooth) - 2
fig, ax = plt.subplots(figsize=(10, 7), facecolor='#ffffff')
ax.set_facecolor('#ffffff')
ax.yaxis.grid(True, color='#f0f0f0', linewidth=1, zorder=1)
ax.xaxis.grid(True, color='#f0f0f0', linewidth=1, zorder=1)
# Light saturation zone
ax.axvspan(800, 2000, alpha=0.05, color='#F5B027', zorder=1)
ax.text(1400, 2, 'saturation', fontsize=9, color='#F5B027', ha='center', alpha=0.8)
ax.fill_between(par_smooth, photo_smooth - 2, photo_smooth + 2, color='#6CF527', alpha=0.12, linewidth=0, zorder=2)
ax.plot(par_smooth, photo_smooth, color='#6CF527', linewidth=2.5, zorder=3)
ax.scatter(par, photo, c='#276CF5', s=55, alpha=0.8, edgecolors='white', linewidths=0.6, zorder=4)
# Compensation point
ax.axhline(y=0, color='#C82909', linestyle='--', linewidth=1.2, alpha=0.6)
ax.text(50, 1, 'LCP', fontsize=9, color='#C82909')
for spine in ['top', 'right']:
ax.spines[spine].set_visible(False)
for spine in ['bottom', 'left']:
ax.spines[spine].set_color('#cccccc')
ax.set_xlabel('PAR (μmol photons m⁻² s⁻¹)', fontsize=12, color='#333333', fontweight='500', labelpad=10)
ax.set_ylabel('Net Photosynthesis (μmol CO₂ m⁻² s⁻¹)', fontsize=12, color='#333333', fontweight='500', labelpad=10)
ax.set_title('Light Response Curve', fontsize=15, color='#1a1a1a', fontweight='bold', pad=20, loc='left')
ax.tick_params(colors='#666666', labelsize=10, length=0)
plt.tight_layout()
plt.show()
Library
Matplotlib
Category
Pairwise Data
More Linear Regression Plot examples
☕