Make me flow charts in pdf

Reading File
Running Command

cd /home/daytona/workspace && python3 -c " import pdfplumber with pdfplumber.open('attachments/6c15b3c4-fc9b-416c-89e8-22ebec4be073/Circulatory system.pdf') as pdf: for i, page in enumerate(pdf.pages): print(f'=== PAGE {i+1} ===') text = page.extract_text() print(text) print() "

Running Command

mkdir -p /home/daytona/workspace/circulatory-flowcharts && python3 -c "import matplotlib; import reportlab; print('libs ok')"

Writing File

~/circulatory-flowcharts/make_flowcharts.py

import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
from matplotlib.patches import FancyArrowPatch, FancyBboxPatch
from matplotlib.backends.backend_pdf import PdfPages
import numpy as np

OUTPUT = "/home/daytona/workspace/circulatory-flowcharts/Circulatory_System_Flowcharts.pdf"

# ── colour palette ──────────────────────────────────────────────────────────
C_TITLE   = "#1A237E"   # deep navy
C_BOX_BLU = "#E3F2FD"   # light blue fill
C_BOX_RED = "#FFEBEE"   # light red fill
C_BOX_GRN = "#E8F5E9"   # light green fill
C_BOX_ORG = "#FFF3E0"   # light orange fill
C_BOX_PUR = "#F3E5F5"   # light purple fill
C_BOX_GRY = "#F5F5F5"   # light grey fill
C_ARR     = "#37474F"   # arrow / border colour
C_TXT     = "#1A1A2E"   # body text

def rounded_box(ax, x, y, w, h, text, facecolor, edgecolor=C_ARR,
                fontsize=9, bold=False, radius=0.04):
    box = FancyBboxPatch((x - w/2, y - h/2), w, h,
                         boxstyle=f"round,pad=0.01,rounding_size={radius}",
                         facecolor=facecolor, edgecolor=edgecolor, linewidth=1.2,
                         zorder=3)
    ax.add_patch(box)
    ax.text(x, y, text, ha='center', va='center', fontsize=fontsize,
            fontweight='bold' if bold else 'normal', color=C_TXT,
            zorder=4, wrap=True,
            multialignment='center')

def diamond(ax, x, y, w, h, text, facecolor=C_BOX_ORG, fontsize=8.5):
    dx, dy = w/2, h/2
    xs = [x, x+dx, x, x-dx, x]
    ys = [y+dy, y, y-dy, y, y+dy]
    ax.fill(xs, ys, facecolor=facecolor, edgecolor=C_ARR, linewidth=1.2, zorder=3)
    ax.text(x, y, text, ha='center', va='center', fontsize=fontsize,
            color=C_TXT, zorder=4, multialignment='center')

def arrow(ax, x1, y1, x2, y2, label='', color=C_ARR):
    ax.annotate('', xy=(x2, y2), xytext=(x1, y1),
                arrowprops=dict(arrowstyle='->', color=color, lw=1.5),
                zorder=2)
    if label:
        mx, my = (x1+x2)/2, (y1+y2)/2
        ax.text(mx+0.02, my, label, fontsize=7.5, color='#555555', zorder=5)

def page_title(ax, title, subtitle=''):
    ax.text(0.5, 0.97, title, transform=ax.transAxes,
            ha='center', va='top', fontsize=14, fontweight='bold', color=C_TITLE)
    if subtitle:
        ax.text(0.5, 0.93, subtitle, transform=ax.transAxes,
                ha='center', va='top', fontsize=9, color='#555555')

def clean_ax(ax, xlim=(0,1), ylim=(0,1)):
    ax.set_xlim(*xlim)
    ax.set_ylim(*ylim)
    ax.axis('off')

