Can u make these flowcharts better in terms of what are fhe high risk factors when to treat and when nkt to treat or observe
pip install matplotlib --quiet && python3 -c "import matplotlib; print(matplotlib.__version__)"
mkdir -p /tmp/workspace/retina-flowcharts && cat > /tmp/workspace/retina-flowcharts/flowcharts.py << 'PYEOF' import matplotlib.pyplot as plt import matplotlib.patches as mpatches from matplotlib.patches import FancyBboxPatch, FancyArrowPatch import matplotlib.patheffects as pe # ─────────────── COLOR PALETTE ─────────────── C_START = "#1a1a2e" # deep navy – start node C_HIGH = "#c0392b" # crimson – high-risk factors C_LOW = "#2ecc71" # green – low-risk / no risk C_TREAT = "#e74c3c" # red-orange – TREAT boxes C_OBSERVE = "#27ae60" # emerald – OBSERVE boxes C_NEUTRAL = "#2980b9" # blue – neutral decision boxes C_ORANGE = "#e67e22" # orange – intermediate / conditional treat C_BG = "#f8f9fa" # light grey background C_TEXT_W = "white" C_TEXT_D = "#1a1a2e" C_BORDER = "#2c3e50" def draw_box(ax, x, y, w, h, text, facecolor, textcolor=C_TEXT_W, fontsize=8.5, bold=False, radius=0.015, linestyle='-', edgecolor=C_BORDER, linewidth=1.5): box = FancyBboxPatch((x - w/2, y - h/2), w, h, boxstyle=f"round,pad={radius}", facecolor=facecolor, edgecolor=edgecolor, linewidth=linewidth, linestyle=linestyle, zorder=3) ax.add_patch(box) weight = 'bold' if bold else 'normal' ax.text(x, y, text, ha='center', va='center', fontsize=fontsize, color=textcolor, fontweight=weight, wrap=True, zorder=4, multialignment='center') def arrow(ax, x1, y1, x2, y2, label="", color="#555555", lw=1.6): ax.annotate("", xy=(x2, y2), xytext=(x1, y1), arrowprops=dict(arrowstyle="-|>", color=color, lw=lw, mutation_scale=12), zorder=2) if label: mx, my = (x1+x2)/2, (y1+y2)/2 ax.text(mx+0.01, my, label, fontsize=7.5, color=color, fontweight='bold', ha='left', va='center', zorder=5) def legend_patch(color, label): return mpatches.Patch(facecolor=color, edgecolor=C_BORDER, label=label, linewidth=1.2) # ══════════════════════════════════════════════════════════════ # FIGURE 1 – Flowchart 7.45.1 (Symptomatic eyes – Acute PVD) # ══════════════════════════════════════════════════════════════ fig1, ax1 = plt.subplots(figsize=(13, 10)) ax1.set_xlim(0, 1); ax1.set_ylim(0, 1) ax1.set_facecolor(C_BG); fig1.patch.set_facecolor(C_BG) ax1.axis('off') ax1.text(0.5, 0.97, "Flowchart 7.45.1 – Symptomatic Eyes with Acute PVD", ha='center', va='top', fontsize=13, fontweight='bold', color=C_START) ax1.text(0.5, 0.93, "(Eyes with floaters, flashes, etc.)", ha='center', va='top', fontsize=9, color="#555") # START draw_box(ax1, 0.5, 0.87, 0.52, 0.06, "SYMPTOMATIC EYES WITH ACUTE PVD\n(Floaters, Flashes, Photopsia)", C_START, bold=True, fontsize=9) # Branch arrows down arrow(ax1, 0.29, 0.84, 0.22, 0.77) arrow(ax1, 0.71, 0.84, 0.79, 0.77) # Branch labels ax1.text(0.14, 0.81, "Retinal\nTears", ha='center', fontsize=8, color=C_NEUTRAL, fontweight='bold') ax1.text(0.86, 0.81, "Pre-existing Retinal\nHoles & Other Lesions", ha='center', fontsize=8, color=C_NEUTRAL, fontweight='bold') # Left branch box – tears draw_box(ax1, 0.22, 0.73, 0.26, 0.07, "RETINAL TEARS", C_NEUTRAL, bold=True) # Right branch box draw_box(ax1, 0.79, 0.73, 0.30, 0.07, "Pre-existing Retinal Holes\n& Other Lesions\n→ Treat as in Asymptomatic Eyes", C_NEUTRAL, fontsize=7.5) # Sub-branches from tears arrow(ax1, 0.10, 0.695, 0.10, 0.63) arrow(ax1, 0.34, 0.695, 0.52, 0.63) ax1.text(0.05, 0.665, "With\npersistent\nVR traction", ha='center', fontsize=7.5, color=C_HIGH, fontweight='bold') ax1.text(0.40, 0.665, "Without\npersistent\nVR traction", ha='center', fontsize=7.5, color=C_LOW, fontweight='bold') # ── HIGH-RISK box (with persistent VR traction) draw_box(ax1, 0.10, 0.585, 0.26, 0.08, "⚠ HIGH RISK\nHST with residual traction\nat adjacent blood vessels\nOperculated tear with traction", C_HIGH, fontsize=7.5, bold=False, linewidth=2.5) arrow(ax1, 0.10, 0.545, 0.10, 0.475) draw_box(ax1, 0.10, 0.44, 0.22, 0.06, "✔ TREAT\n(Prompt laser/cryo)", C_TREAT, bold=True, fontsize=9, linewidth=2.5) # ── LOW-RISK box (without persistent VR traction) draw_box(ax1, 0.52, 0.585, 0.26, 0.08, "✓ LOW RISK\nOperculated holes without traction\nAtrophic holes\nRound holes", C_LOW, C_TEXT_D, fontsize=7.5, linewidth=2.5) arrow(ax1, 0.52, 0.545, 0.52, 0.475) draw_box(ax1, 0.52, 0.44, 0.22, 0.06, "👁 OBSERVE\n(Watchful waiting)", C_OBSERVE, bold=True, fontsize=9, linewidth=2.5) # Important note box draw_box(ax1, 0.5, 0.32, 0.86, 0.10, "⚡ IMPORTANT CLINICAL NOTE\n" "Call back ALL patients with acute PVD and no breaks within 6 weeks\n" "(2× chance of developing new breaks)\n" "Laser/cryo should cover anterior edge of lesion and extend to ora serrata", "#8e44ad", fontsize=8, linewidth=2, edgecolor="#6c3483") # ── HIGH-RISK FACTORS LEGEND PANEL draw_box(ax1, 0.5, 0.12, 0.86, 0.12, "", "#fdfefe", textcolor=C_TEXT_D, linewidth=1.5, edgecolor="#bdc3c7") ax1.text(0.5, 0.175, "🔴 HIGH-RISK FACTORS that mandate TREATMENT (Acute PVD context)", ha='center', fontsize=9, fontweight='bold', color=C_HIGH) risks = [ "• HST (Horseshoe Tear) with persistent vitreoretinal traction", "• Operculated tear with residual traction at adjacent blood vessels", "• Any symptomatic tear with hemorrhage or subretinal fluid", "• Giant Retinal Tear (GRT) – treat all associated lesions", ] for i, r in enumerate(risks): ax1.text(0.08, 0.157 - i*0.018, r, fontsize=7.8, color=C_TEXT_D) # Legend handles = [ legend_patch(C_HIGH, "High-Risk Feature"), legend_patch(C_TREAT, "TREAT"), legend_patch(C_OBSERVE, "OBSERVE"), legend_patch(C_LOW, "Low Risk"), legend_patch(C_NEUTRAL, "Neutral / Classify"), legend_patch("#8e44ad", "Clinical Caution"), ] ax1.legend(handles=handles, loc='lower right', fontsize=7.5, framealpha=0.9, ncol=3, title="Legend", title_fontsize=8) fig1.tight_layout() fig1.savefig("/tmp/workspace/retina-flowcharts/flowchart_7_45_1.png", dpi=180, bbox_inches='tight', facecolor=C_BG) print("Fig1 saved") # ══════════════════════════════════════════════════════════════ # FIGURE 2 – Flowchart 7.45.2 & 7.45.3 (Asymptomatic eyes) # ══════════════════════════════════════════════════════════════ fig2, axes = plt.subplots(1, 2, figsize=(18, 14)) fig2.patch.set_facecolor(C_BG) # ──────────────────── LEFT PANEL – 7.45.2 (Fellow eye) ──────────────────── ax = axes[0] ax.set_xlim(0, 1); ax.set_ylim(0, 1) ax.set_facecolor(C_BG); ax.axis('off') ax.text(0.5, 0.98, "Flowchart 7.45.2", ha='center', fontsize=12, fontweight='bold', color=C_START) ax.text(0.5, 0.945, "Asymptomatic Fellow Eye (Other Eye has RD)", ha='center', fontsize=9, color="#555") draw_box(ax, 0.5, 0.90, 0.72, 0.055, "ASYMPTOMATIC FELLOW EYE (Other Eye = RD)", C_START, bold=True, fontsize=9) # Two branches: Phakic | Aphakic/Pseudophakic arrow(ax, 0.28, 0.872, 0.23, 0.820) arrow(ax, 0.72, 0.872, 0.77, 0.820) draw_box(ax, 0.23, 0.793, 0.30, 0.048, "PHAKIC", C_NEUTRAL, bold=True) draw_box(ax, 0.77, 0.793, 0.38, 0.048, "APHAKIC / PSEUDOPHAKIC\nor Just Prior to Cataract Surgery", C_HIGH, bold=True, fontsize=8) # ── PHAKIC sub-branches arrow(ax, 0.10, 0.768, 0.10, 0.715) arrow(ax, 0.36, 0.768, 0.50, 0.715) ax.text(0.06, 0.743, "Retinal\nBreaks", ha='center', fontsize=7.5, color=C_TREAT, fontweight='bold') ax.text(0.44, 0.743, "VR Precursors\nof RD", ha='center', fontsize=7.5, color=C_ORANGE, fontweight='bold') # Breaks → Treat draw_box(ax, 0.10, 0.688, 0.14, 0.045, "✔ TREAT ALL\nBreaks", C_TREAT, bold=True, fontsize=8) # VR precursors – conditional treat box draw_box(ax, 0.50, 0.56, 0.58, 0.29, "TREAT IF any of these conditions:\n\n" "⚠ Lattice: <1.25 D myopia, <6 clock hrs & absent/incomplete PVD\n" "⚠ Lattice: >6 clock hrs AND/OR >6 D myopia → 360° barrage\n" "⚠ Lattice + poor surgical result in other eye\n" "⚠ Lattice + limited follow-up\n" "⚠ Lattice + cannot recognise PVD/RD symptoms\n" "⚠ Progressively increasing vitreous liquefaction/white\n" " with pressure if other eye had GRT", C_TREAT, fontsize=7.5, linewidth=2.5, radius=0.012) ax.text(0.50, 0.415, "Otherwise → OBSERVE", ha='center', fontsize=8.5, color=C_OBSERVE, fontweight='bold') draw_box(ax, 0.50, 0.380, 0.30, 0.05, "👁 OBSERVE", C_OBSERVE, bold=True, fontsize=10) # Arrow from VR precursors → conditional treat arrow(ax, 0.50, 0.715, 0.50, 0.705) # ── APHAKIC / PSEUDOPHAKIC conditional treat draw_box(ax, 0.77, 0.555, 0.38, 0.35, "TREAT IF any of these:\n\n" "🔴 Progressively increasing vitreous\n" " liquefaction/white with pressure\n" " (other eye had GRT)\n\n" "🔴 Retinal Breaks (any)\n\n" "🔴 Lattice → 360° barrage treatment", C_HIGH, fontsize=8, linewidth=2.5, radius=0.012) ax.text(0.77, 0.365, "Otherwise → OBSERVE", ha='center', fontsize=8.5, color=C_OBSERVE, fontweight='bold') draw_box(ax, 0.77, 0.330, 0.30, 0.05, "👁 OBSERVE", C_OBSERVE, bold=True, fontsize=10) arrow(ax, 0.77, 0.768, 0.77, 0.730) # ── High-risk summary panel draw_box(ax, 0.5, 0.16, 0.88, 0.20, "", "#fdfefe", textcolor=C_TEXT_D, linewidth=1.5, edgecolor="#bdc3c7") ax.text(0.5, 0.255, "🔴 HIGH-RISK FACTORS – Asymptomatic Fellow Eye", ha='center', fontsize=9, fontweight='bold', color=C_HIGH) items = [ ("PHAKIC risks:", C_NEUTRAL), (" • Lattice >6 clock hours or >6 D myopia → 360° barrage", C_TEXT_D), (" • Poor surgical outcome in contralateral eye", C_TEXT_D), (" • Limited follow-up / cannot report symptoms", C_TEXT_D), (" • Progressively increasing vitreous liquefaction if other eye had GRT", C_TEXT_D), ("APHAKIC / PSEUDOPHAKIC risks:", C_HIGH), (" • ANY retinal break → treat all", C_TEXT_D), (" • Lattice degeneration → 360° barrage", C_TEXT_D), (" • Increasing vitreous liq. with GRT in fellow eye", C_TEXT_D), ] for i, (txt, col) in enumerate(items): ax.text(0.06, 0.237 - i*0.020, txt, fontsize=7.5, color=col, fontweight='bold' if ':' in txt and not ' •' in txt else 'normal') # ──────────────────── RIGHT PANEL – 7.45.3 (Nonfellow eye) ──────────────────── ax2 = axes[1] ax2.set_xlim(0, 1); ax2.set_ylim(0, 1) ax2.set_facecolor(C_BG); ax2.axis('off') ax2.text(0.5, 0.98, "Flowchart 7.45.3", ha='center', fontsize=12, fontweight='bold', color=C_START) ax2.text(0.5, 0.945, "Asymptomatic NON-Fellow Eye", ha='center', fontsize=9, color="#555") draw_box(ax2, 0.5, 0.90, 0.72, 0.055, "ASYMPTOMATIC NON-FELLOW EYE", C_START, bold=True, fontsize=9) # Two branches arrow(ax2, 0.28, 0.872, 0.23, 0.820) arrow(ax2, 0.72, 0.872, 0.77, 0.820) draw_box(ax2, 0.23, 0.793, 0.36, 0.048, "WITHOUT High-Risk Factors", C_LOW, C_TEXT_D, bold=True, fontsize=8.5) draw_box(ax2, 0.77, 0.793, 0.36, 0.048, "WITH High-Risk Factors", C_HIGH, bold=True, fontsize=8.5) # Without HRF branch draw_box(ax2, 0.23, 0.700, 0.36, 0.075, "✔ TREAT only if:\n• Subclinical RD\n• Inferior retinal dialysis", C_TREAT, fontsize=8, linewidth=2) arrow(ax2, 0.23, 0.815, 0.23, 0.738) ax2.text(0.23, 0.628, "All other findings\n→ OBSERVE", ha='center', fontsize=8.5, color=C_OBSERVE, fontweight='bold') draw_box(ax2, 0.23, 0.592, 0.28, 0.05, "👁 OBSERVE", C_OBSERVE, bold=True, fontsize=10) # With HRF → three sub-boxes arrow(ax2, 0.77, 0.815, 0.77, 0.760) # Sub 1: Myopia draw_box(ax2, 0.77, 0.700, 0.38, 0.10, "🔴 MYOPIA\n" "• HST → TREAT\n" "• Lattice → Based on\n clinical discretion", C_HIGH, fontsize=8, linewidth=2) # Arrow down to Aphakic/pseudophakic arrow(ax2, 0.77, 0.650, 0.77, 0.590) draw_box(ax2, 0.77, 0.530, 0.38, 0.10, "🔴 APHAKIC / PSEUDOPHAKIC\nor Family History of RD\n" "• TREAT ALL lesions\n (no exceptions)", C_HIGH, fontsize=8, linewidth=2) arrow(ax2, 0.77, 0.480, 0.77, 0.420) draw_box(ax2, 0.77, 0.360, 0.38, 0.10, "🔴 JUST PRIOR TO\nCATARACT SURGERY\n" "• Treat HSTs only\n (not lattice alone)", C_HIGH, fontsize=8, linewidth=2) # High-risk factor summary panel draw_box(ax2, 0.5, 0.19, 0.88, 0.26, "", "#fdfefe", textcolor=C_TEXT_D, linewidth=1.5, edgecolor="#bdc3c7") ax2.text(0.5, 0.315, "🔴 HIGH-RISK FACTORS – Non-Fellow Eye (by category)", ha='center', fontsize=9, fontweight='bold', color=C_HIGH) hrf_items = [ ("MYOPIA:", C_HIGH), (" • Any HST → Treat regardless of extent", C_TEXT_D), (" • Lattice degeneration → clinical discretion (degree, PVD status)", C_TEXT_D), ("APHAKIC / PSEUDOPHAKIC:", C_HIGH), (" • All VR lesions require treatment (lens removed = higher RD risk)", C_TEXT_D), (" • Family history of RD → treat all lesions", C_TEXT_D), ("PRE-CATARACT SURGERY:", C_HIGH), (" • Treat HSTs only; lattice alone does not require prophylaxis", C_TEXT_D), ("LOW-RISK (Observe only):", C_OBSERVE), (" • Atrophic holes, snail-track without HST, lattice without myopia/PVD", C_TEXT_D), ] for i, (txt, col) in enumerate(hrf_items): ax2.text(0.06, 0.298 - i*0.021, txt, fontsize=7.5, color=col, fontweight='bold' if not txt.startswith(' •') else 'normal') # Global figure title fig2.suptitle("Vitreoretinal Prophylaxis Decision Framework – Asymptomatic Eyes\n" "(Based on AAO Preferred Practice Pattern, 2019)", fontsize=12, fontweight='bold', color=C_START, y=1.01) # Shared legend handles2 = [ legend_patch(C_HIGH, "High-Risk Factor / Condition"), legend_patch(C_TREAT, "TREAT (Active Intervention)"), legend_patch(C_OBSERVE, "OBSERVE (Watchful Waiting)"), legend_patch(C_LOW, "Low-Risk / Phakic Baseline"), legend_patch(C_NEUTRAL, "Neutral Classify Node"), legend_patch(C_ORANGE, "Intermediate / Conditional"), ] fig2.legend(handles=handles2, loc='lower center', fontsize=8.5, framealpha=0.9, ncol=3, title="Legend", title_fontsize=9, bbox_to_anchor=(0.5, -0.01)) fig2.tight_layout(pad=2.0) fig2.savefig("/tmp/workspace/retina-flowcharts/flowchart_7_45_2_3.png", dpi=180, bbox_inches='tight', facecolor=C_BG) print("Fig2 saved") PYEOF python3 /tmp/workspace/retina-flowcharts/flowcharts.py
ls -lh /tmp/workspace/retina-flowcharts/
flowchart 7 45 1
Image · PNG
flowchart 7 45 2 3
Image · PNG
| Color | Meaning |
|---|---|
| Red/Crimson | High-risk factor or high-risk patient category |
| Red-orange | TREAT - active intervention needed |
| Emerald green | OBSERVE - watchful waiting appropriate |
| Blue | Neutral classification node |
| Dark navy | Starting point |