Hi
Prepare a graph of menstrual cycle with levels of hormones through out normal menstrual cycle
ls /home/daytona/workspace/ 2>/dev/null || echo "workspace empty or not found"
mkdir -p /home/daytona/workspace/menstrual-cycle && python3 << 'EOF' import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt import matplotlib.patches as mpatches import numpy as np days = np.linspace(1, 28, 300) # --- FSH: rises early follicular, peaks just before ovulation (day 13), then drops --- def fsh(d): base = 5 # early follicular rise early = 4 * np.exp(-((d - 3)**2) / (2 * 3**2)) # pre-ovulatory surge surge = 7 * np.exp(-((d - 13)**2) / (2 * 0.8**2)) # luteal low luteal = np.where(d > 14, -1.5 * np.exp(-((d - 20)**2) / (2 * 4**2)), 0) return base + early + surge + luteal # --- LH: flat early, sharp mid-cycle surge at day 13, then drops --- def lh(d): base = 5 surge = 60 * np.exp(-((d - 13.5)**2) / (2 * 0.6**2)) return base + surge # --- Estrogen: rises through follicular phase, peaks at day 12, dips, then secondary luteal peak --- def estrogen(d): follicular_peak = 250 * np.exp(-((d - 12)**2) / (2 * 2.5**2)) luteal_peak = 130 * np.exp(-((d - 21)**2) / (2 * 3**2)) baseline = 40 return baseline + follicular_peak + luteal_peak # --- Progesterone: very low follicular, rises post-ovulation, peaks day 21, drops at end --- def progesterone(d): luteal = np.where(d > 14, 18 * np.exp(-((d - 21)**2) / (2 * 3.5**2)), 0.5 * np.ones_like(d)) return luteal FSH_vals = fsh(days) LH_vals = lh(days) E2_vals = estrogen(days) P4_vals = progesterone(days) fig = plt.figure(figsize=(14, 11), facecolor='#FAFAFA') fig.suptitle('The Normal Menstrual Cycle\nHormonal Changes Over 28 Days', fontsize=16, fontweight='bold', y=0.98, color='#1a1a2e') gs = fig.add_gridspec(3, 1, hspace=0.45, top=0.93, bottom=0.08) # ---- TOP PANEL: FSH & LH ---- ax1 = fig.add_subplot(gs[0]) ax1.plot(days, FSH_vals, color='#0077B6', lw=2.5, label='FSH') ax1.plot(days, LH_vals, color='#E63946', lw=2.5, label='LH') ax1.set_ylabel('Hormone level\n(IU/L)', fontsize=10) ax1.set_title('Gonadotropins (FSH & LH)', fontsize=11, fontweight='bold', color='#333') ax1.legend(loc='upper left', fontsize=10, framealpha=0.8) ax1.set_xlim(1, 28) ax1.set_ylim(0, 80) ax1.axvline(x=14, color='gray', linestyle='--', linewidth=1.2, alpha=0.7) ax1.annotate('Ovulation\n(Day 14)', xy=(14, 70), ha='center', fontsize=9, color='gray', style='italic') ax1.set_facecolor('#FAFAFA') ax1.spines['top'].set_visible(False) ax1.spines['right'].set_visible(False) ax1.tick_params(labelbottom=False) # ---- MIDDLE PANEL: Estrogen & Progesterone ---- ax2 = fig.add_subplot(gs[1]) ax2_twin = ax2.twinx() ax2.plot(days, E2_vals, color='#F4845F', lw=2.5, label='Estrogen (E₂)') ax2_twin.plot(days, P4_vals, color='#8338EC', lw=2.5, label='Progesterone (P₄)', linestyle='-') ax2.set_ylabel('Estrogen (E₂)\n(pg/mL)', fontsize=10, color='#F4845F') ax2_twin.set_ylabel('Progesterone (P₄)\n(ng/mL)', fontsize=10, color='#8338EC') ax2.set_title('Ovarian Hormones (Estrogen & Progesterone)', fontsize=11, fontweight='bold', color='#333') ax2.set_xlim(1, 28) ax2.set_ylim(0, 340) ax2_twin.set_ylim(0, 22) ax2.axvline(x=14, color='gray', linestyle='--', linewidth=1.2, alpha=0.7) ax2.tick_params(axis='y', labelcolor='#F4845F') ax2_twin.tick_params(axis='y', labelcolor='#8338EC') ax2.set_facecolor('#FAFAFA') ax2.spines['top'].set_visible(False) ax2.tick_params(labelbottom=False) lines1, labels1 = ax2.get_legend_handles_labels() lines2, labels2 = ax2_twin.get_legend_handles_labels() ax2.legend(lines1 + lines2, labels1 + labels2, loc='upper left', fontsize=10, framealpha=0.8) # ---- BOTTOM PANEL: Phase/endometrium annotations ---- ax3 = fig.add_subplot(gs[2]) ax3.set_xlim(1, 28) ax3.set_ylim(0, 3) ax3.axis('off') # Phase bands ax3.axvspan(1, 5, alpha=0.2, color='#FF6B6B') ax3.axvspan(5, 14, alpha=0.2, color='#06D6A0') ax3.axvspan(14, 28, alpha=0.2, color='#FFB703') ax3.text(3, 2.3, 'Menstruation\n(Days 1–5)', ha='center', va='center', fontsize=9.5, fontweight='bold', color='#CC0000') ax3.text(9.5, 2.3, 'Follicular / Proliferative Phase\n(Days 5–14)', ha='center', va='center', fontsize=9.5, fontweight='bold', color='#028960') ax3.text(21, 2.3, 'Luteal / Secretory Phase\n(Days 14–28)', ha='center', va='center', fontsize=9.5, fontweight='bold', color='#b37700') # Ovulation marker ax3.annotate('', xy=(14, 1.8), xytext=(14, 1.0), arrowprops=dict(arrowstyle='->', color='black', lw=2)) ax3.text(14, 0.6, 'Ovulation\n(Day 14)', ha='center', fontsize=9.5, color='black', fontweight='bold') # Endometrial changes ax3.text(3, 0.7, 'Endometrium\nshedding', ha='center', fontsize=8.5, color='#CC0000', style='italic') ax3.text(9.5, 0.7, 'Proliferation of\nendometrium', ha='center', fontsize=8.5, color='#028960', style='italic') ax3.text(21, 0.7, 'Secretory changes;\nglandular activity', ha='center', fontsize=8.5, color='#b37700', style='italic') ax3.set_title('Menstrual Cycle Phases & Endometrial Changes', fontsize=11, fontweight='bold', color='#333') # x-axis ticks on all panels for ax in [ax1, ax2]: ax.set_xticks([1, 5, 7, 10, 12, 13, 14, 16, 18, 21, 24, 28]) # Common x label fig.text(0.5, 0.02, 'Day of Menstrual Cycle', ha='center', fontsize=12, fontweight='bold') out_path = '/home/daytona/workspace/menstrual-cycle/menstrual_cycle_hormones.png' plt.savefig(out_path, dpi=180, bbox_inches='tight', facecolor='#FAFAFA') print(f"Saved to {out_path}") EOF
menstrual cycle hormones
Image · PNG
| Phase | Days | Dominant Hormone | Endometrium |
|---|---|---|---|
| Menstruation | 1-5 | None (hormone withdrawal) | Shedding |
| Follicular / Proliferative | 5-14 | Estrogen | Regeneration & growth |
| Ovulation | Day 14 | LH surge | - |
| Luteal / Secretory | 14-28 | Progesterone | Secretory glandular changes |
Is fsh graph is crt
Regenerate the graph with corrected FSH intercycle rise
python3 << 'EOF' import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt import numpy as np days = np.linspace(1, 28, 400) # --- FSH: CORRECTED --- # 1. Gentle sustained rise from Day 1-10 (follicular recruitment) # 2. Small co-surge with LH at Day 12-13 (smaller than LH) # 3. Suppressed mid-luteal phase # 4. Late luteal INTERCYCLE RISE starting ~Day 25 (recruits next cohort) def fsh(d): baseline = 5 # Gentle follicular rise (broad, sustained Days 1-10) follicular = 5 * np.exp(-((d - 6)**2) / (2 * 5**2)) # Small mid-cycle co-surge (Day 12-13, much smaller than LH) cosurge = 9 * np.exp(-((d - 13)**2) / (2 * 0.7**2)) # Luteal suppression dip suppression = -3 * np.exp(-((d - 20)**2) / (2 * 4**2)) # Late luteal / intercycle rise (Day 25-28, begins recruitment of next cycle) intercycle = 6 * np.exp(-((d - 27.5)**2) / (2 * 1.5**2)) return baseline + follicular + cosurge + suppression + intercycle # --- LH: sharp mid-cycle surge at Day 13 --- def lh(d): baseline = 5 surge = 55 * np.exp(-((d - 13.5)**2) / (2 * 0.6**2)) return baseline + surge # --- Estrogen: follicular peak Day 12, dip, luteal secondary peak Day 21 --- def estrogen(d): follicular_peak = 240 * np.exp(-((d - 12)**2) / (2 * 2.5**2)) luteal_peak = 120 * np.exp(-((d - 21)**2) / (2 * 3**2)) return 40 + follicular_peak + luteal_peak # --- Progesterone: low follicular, peaks Day 21, drops end of luteal --- def progesterone(d): luteal = np.where(d > 14, 18 * np.exp(-((d - 21)**2) / (2 * 3.5**2)), 0.4 * np.ones_like(d)) return luteal FSH_vals = fsh(days) LH_vals = lh(days) E2_vals = estrogen(days) P4_vals = progesterone(days) fig = plt.figure(figsize=(14, 12), facecolor='#FAFAFA') fig.suptitle('The Normal Menstrual Cycle — Hormonal Changes Over 28 Days\n(with Corrected FSH Intercycle Rise)', fontsize=15, fontweight='bold', y=0.99, color='#1a1a2e') gs = fig.add_gridspec(3, 1, hspace=0.50, top=0.94, bottom=0.07) # ============================================================ # PANEL 1: FSH & LH # ============================================================ ax1 = fig.add_subplot(gs[0]) ax1.plot(days, FSH_vals, color='#0077B6', lw=2.8, label='FSH', zorder=3) ax1.plot(days, LH_vals, color='#E63946', lw=2.8, label='LH', zorder=3) ax1.fill_between(days, FSH_vals, alpha=0.10, color='#0077B6') ax1.fill_between(days, LH_vals, alpha=0.08, color='#E63946') # Annotate intercycle FSH rise ax1.annotate('Intercycle FSH rise\n(recruits next cohort)', xy=(27, fsh(np.array([27]))[0]), xytext=(23, 30), fontsize=8.5, color='#0077B6', arrowprops=dict(arrowstyle='->', color='#0077B6', lw=1.4), ha='center') # Annotate LH surge ax1.annotate('LH surge\n(triggers ovulation)', xy=(13.5, 62), xytext=(17.5, 65), fontsize=8.5, color='#E63946', arrowprops=dict(arrowstyle='->', color='#E63946', lw=1.4)) ax1.set_ylabel('Hormone level (IU/L)', fontsize=10) ax1.set_title('Gonadotropins — FSH & LH', fontsize=11, fontweight='bold', color='#333') ax1.legend(loc='upper left', fontsize=10, framealpha=0.85) ax1.set_xlim(1, 28) ax1.set_ylim(0, 85) ax1.axvline(x=14, color='#555', linestyle='--', linewidth=1.2, alpha=0.6) ax1.text(14.3, 78, 'Ovulation', fontsize=8.5, color='#555', style='italic') ax1.set_facecolor('#FAFAFA') ax1.spines['top'].set_visible(False) ax1.spines['right'].set_visible(False) ax1.tick_params(labelbottom=False) ax1.set_xticks([1,5,7,10,12,13,14,16,18,21,24,25,28]) # ============================================================ # PANEL 2: Estrogen & Progesterone # ============================================================ ax2 = fig.add_subplot(gs[1]) ax2b = ax2.twinx() ax2.plot(days, E2_vals, color='#F4845F', lw=2.8, label='Estrogen (E₂)') ax2.fill_between(days, E2_vals, alpha=0.10, color='#F4845F') ax2b.plot(days, P4_vals, color='#7B2D8B', lw=2.8, label='Progesterone (P₄)') ax2b.fill_between(days, P4_vals, alpha=0.10, color='#7B2D8B') # Annotations ax2.annotate('Pre-ovulatory\nE₂ peak', xy=(12, 280), xytext=(7.5, 295), fontsize=8.5, color='#C85000', arrowprops=dict(arrowstyle='->', color='#C85000', lw=1.3)) ax2.annotate('Luteal E₂\nsecondary peak', xy=(21, 160), xytext=(18, 235), fontsize=8.5, color='#C85000', arrowprops=dict(arrowstyle='->', color='#C85000', lw=1.3)) ax2b.annotate('P₄ peak\n(Day 21)', xy=(21, 18), xytext=(23.5, 15), fontsize=8.5, color='#7B2D8B', arrowprops=dict(arrowstyle='->', color='#7B2D8B', lw=1.3)) ax2.set_ylabel('Estrogen E₂ (pg/mL)', fontsize=10, color='#F4845F') ax2b.set_ylabel('Progesterone P₄ (ng/mL)', fontsize=10, color='#7B2D8B') ax2.set_title('Ovarian Hormones — Estrogen & Progesterone', fontsize=11, fontweight='bold', color='#333') ax2.set_xlim(1, 28) ax2.set_ylim(0, 360) ax2b.set_ylim(0, 24) ax2.axvline(x=14, color='#555', linestyle='--', linewidth=1.2, alpha=0.6) ax2.tick_params(axis='y', labelcolor='#F4845F') ax2b.tick_params(axis='y', labelcolor='#7B2D8B') ax2.set_facecolor('#FAFAFA') ax2.spines['top'].set_visible(False) ax2.tick_params(labelbottom=False) ax2.set_xticks([1,5,7,10,12,13,14,16,18,21,24,25,28]) lines1, labels1 = ax2.get_legend_handles_labels() lines2, labels2 = ax2b.get_legend_handles_labels() ax2.legend(lines1 + lines2, labels1 + labels2, loc='upper left', fontsize=10, framealpha=0.85) # ============================================================ # PANEL 3: Phase annotations # ============================================================ ax3 = fig.add_subplot(gs[2]) ax3.set_xlim(1, 28) ax3.set_ylim(0, 3.2) ax3.axis('off') # Phase spans ax3.axvspan(1, 5, alpha=0.20, color='#FF6B6B') ax3.axvspan(5, 14, alpha=0.20, color='#06D6A0') ax3.axvspan(14, 28, alpha=0.20, color='#FFB703') ax3.text(3, 2.6, 'Menstruation\n(Days 1–5)', ha='center', fontsize=9, fontweight='bold', color='#CC0000') ax3.text(9.5, 2.6, 'Follicular / Proliferative Phase\n(Days 5–14)', ha='center', fontsize=9, fontweight='bold', color='#028960') ax3.text(21, 2.6, 'Luteal / Secretory Phase\n(Days 14–28)', ha='center', fontsize=9, fontweight='bold', color='#b37700') ax3.annotate('', xy=(14, 2.0), xytext=(14, 1.3), arrowprops=dict(arrowstyle='->', color='black', lw=2)) ax3.text(14, 1.0, 'Ovulation\n(Day 14)', ha='center', fontsize=9, color='black', fontweight='bold') ax3.text(3, 0.4, 'Endometrium\nshedding', ha='center', fontsize=8.5, color='#CC0000', style='italic') ax3.text(9.5, 0.4, 'Proliferation &\ngrowth', ha='center', fontsize=8.5, color='#028960', style='italic') ax3.text(19, 0.4, 'Secretory changes\n& glandular activity', ha='center', fontsize=8.5, color='#b37700', style='italic') ax3.text(26, 0.4, 'FSH intercycle\nrise begins', ha='center', fontsize=8, color='#0077B6', style='italic', fontweight='bold') ax3.set_title('Menstrual Cycle Phases & Endometrial Changes', fontsize=11, fontweight='bold', color='#333') fig.text(0.5, 0.01, 'Day of Menstrual Cycle', ha='center', fontsize=12, fontweight='bold') out = '/home/daytona/workspace/menstrual-cycle/menstrual_cycle_corrected.png' plt.savefig(out, dpi=180, bbox_inches='tight', facecolor='#FAFAFA') print(f"Saved: {out}") EOF
menstrual cycle corrected
Image · PNG
| Feature | Previous (incorrect) | Corrected |
|---|---|---|
| Early follicular shape | Sharp early peak (Day 3) | Gentle, sustained broad rise (Days 1-10) |
| Mid-cycle co-surge | Present (correct) | Retained - smaller than LH surge |
| Luteal phase | Flat suppression | Mild suppression, then rises |
| Late luteal rise (Day 25-28) | Missing | Added - intercycle FSH rise |