# ═══════════════════════════════════════════════════════════════════════════
# PAGE 1 – Pulmonary & Systemic Circulation
# ═══════════════════════════════════════════════════════════════════════════
def page_pulmonary_systemic(pdf):
    fig, ax = plt.subplots(figsize=(8.5, 11))
    clean_ax(ax, (0, 10), (0, 14))
    page_title(ax, "Flowchart 1: The Two Main Circulatory Circuits",
               "Pulmonary Circulation  |  Systemic Circulation  |  Portal Circulation")

    BW, BH = 3.6, 0.55   # box width / height

    # ── LEFT column: Pulmonary ──────────────────────────────────────────
    lx = 2.6
    nodes_l = [
        (lx, 12.5, "Upper & Lower Body Tissues\n(deoxygenated blood)", C_BOX_RED),
        (lx, 11.5, "Superior & Inferior Vena Cava",  C_BOX_BLU),
        (lx, 10.5, "Right Atrium",                   C_BOX_BLU),
        (lx,  9.5, "Right Ventricle",                C_BOX_BLU),
        (lx,  8.5, "Pulmonary Arteries",             C_BOX_BLU),
        (lx,  7.5, "Lungs\n(O₂ absorbed / CO₂ released)", C_BOX_GRN),
    ]
    for (x, y, t, c) in nodes_l:
        rounded_box(ax, x, y, BW, BH, t, c)
    for i in range(len(nodes_l)-1):
        arrow(ax, nodes_l[i][0], nodes_l[i][1]-BH/2,
                  nodes_l[i+1][0], nodes_l[i+1][1]+BH/2)

    ax.text(lx, 13.3, "PULMONARY CIRCULATION", ha='center', fontsize=10,
            fontweight='bold', color='#1565C0')

    # ── RIGHT column: Systemic ──────────────────────────────────────────
    rx = 7.4
    nodes_r = [
        (rx, 7.5,  "Pulmonary Veins\n(oxygenated blood)",  C_BOX_GRN),
        (rx, 8.5,  "Left Atrium",                          C_BOX_RED),
        (rx, 9.5,  "Left Ventricle",                       C_BOX_RED),
        (rx, 10.5, "Aorta",                                C_BOX_RED),
        (rx, 11.5, "Body Tissues / Organs",                C_BOX_ORG),
        (rx, 12.5, "Systemic Capillaries\n(O₂ delivered / CO₂ collected)", C_BOX_ORG),
    ]
    for (x, y, t, c) in nodes_r:
        rounded_box(ax, x, y, BW, BH, t, c)
    for i in range(len(nodes_r)-1):
        arrow(ax, nodes_r[i][0], nodes_r[i][1]+BH/2,
                  nodes_r[i+1][0], nodes_r[i+1][1]-BH/2)

    ax.text(rx, 13.3, "SYSTEMIC CIRCULATION", ha='center', fontsize=10,
            fontweight='bold', color='#B71C1C')

    # Heart box in the middle
    rounded_box(ax, 5.0, 6.4, 2.2, 0.65, "HEART\n(Central Pump)",
                "#FFF9C4", edgecolor="#F9A825", fontsize=9, bold=True)

    # Arrows: heart ↔ columns
    arrow(ax, 3.8, 7.5, 4.0, 6.6)   # lungs→heart left
    arrow(ax, 4.0, 6.2, 3.8, 7.2)   # heart→pulm art (right ventricle side)
    arrow(ax, 6.0, 6.6, 6.2, 7.5)   # heart→pulm veins
    arrow(ax, 6.2, 7.2, 6.0, 6.2)

    # ── Portal circulation inset ────────────────────────────────────────
    px = 5.0
    rounded_box(ax, px, 4.8, 7.5, 0.5,
                "PORTAL CIRCULATION  –  A special part of the systemic circuit",
                C_BOX_PUR, bold=True, fontsize=9)

    portal_nodes = [
        (px, 4.0, "Digestive Organs\n(stomach, bowel, pancreas, spleen)", C_BOX_GRN),
        (px, 3.1, "Portal Vein",                                           C_BOX_BLU),
        (px, 2.2, "Liver Capillary Bed\n(filtering & metabolic processing)", C_BOX_ORG),
        (px, 1.3, "Hepatic Veins → Inferior Vena Cava",                    C_BOX_BLU),
    ]
    PW = 4.2
    for (x, y, t, c) in portal_nodes:
        rounded_box(ax, x, y, PW, 0.62, t, c, fontsize=8.5)
    for i in range(len(portal_nodes)-1):
        arrow(ax, portal_nodes[i][0], portal_nodes[i][1]-0.31,
                  portal_nodes[i+1][0], portal_nodes[i+1][1]+0.31)
    arrow(ax, px, 4.8-0.25, px, 4.0+0.31)

    ax.text(0.12, 0.018, "Source: THIEME Atlas of Anatomy – General Anatomy, Sections 6.1–6.3",
            transform=ax.transAxes, fontsize=7, color='#888888')

    plt.tight_layout()
    pdf.savefig(fig, bbox_inches='tight')
    plt.close(fig)

