Linear Regression Plot

Antibody Neutralization Kinetics

Immunology dose-response with EC50 marker and sigmoid fit

Output
Antibody Neutralization Kinetics
Python
import matplotlib.pyplot as plt
import numpy as np

np.random.seed(789)

# Dose-response data
log_conc = np.linspace(-2, 3, 50)
conc = 10**log_conc
ec50 = 10  # EC50 value
hill = 1.2
response = 100 / (1 + (ec50/conc)**hill) + np.random.normal(0, 4, 50)
response = np.clip(response, 0, 100)

# Fit curve
x_smooth = np.linspace(-2, 3, 200)
conc_smooth = 10**x_smooth
y_smooth = 100 / (1 + (ec50/conc_smooth)**hill)

fig, ax = plt.subplots(figsize=(10, 7), facecolor='#0a0a0f')
ax.set_facecolor('#0a0a0f')

# Confidence band
ax.fill_between(x_smooth, y_smooth - 8, y_smooth + 8, color='#5314E6', alpha=0.15, linewidth=0)

ax.plot(x_smooth, y_smooth, color='#5314E6', linewidth=2.5, zorder=3)
ax.scatter(log_conc, response, c='#F5D327', s=65, alpha=0.85, edgecolors='white', linewidths=0.4, zorder=4)

# EC50 marker
ax.axvline(x=np.log10(ec50), color='#F5276C', linestyle='--', linewidth=1.5, alpha=0.7)
ax.axhline(y=50, color='#F5276C', linestyle='--', linewidth=1.5, alpha=0.7)
ax.scatter([np.log10(ec50)], [50], c='#F5276C', s=100, marker='o', zorder=5, edgecolors='white', linewidths=2)
ax.text(np.log10(ec50) + 0.15, 53, f'EC₅₀ = {ec50} nM', fontsize=10, color='#F5276C')

for spine in ['top', 'right']:
    ax.spines[spine].set_visible(False)
for spine in ['bottom', 'left']:
    ax.spines[spine].set_color('#333333')

ax.set_xlabel('Log₁₀ Concentration (nM)', fontsize=12, color='white', fontweight='500', labelpad=10)
ax.set_ylabel('Neutralization (%)', fontsize=12, color='white', fontweight='500', labelpad=10)
ax.set_title('Antibody Dose-Response', fontsize=15, color='white', 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

Did this help you?

Support PyLucid to keep it free & growing

Support