Endocrine Disruption: Estrogen Receptor (ER) Interaction Dashboard

DrugBank database
MolPort database
Python script number 87 to build the frequency distribution graph of the ER parameter on DrugBank molecules.
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
from matplotlib.patches import Patch
import numpy as np
from scipy.interpolate import PchipInterpolator

# ==============================================================================
# 1. STANDARD FORMAT FOR THE INJECTOR
# ==============================================================================
datos_crudos = """Bin Center	% Frequency
0	47.98
0.05	17.24
0.1	6.84
0.15	4.42
0.2	3.06
0.25	3.48
0.3	2.63
0.35	2.46
0.4	1.74
0.45	1.87
0.5	1.53
0.55	1.57
0.6	1.02
0.65	1.02
0.7	1.15
0.75	0.42
0.8	0.64
0.85	0.55
0.9	0.30
0.95	0.08"""

lineas = datos_crudos.strip().split('\n')[1:] 
bins_array = []
freq_array = []
for linea in lineas:
    b, f = linea.strip().split() 
    bins_array.append(float(b))
    freq_array.append(float(f))

bins = np.array(bins_array)
freq = np.array(freq_array)

# 2. Dynamic Statistical Calculations
mean_val = np.average(bins, weights=freq)

# PCHIP Interpolation (Negative Exponential Empirical Trend)
interpolator = PchipInterpolator(bins, freq)
x_fit = np.linspace(0, 0.95, 500)
y_fit = interpolator(x_fit)
y_fit = np.clip(y_fit, 0, None)

# 3. Color Function (ER Probability Traffic Light)
def get_colors(bins):
    return ['#008000' if b < 0.4 else '#FFD700' if b <= 0.7 else '#B22222' for b in bins]

colors_hex = get_colors(bins)

# Apply independent transparencies
face_colors = [mcolors.to_rgba(c, alpha=0.60) for c in colors_hex]
edge_colors = [mcolors.to_rgba(c, alpha=0.90) for c in colors_hex]

# 4. Create the chart
plt.figure(figsize=(7, 6))

# Draw bars and empirical trend line
plt.bar(bins, freq, width=0.04, color=face_colors, edgecolor=edge_colors, linewidth=1.5, zorder=2)

# 5. Tags and Titles
plt.xlabel('Estrogen Receptor Binding Probability (EDC Potential)', fontsize=12)
plt.ylabel('% Frequency', fontsize=12)
plt.title('Endocrine Disruption: Estrogen Receptor (ER) Interaction', fontsize=14)

# 6. Structured Legend
legend_elements = [
    Patch(facecolor=mcolors.to_rgba('#008000', 0.6), edgecolor='#008000', label='Non-Receptor / Safe (< 0.4)'),
    Patch(facecolor=mcolors.to_rgba('#FFD700', 0.6), edgecolor='#FFD700', label='Weak/Moderate Interaction (0.4 - 0.7)'),
    Patch(facecolor=mcolors.to_rgba('#B22222', 0.6), edgecolor='#B22222', label='ER Disruptor / Binder (> 0.7)')
]
plt.legend(handles=legend_elements, loc='upper right', framealpha=0.95, fontsize=10)

plt.grid(axis='y', linestyle=':', alpha=0.7, zorder=0)
plt.xlim(-0.05, 1.0)
plt.ylim(0, 52)
plt.tight_layout()

plt.show()