# ═══════════════════════════════════════════════════════════════════════════
# PAGE 2 – Functional Pressure Systems
# ═══════════════════════════════════════════════════════════════════════════
def page_pressure_systems(pdf):
    fig, ax = plt.subplots(figsize=(8.5, 11))
    clean_ax(ax, (0, 10), (0, 14))
    page_title(ax, "Flowchart 2: Functional Pressure Systems",
               "High-Pressure System  →  Capillary Exchange  →  Low-Pressure System")

    BW, BH = 3.8, 0.60

    # High pressure column (left)
    lx = 2.5
    ax.text(lx, 13.3, "HIGH-PRESSURE SYSTEM (~100 mmHg)", ha='center',
            fontsize=10, fontweight='bold', color='#B71C1C')
    hp = [
        (lx, 12.6, "Left Ventricle\n(Pump origin, systole ~120 mmHg)", C_BOX_RED),
        (lx, 11.5, "Elastic Arteries (e.g. Aorta)\n• Expand during systole\n• Elastic recoil during diastole\n  → converts pulsatile to continuous flow", C_BOX_RED),
        (lx, 10.1, "Muscular Arteries\n• Active vasodilation / vasoconstriction\n• Control vascular resistance\n• Regulate local blood flow", C_BOX_RED),
        (lx,  8.9, "Arterioles\n(Pressure drops significantly here)", C_BOX_ORG),
    ]
    heights = [0.60, 1.2, 1.0, 0.60]
    for i,(x,y,t,c) in enumerate(hp):
        h = heights[i]
        box = FancyBboxPatch((x-BW/2, y-h/2), BW, h,
                             boxstyle="round,pad=0.01,rounding_size=0.04",
                             facecolor=c, edgecolor=C_ARR, linewidth=1.2, zorder=3)
        ax.add_patch(box)
        ax.text(x, y, t, ha='center', va='center', fontsize=8.2,
                color=C_TXT, zorder=4, multialignment='center')
    # arrows
    y_bottoms = [y-h/2 for (x,y,t,c),h in zip(hp, heights)]
    y_tops    = [y+h/2 for (x,y,t,c),h in zip(hp, heights)]
    for i in range(len(hp)-1):
        arrow(ax, hp[i][0], y_bottoms[i], hp[i+1][0], y_tops[i+1])

    # Capillary exchange (centre)
    cx = 5.0
    ax.text(cx, 7.9, "CAPILLARY EXCHANGE ZONE", ha='center', fontsize=10,
            fontweight='bold', color='#1B5E20')
    cap_nodes = [
        (cx, 7.3,  "Precapillary Sphincters\n(regulate entry; only 25–35% open at rest)", C_BOX_GRN, 0.65),
        (cx, 6.3,  "Capillary Bed (5–15 µm)\n• 800× cross-section of aorta\n• Flow drops: 50 cm/s → 0.05 cm/s\n• ~1 second for metabolic exchange", C_BOX_GRN, 1.1),
        (cx, 4.85, "Starling Forces\nArterial end: HP 35 > COP 25 → fluid OUT\nVenous end:   HP 15 < COP 25 → fluid IN\nExcess → Lymphatic capillaries", C_BOX_GRN, 1.0),
    ]
    for (x,y,t,c,h) in cap_nodes:
        box = FancyBboxPatch((x-2.2, y-h/2), 4.4, h,
                             boxstyle="round,pad=0.01,rounding_size=0.04",
                             facecolor=c, edgecolor=C_ARR, linewidth=1.2, zorder=3)
        ax.add_patch(box)
        ax.text(x, y, t, ha='center', va='center', fontsize=8.2,
                color=C_TXT, zorder=4, multialignment='center')
    for i in range(len(cap_nodes)-1):
        arrow(ax, cap_nodes[i][0], cap_nodes[i][1]-cap_nodes[i][4]/2,
                  cap_nodes[i+1][0], cap_nodes[i+1][1]+cap_nodes[i+1][4]/2)

    # Low pressure column (right)
    rx = 7.5
    ax.text(rx, 13.3, "LOW-PRESSURE SYSTEM (< 20 mmHg)", ha='center',
            fontsize=10, fontweight='bold', color='#1565C0')
    lp = [
        (rx, 12.6, "Venules\n(postcapillary)", C_BOX_BLU),
        (rx, 11.6, "Veins\n(capacitance vessels)\n• Hold ~80% of total blood volume\n• Serve as blood reservoir", C_BOX_BLU),
        (rx, 10.2, "Pulmonary Vessels\n(also low pressure < 20 mmHg)\n• Lung capillary bed", C_BOX_BLU),
        (rx,  9.1, "Right Atrium / Right Ventricle", C_BOX_BLU),
    ]
    lp_h = [0.6, 1.0, 0.9, 0.6]
    for i,(x,y,t,c) in enumerate(lp):
        h = lp_h[i]
        box = FancyBboxPatch((x-BW/2, y-h/2), BW, h,
                             boxstyle="round,pad=0.01,rounding_size=0.04",
                             facecolor=c, edgecolor=C_ARR, linewidth=1.2, zorder=3)
        ax.add_patch(box)
        ax.text(x, y, t, ha='center', va='center', fontsize=8.2,
                color=C_TXT, zorder=4, multialignment='center')
    lp_bottoms = [y-h/2 for (x,y,t,c),h in zip(lp, lp_h)]
    lp_tops    = [y+h/2 for (x,y,t,c),h in zip(lp, lp_h)]
    for i in range(len(lp)-1):
        arrow(ax, lp[i][0], lp_bottoms[i], lp[i+1][0], lp_tops[i+1])

    # Connecting arrows across columns to capillary box
    arrow(ax, hp[-1][0]+BW/2-0.2, hp[-1][1], cx-2.2, cap_nodes[0][1], color='#E65100')
    arrow(ax, cx+2.2, cap_nodes[0][1], lp[0][0]-BW/2+0.2, lp[0][1], color='#0D47A1')

    # Lymphatic inset
    rounded_box(ax, 5.0, 2.8, 5.5, 0.55,
                "Lymphatic System: collects excess interstitial fluid → lymph nodes → returns to venous blood",
                C_BOX_PUR, fontsize=8.5)
    arrow(ax, cx, cap_nodes[-1][1]-cap_nodes[-1][4]/2, 5.0, 2.8+0.28, color='#6A1B9A')

    ax.text(0.12, 0.018, "Source: THIEME Atlas of Anatomy – General Anatomy, Sections 6.1–6.3",
            transform=ax.transAxes, fontsize=7, color='#888888')
    plt.tight_layout()
    pdf.savefig(fig, bbox_inches='tight')
    plt.close(fig)

# ═══════════════════════════════════════════════════════════════════════════
# PAGE 3 – Structure of Blood Vessel Walls
# ═══════════════════════════════════════════════════════════════════════════
def page_vessel_structure(pdf):
    fig, ax = plt.subplots(figsize=(8.5, 11))
    clean_ax(ax, (0, 10), (0, 14))
    page_title(ax, "Flowchart 3: Structure of Blood Vessel Walls",
               "Three Fundamental Layers  |  Artery vs. Vein Differences")

    # Three layers (stacked large boxes)
    layers = [
        (5.0, 11.8, "LAYER 1 – Tunica Intima  (Innermost)",
         "• Spindle-shaped endothelial cells aligned along vessel axis\n"
         "• Resting on basement membrane + thin subendothelial connective tissue\n"
         "• In muscular arteries: separated from media by internal elastic membrane\n"
         "• Function: Exchange of gases, fluids & substances through vessel wall",
         C_BOX_GRN),
        (5.0,  9.5, "LAYER 2 – Tunica Media  (Middle)",
         "• Circular arrangement of smooth muscle cells\n"
         "• Elastic and collagenous fibres + proteoglycans\n"
         "• Muscular arteries may have external elastic membrane\n"
         "• Function: Regulates blood flow via contraction / relaxation of smooth muscle",
         C_BOX_ORG),
        (5.0,  7.2, "LAYER 3 – Tunica Adventitia  (Outermost)",
         "• Longitudinally aligned connective tissue; veins may also have smooth muscle\n"
         "• Contains autonomic nerves to vessel wall muscle\n"
         "• Larger vessels: vasa vasorum (supply outer third of vessel wall)\n"
         "• Function: Integrates blood vessel into surrounding tissue",
         C_BOX_BLU),
    ]
    for (x, y, title, detail, col) in layers:
        h = 1.8
        box = FancyBboxPatch((x-4.5, y-h/2), 9.0, h,
                             boxstyle="round,pad=0.02,rounding_size=0.06",
                             facecolor=col, edgecolor=C_ARR, linewidth=1.4, zorder=3)
        ax.add_patch(box)
        ax.text(x, y+0.55, title, ha='center', va='center', fontsize=9.5,
                fontweight='bold', color=C_TITLE, zorder=4)
        ax.text(x, y-0.15, detail, ha='center', va='center', fontsize=8.0,
                color=C_TXT, zorder=4, multialignment='center')

    arrow(ax, 5.0, 10.9, 5.0, 10.4)
    arrow(ax, 5.0,  8.6, 5.0,  8.1)

    # Artery vs Vein comparison boxes
    ax.text(5.0, 5.7, "Artery  vs.  Vein  –  Key Differences",
            ha='center', fontsize=10, fontweight='bold', color=C_TITLE)

    art_detail = (
        "ARTERIES\n"
        "• Thick, densely packed smooth muscle in media\n"
        "• Prominent internal elastic membrane\n"
        "• Elastic type (aorta): expand & recoil\n"
        "• Muscular type: active vasoconstriction /\n"
        "  vasodilation for flow regulation"
    )
    vein_detail = (
        "VEINS\n"
        "• More connective tissue (collagen & elastic fibres)\n"
        "• Looser wall structure\n"
        "• No prominent internal elastic membrane\n"
        "• Capacitance vessels: hold ~80% blood volume\n"
        "• May have smooth muscle in adventitia"
    )
    for x, text, col in [(2.8, art_detail, C_BOX_RED), (7.2, vein_detail, C_BOX_BLU)]:
        box = FancyBboxPatch((x-2.4, 3.2), 4.8, 2.2,
                             boxstyle="round,pad=0.02,rounding_size=0.06",
                             facecolor=col, edgecolor=C_ARR, linewidth=1.2, zorder=3)
        ax.add_patch(box)
        ax.text(x, 4.3, text, ha='center', va='center', fontsize=8.0,
                color=C_TXT, zorder=4, multialignment='center')

    # VS label
    ax.text(5.0, 4.3, "VS", ha='center', va='center', fontsize=14,
            fontweight='bold', color='#757575')

    # Capillary note at bottom
    rounded_box(ax, 5.0, 2.3, 8.5, 0.70,
                "CAPILLARIES  –  Simplest vessels\n"
                "Only endothelial layer + basal lamina (no media or adventitia)  |  Diameter: 5–15 µm",
                C_BOX_GRY, fontsize=8.5)

    ax.text(0.12, 0.018, "Source: THIEME Atlas of Anatomy – General Anatomy, Section 6.2",
            transform=ax.transAxes, fontsize=7, color='#888888')
    plt.tight_layout()
    pdf.savefig(fig, bbox_inches='tight')
    plt.close(fig)

# ═══════════════════════════════════════════════════════════════════════════
# PAGE 4 – Microcirculation & Capillary Endothelium Types
# ═══════════════════════════════════════════════════════════════════════════
def page_microcirculation(pdf):
    fig, ax = plt.subplots(figsize=(8.5, 11))
    clean_ax(ax, (0, 10), (0, 14))
    page_title(ax, "Flowchart 4: Terminal Vascular Bed & Microcirculation",
               "Afferent Limb  →  Capillary Bed  →  Efferent Limb  |  Capillary Endothelium Types")

    BW = 4.0

    # Afferent → capillary → efferent
    flow = [
        (5.0, 12.8, "Arteriole\n(afferent arterial limb)", C_BOX_RED, 0.65),
        (5.0, 12.0, "Metarteriole", C_BOX_RED, 0.55),
        (5.0, 11.1, "Precapillary Sphincter\n(circular muscle; opens/closes capillary entry)\nResting: only 25–35% of capillaries open", C_BOX_ORG, 0.9),
    ]
    for (x,y,t,c,h) in flow:
        box = FancyBboxPatch((x-BW/2, y-h/2), BW, h,
                             boxstyle="round,pad=0.01,rounding_size=0.04",
                             facecolor=c, edgecolor=C_ARR, linewidth=1.2, zorder=3)
        ax.add_patch(box)
        ax.text(x, y, t, ha='center', va='center', fontsize=8.2,
                color=C_TXT, zorder=4, multialignment='center')
    arrow(ax, 5.0, 12.8-0.33, 5.0, 12.0+0.28)
    arrow(ax, 5.0, 12.0-0.28, 5.0, 11.1+0.45)

    # Capillary bed
    cap_h = 1.3
    box = FancyBboxPatch((5.0-BW/2, 9.5-cap_h/2), BW, cap_h,
                         boxstyle="round,pad=0.02,rounding_size=0.06",
                         facecolor=C_BOX_GRN, edgecolor="#2E7D32", linewidth=2, zorder=3)
    ax.add_patch(box)
    ax.text(5.0, 9.5, "CAPILLARY BED\nDiameter: 5–15 µm\nCross-section: 800× that of aorta\nBlood velocity: 50 cm/s (aorta) → 0.05 cm/s\nExchange time: ~1 second",
            ha='center', va='center', fontsize=8.2, color=C_TXT, zorder=4, multialignment='center')
    arrow(ax, 5.0, flow[-1][1]-flow[-1][4]/2, 5.0, 9.5+cap_h/2)

    # AV shunt side branch
    ax.annotate('', xy=(7.8, 9.5), xytext=(7.8, 11.4),
                arrowprops=dict(arrowstyle='->', color='#E65100', lw=1.4,
                                connectionstyle='arc3,rad=0'))
    ax.text(8.2, 10.45, "AV\nAnastomosis\n(shunt)", ha='center', va='center',
            fontsize=7.5, color='#E65100',
            bbox=dict(facecolor='#FFF3E0', edgecolor='#E65100', boxstyle='round'))

    # Efferent
    eff = [
        (5.0, 8.5, "Postcapillary Venule\n(efferent venous limb)", C_BOX_BLU, 0.65),
        (5.0, 7.6, "Venule → Vein", C_BOX_BLU, 0.55),
    ]
    for (x,y,t,c,h) in eff:
        box = FancyBboxPatch((x-BW/2, y-h/2), BW, h,
                             boxstyle="round,pad=0.01,rounding_size=0.04",
                             facecolor=c, edgecolor=C_ARR, linewidth=1.2, zorder=3)
        ax.add_patch(box)
        ax.text(x, y, t, ha='center', va='center', fontsize=8.2,
                color=C_TXT, zorder=4, multialignment='center')
    arrow(ax, 5.0, 9.5-cap_h/2, 5.0, eff[0][1]+eff[0][4]/2)
    arrow(ax, 5.0, eff[0][1]-eff[0][4]/2, 5.0, eff[1][1]+eff[1][4]/2)

    # Capillary endothelium types table
    ax.text(5.0, 6.7, "Types of Capillary Endothelium", ha='center', fontsize=10,
            fontweight='bold', color=C_TITLE)

    types = [
        ("Type I",   "Continuous, no fenestrations\nContinuous basal lamina",                 "Nervous system",                   C_BOX_GRY),
        ("Type II",  "Continuous, with pinocytotic activity",                                  "Cardiac & skeletal muscle",        C_BOX_BLU),
        ("Type III", "Fenestrated by a diaphragm",                                             "Gastrointestinal tract, kidneys",  C_BOX_ORG),
        ("Type IV",  "Intercellular gaps\nNo continuous basal lamina",                         "Liver (sinusoids)",                C_BOX_RED),
    ]
    col_xs = [1.4, 4.5, 8.0]
    col_labels = ["Type", "Structure", "Location"]
    header_y = 6.15
    for lx, label in zip(col_xs, col_labels):
        ax.text(lx, header_y, label, ha='center', va='center', fontsize=9,
                fontweight='bold', color='white',
                bbox=dict(facecolor=C_TITLE, boxstyle='round,pad=0.3'))

    row_h = 0.75
    for i, (typ, struct, loc, col) in enumerate(types):
        y = header_y - (i+1)*row_h - 0.1
        box = FancyBboxPatch((0.2, y-row_h/2+0.05), 9.6, row_h-0.1,
                             boxstyle="round,pad=0.01,rounding_size=0.03",
                             facecolor=col, edgecolor=C_ARR, linewidth=0.8, zorder=3)
        ax.add_patch(box)
        ax.text(col_xs[0], y, typ,    ha='center', va='center', fontsize=8.5, fontweight='bold', color=C_TXT, zorder=4)
        ax.text(col_xs[1], y, struct, ha='center', va='center', fontsize=8.0, color=C_TXT, zorder=4, multialignment='center')
        ax.text(col_xs[2], y, loc,    ha='center', va='center', fontsize=8.0, color=C_TXT, zorder=4, multialignment='center')

    ax.text(0.12, 0.018, "Source: THIEME Atlas of Anatomy – General Anatomy, Section 6.3",
            transform=ax.transAxes, fontsize=7, color='#888888')
    plt.tight_layout()
    pdf.savefig(fig, bbox_inches='tight')
    plt.close(fig)

# ═══════════════════════════════════════════════════════════════════════════
# PAGE 5 – Embryonic Circulation & Lymphatics
# ═══════════════════════════════════════════════════════════════════════════
def page_embryo_lymph(pdf):
    fig, ax = plt.subplots(figsize=(8.5, 11))
    clean_ax(ax, (0, 10), (0, 14))
    page_title(ax, "Flowchart 5: Embryonic Circulation & Lymphatic System",
               "3–4 Week Embryo  |  Three Circulatory Systems  |  Lymphatic Pathway")

    BW = 4.0

    # Header
    ax.text(5.0, 13.0, "EARLY EMBRYONIC CARDIOVASCULAR SYSTEM (Weeks 3–4)",
            ha='center', fontsize=10, fontweight='bold', color=C_TITLE)
    rounded_box(ax, 5.0, 12.4, 6.0, 0.55,
                "Two-chambered heart  +  Three distinct circulatory systems",
                "#E8EAF6", bold=True, fontsize=9)

    # Three circuits
    circuits = [
        (1.8, [
            (1.8, 11.3, "Intraembryonic\nSystemic Circulation", C_BOX_ORG),
            (1.8, 10.3, "Ventral & Dorsal Aorta\nBranchial / Aortic Arches", C_BOX_ORG),
            (1.8,  9.3, "Anterior & Posterior\nCardinal Veins", C_BOX_ORG),
        ]),
        (5.0, [
            (5.0, 11.3, "Extraembryonic Vitelline\nCirculation", C_BOX_GRN),
            (5.0, 10.3, "Omphalomesenteric\nArteries", C_BOX_GRN),
            (5.0,  9.3, "Omphalomesenteric\n(Vitelline) Veins", C_BOX_GRN),
        ]),
        (8.2, [
            (8.2, 11.3, "Placental Circulation", C_BOX_BLU),
            (8.2, 10.3, "Umbilical Arteries\n(deoxygenated blood to placenta)", C_BOX_BLU),
            (8.2,  9.3, "Umbilical Vein\n(O₂-rich blood to embryo\n– note: vein carries O₂ blood!)", C_BOX_BLU),
        ]),
    ]
    for (_, nodes) in circuits:
        for (x,y,t,c) in nodes:
            rounded_box(ax, x, y, 3.0, 0.70, t, c, fontsize=8.2)
        for i in range(len(nodes)-1):
            arrow(ax, nodes[i][0], nodes[i][1]-0.35, nodes[i+1][0], nodes[i+1][1]+0.35)
        arrow(ax, 5.0, 12.4-0.28, nodes[0][0], nodes[0][1]+0.35)

    # Note about symmetry loss
    rounded_box(ax, 5.0, 8.4, 8.5, 0.65,
                "Initially: largely symmetrical vascular arrangement\n"
                "With development: symmetry lost → LEFT-sided preponderance\n"
                "(e.g., left 4th aortic arch becomes the definitive aortic arch)",
                C_BOX_PUR, fontsize=8.5)

    # Lymphatic system
    ax.text(5.0, 7.5, "LYMPHATIC SYSTEM", ha='center', fontsize=10,
            fontweight='bold', color=C_TITLE)

    lymph = [
        (5.0, 6.9, "Interstitium\n(excess fluid from capillary exchange)", C_BOX_GRY),
        (5.0, 6.0, "Blind-ended Lymphatic Capillaries\n(initial collectors)", C_BOX_PUR),
        (5.0, 5.1, "Lymph Nodes\n(biological filtration of lymph)", C_BOX_PUR),
        (5.0, 4.2, "Progressively Larger Lymphatic Vessels\n(thoracic duct / right lymphatic duct)", C_BOX_PUR),
        (5.0, 3.3, "Venous Blood\n(subclavian vein junction – returns lymph to circulation)", C_BOX_BLU),
    ]
    for (x,y,t,c) in lymph:
        rounded_box(ax, x, y, 5.5, 0.65, t, c, fontsize=8.5)
    for i in range(len(lymph)-1):
        arrow(ax, lymph[i][0], lymph[i][1]-0.33, lymph[i+1][0], lymph[i+1][1]+0.33)

    # Key rule callout
    rounded_box(ax, 5.0, 2.1, 8.5, 0.65,
                "KEY RULE: All vessels leading AWAY from the heart = Arteries\n"
                "All vessels leading TOWARD the heart = Veins  (regardless of O₂ content)",
                "#FFFDE7", edgecolor="#F9A825", fontsize=8.5, bold=False)

    ax.text(0.12, 0.018, "Source: THIEME Atlas of Anatomy – General Anatomy, Sections 1.6 & 6.1",
            transform=ax.transAxes, fontsize=7, color='#888888')
    plt.tight_layout()
    pdf.savefig(fig, bbox_inches='tight')
    plt.close(fig)


# ═══════════════════════════════════════════════════════════════════════════
# COVER PAGE
# ═══════════════════════════════════════════════════════════════════════════
def page_cover(pdf):
    fig, ax = plt.subplots(figsize=(8.5, 11))
    clean_ax(ax, (0, 1), (0, 1))

    # Background gradient blocks
    for i, col in enumerate(["#E3F2FD","#E8F5E9","#FFF3E0","#F3E5F5","#FFEBEE"]):
        ax.add_patch(FancyBboxPatch((0.05, 0.08+i*0.13), 0.9, 0.12,
                     boxstyle="round,pad=0.01", facecolor=col,
                     edgecolor='none', zorder=1))

    ax.add_patch(FancyBboxPatch((0.04, 0.06), 0.92, 0.68,
                 boxstyle="round,pad=0.01", facecolor='white',
                 edgecolor=C_TITLE, linewidth=2, zorder=2))

    ax.text(0.5, 0.92, "THE CIRCULATORY SYSTEM", ha='center', fontsize=22,
            fontweight='bold', color=C_TITLE, transform=ax.transAxes)
    ax.text(0.5, 0.86, "Visual Flowchart Reference", ha='center', fontsize=14,
            color='#37474F', transform=ax.transAxes)
    ax.text(0.5, 0.82, "Based on: THIEME Atlas of Anatomy – General Anatomy\n"
                       "Sections 1.6, 6.1, 6.2, 6.3",
            ha='center', fontsize=10, color='#555555', transform=ax.transAxes,
            multialignment='center')

    charts = [
        ("1", "The Two Main Circulatory Circuits",          "Pulmonary · Systemic · Portal",                   C_BOX_RED),
        ("2", "Functional Pressure Systems",                "High-pressure · Capillary Exchange · Low-pressure", C_BOX_ORG),
        ("3", "Structure of Blood Vessel Walls",            "Tunica Intima · Media · Adventitia",               C_BOX_GRN),
        ("4", "Terminal Vascular Bed & Microcirculation",   "Precapillary sphincters · Starling forces · Capillary types", C_BOX_BLU),
        ("5", "Embryonic Circulation & Lymphatic System",   "3-circuit embryo · Lymphatic pathway",             C_BOX_PUR),
    ]
    for i, (num, title, sub, col) in enumerate(charts):
        y = 0.70 - i*0.13
        ax.add_patch(FancyBboxPatch((0.06, y-0.045), 0.88, 0.09,
                     boxstyle="round,pad=0.01,rounding_size=0.02",
                     facecolor=col, edgecolor=C_ARR, linewidth=0.8,
                     transform=ax.transAxes, zorder=3))
        ax.text(0.11, y+0.005, f"#{num}", ha='center', va='center', fontsize=13,
                fontweight='bold', color=C_TITLE, transform=ax.transAxes)
        ax.text(0.62, y+0.018, title, ha='center', va='center', fontsize=10,
                fontweight='bold', color=C_TXT, transform=ax.transAxes)
        ax.text(0.62, y-0.015, sub, ha='center', va='center', fontsize=8,
                color='#555555', transform=ax.transAxes)

    ax.text(0.5, 0.035, "Generated June 2026  |  For educational use only",
            ha='center', fontsize=8, color='#999999', transform=ax.transAxes)

    pdf.savefig(fig, bbox_inches='tight')
    plt.close(fig)


# ═══════════════════════════════════════════════════════════════════════════
# MAIN
# ═══════════════════════════════════════════════════════════════════════════
with PdfPages(OUTPUT) as pdf:
    page_cover(pdf)
    page_pulmonary_systemic(pdf)
    page_pressure_systems(pdf)
    page_vessel_structure(pdf)
    page_microcirculation(pdf)
    page_embryo_lymph(pdf)

    d = pdf.infodict()
    d['Title']   = 'Circulatory System – Flowchart Reference'
    d['Author']  = 'Orris AI'
    d['Subject'] = 'Human Circulatory System'
    d['Keywords']= 'circulatory system, heart, blood vessels, anatomy, flowchart'

print("PDF saved to:", OUTPUT)
Running Command

python3 /home/daytona/workspace/circulatory-flowcharts/make_flowcharts.py 2>&1

You've run out of free credits. Sign up for a free account to continue using Orris.
This is a shared conversation. Sign in to Orris to start your own chat.