increased hydrostatic pressure which causes right and left heart failure leading to edema. Diagram for it in simple explaiantion
A clean, simple medical diagram showing how increased hydrostatic pressure causes heart failure edema. Show two pathways side by side: LEFT SIDE - Right Heart Failure pathway: - Box: "Right Heart Failure" with a weak right heart icon - Arrow down: "↑ Venous Hydrostatic Pressure (systemic)" - Arrow down: "Fluid pushed OUT of capillaries into tissues" - Result boxes: "Peripheral Edema (legs/ankles)", "Ascites (abdomen)", "Hepatomegaly" RIGHT SIDE - Left Heart Failure pathway: - Box: "Left Heart Failure" with a weak left heart icon - Arrow down: "↑ Pulmonary Hydrostatic Pressure" - Arrow down: "Fluid pushed into lung alveoli" - Result boxes: "Pulmonary Edema", "Dyspnea / Breathlessness" CENTER TOP: "Increased Hydrostatic Pressure" as the main title with a large arrow branching to both sides BOTTOM CENTER: A simple Starling Forces equation box showing: "When Hydrostatic Pressure > Oncotic Pressure → Fluid leaks into interstitium → EDEMA" Use a clean white background, blue and red color coding (blue for venous/right side, red for arterial/left side), simple bold arrows, and clear readable fonts. Keep it educational and simple like a medical textbook diagram.
404 Not Found. {'message': '{\n "error": {\n "code": 404,\n "message": "Publisher model `projects/engaged-beaker-474810-u2/locations/global/publishers/google/models/gemini-3-pro-image-preview` was not found or your project does not have access to it. Ensure you are using a valid model name and that the model is available in the specified region. For more information, see: https://docs.cloud.google.com/gemini-enterprise-agent-platform/resources/locations.",\n "status": "NOT_FOUND"\n }\n}\n', 'status': 'Not Found'}
We encountered an error while processing your request. Please try again or reach out to us for help.
peripheral edema
| Force | Direction of Fluid Movement |
|---|---|
| ↑ Capillary hydrostatic pressure | OUT of capillary → edema |
| ↓ Capillary oncotic pressure | OUT of capillary → edema |
| ↑ Interstitial oncotic pressure | OUT of capillary → edema |
| ↑ Capillary permeability | OUT of capillary → edema |


An increase in capillary hydrostatic pressure opposes capillary oncotic pressure and interstitial hydrostatic pressure, leading to net efflux of fluid from capillaries into the interstitial space.
| Cause | Key Features |
|---|---|
| Right heart failure | Bilateral, pitting, dependent edema; also ascites, elevated JVP |
| Left heart failure | Can also have pulmonary edema/pleural effusions alongside leg edema |
| Renal failure | Similar pattern to right heart failure; treat with dialysis |
| Cirrhosis | Mainly ascites; leg edema prominent in advanced disease |
| Deep vein thrombosis (DVT) | Unilateral, acute onset, painful, erythematous |
| Chronic venous insufficiency | Bilateral, chronic, associated with skin changes |
| Pregnancy | Bilateral dependent edema |
| Superior vena cava syndrome | Upper extremity + facial edema |
| Constrictive pericarditis | Bilateral edema + elevated JVP + Kussmaul sign |
| Medications | e.g., calcium channel blockers, NSAIDs |
Give diagrams based on pathophysiology part of the slides.
python3 -c " from docx import Document doc = Document('/tmp/workspace/attachments/c76d0906-e40b-4959-978c-24d4c8716405/Capillary_Exchange_and_Edema_Notes.docx') for p in doc.paragraphs: style = p.style.name if p.style else 'None' if p.text.strip(): print(f'[{style}] {p.text}') "
Clean medical education flowchart diagram titled "MECHANISM 1: Increased Capillary Hydrostatic Pressure → Edema" on white background. Show two parallel vertical pathways side by side: LEFT PATHWAY (label: "Right-Sided Heart Failure"): Box 1: "Right Ventricle Fails to Pump" Arrow down Box 2: "Blood backs up → Right Atrium → Systemic Veins" Arrow down Box 3: "↑ Systemic Venous Pressure" Arrow down Box 4: "↑ Capillary Hydrostatic Pressure (systemic)" Arrow down Box 5 (red outline): "Net Filtration > Lymphatic Capacity" Arrow down Result box (orange): "Bilateral Pitting Ankle Edema, Ascites, Anasarca" RIGHT PATHWAY (label: "Left-Sided Heart Failure"): Box 1: "Left Ventricle Fails to Pump" Arrow down Box 2: "Blood backs up → Left Atrium → Pulmonary Veins" Arrow down Box 3: "↑ Pulmonary Venous Pressure" Arrow down Box 4: "↑ Pulmonary Capillary Hydrostatic Pressure" Arrow down Box 5 (red outline): "Net Filtration > Lymphatic Capacity" Arrow down Result box (blue): "Pulmonary Edema, Dyspnea, Orthopnea, Crepitations" BELOW both pathways, add a small box: "Other causes: DVT (unilateral edema), Renal failure (Na/water retention), Amlodipine (arteriolar dilation), Prolonged standing (postural edema)" At the BOTTOM: Key principle box: "Hydrostatic Pressure ↑, Oncotic Pressure unchanged → Net outward force → Fluid leaks into interstitium → EDEMA (pitting, dependent, bilateral)" Use blue and red color coding, bold arrows, clean sans-serif font, medical textbook style.
404 Not Found. {'message': '{\n "error": {\n "code": 404,\n "message": "Publisher model `projects/engaged-beaker-474810-u2/locations/global/publishers/google/models/gemini-3-pro-image-preview` was not found or your project does not have access to it. Ensure you are using a valid model name and that the model is available in the specified region. For more information, see: https://docs.cloud.google.com/gemini-enterprise-agent-platform/resources/locations.",\n "status": "NOT_FOUND"\n }\n}\n', 'status': 'Not Found'}
We encountered an error while processing your request. Please try again or reach out to us for help.
answer please
mkdir -p /tmp/workspace/edema-diagrams && python3 << 'EOF' import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt import matplotlib.patches as mpatches from matplotlib.patches import FancyBboxPatch, FancyArrowPatch import matplotlib.patheffects as pe # ───────────────────────────────────────────────────────────────────────────── # HELPER: draw a rounded box with text # ───────────────────────────────────────────────────────────────────────────── def box(ax, x, y, w, h, text, fc='#EAF4FB', ec='#2980B9', fontsize=9, bold=False, wrap=True, text_color='#1a1a2e'): rect = FancyBboxPatch((x - w/2, y - h/2), w, h, boxstyle="round,pad=0.03", fc=fc, ec=ec, lw=1.5, zorder=3) ax.add_patch(rect) weight = 'bold' if bold else 'normal' ax.text(x, y, text, ha='center', va='center', fontsize=fontsize, fontweight=weight, color=text_color, zorder=4, wrap=True, multialignment='center', bbox=dict(boxstyle='square,pad=0', fc='none', ec='none')) def arrow(ax, x, y_start, y_end, color='#2C3E50'): ax.annotate('', xy=(x, y_end + 0.03), xytext=(x, y_start - 0.03), arrowprops=dict(arrowstyle='->', color=color, lw=2.0), zorder=5) def title_box(ax, text, color='#2C3E50'): ax.text(0.5, 0.97, text, transform=ax.transAxes, ha='center', va='top', fontsize=13, fontweight='bold', color='white', bbox=dict(boxstyle='round,pad=0.4', fc=color, ec='none')) # ═════════════════════════════════════════════════════════════════════════════ # DIAGRAM 1 — Increased Capillary Hydrostatic Pressure # ═════════════════════════════════════════════════════════════════════════════ fig, ax = plt.subplots(figsize=(13, 10)) ax.set_xlim(0, 13); ax.set_ylim(0, 10) ax.axis('off') fig.patch.set_facecolor('white') title_box(ax, 'MECHANISM 1 — Increased Capillary Hydrostatic Pressure → Edema', '#1565C0') # ── LEFT column: Right Heart Failure ────────────────────────────────────── steps_L = [ (3.2, 8.5, 'Right Ventricle\nFails to Pump Forward', '#D6EAF8', '#1565C0'), (3.2, 7.2, 'Blood backs up into\nRight Atrium → Systemic Veins', '#D6EAF8', '#1565C0'), (3.2, 5.9, '↑ Systemic Venous Pressure', '#AED6F1', '#1565C0'), (3.2, 4.6, '↑ Capillary Hydrostatic Pressure\n(Systemic)', '#5DADE2', '#1565C0'), (3.2, 3.3, 'Net Filtration >\nLymphatic Drainage Capacity', '#E8DAEF', '#7D3C98'), (3.2, 1.9, '🦵 Bilateral Pitting Ankle Edema\nAscites · Anasarca', '#FDEDEC', '#C0392B'), ] ax.text(3.2, 9.4, 'RIGHT-SIDED HEART FAILURE', ha='center', fontsize=10, fontweight='bold', color='#1565C0') for (x, y, txt, fc, ec) in steps_L: box(ax, x, y, 5.2, 0.85, txt, fc=fc, ec=ec, fontsize=8.5) for i in range(len(steps_L)-1): arrow(ax, 3.2, steps_L[i][1] - 0.43, steps_L[i+1][1] + 0.43, '#1565C0') # ── RIGHT column: Left Heart Failure ────────────────────────────────────── steps_R = [ (9.8, 8.5, 'Left Ventricle\nFails to Pump Forward', '#FDEDEC', '#C0392B'), (9.8, 7.2, 'Blood backs up into\nLeft Atrium → Pulmonary Veins', '#FDEDEC', '#C0392B'), (9.8, 5.9, '↑ Pulmonary Venous Pressure', '#F1948A', '#C0392B'), (9.8, 4.6, '↑ Pulmonary Capillary\nHydrostatic Pressure', '#E74C3C', '#922B21'), (9.8, 3.3, 'Net Filtration >\nLymphatic Drainage Capacity', '#E8DAEF', '#7D3C98'), (9.8, 1.9, '🫁 Pulmonary Edema\nDyspnea · Orthopnea · Crepitations', '#FDEDEC', '#C0392B'), ] ax.text(9.8, 9.4, 'LEFT-SIDED HEART FAILURE', ha='center', fontsize=10, fontweight='bold', color='#C0392B') for (x, y, txt, fc, ec) in steps_R: box(ax, x, y, 5.2, 0.85, txt, fc=fc, ec=ec, fontsize=8.5) for i in range(len(steps_R)-1): arrow(ax, 9.8, steps_R[i][1] - 0.43, steps_R[i+1][1] + 0.43, '#C0392B') # ── Other causes note ────────────────────────────────────────────────────── ax.text(6.5, 0.85, 'Other causes: DVT (unilateral edema) · Renal failure (Na/H₂O retention) · ' 'Amlodipine (arteriolar dilation) · Prolonged standing (postural edema)', ha='center', va='center', fontsize=8, color='#555', style='italic', bbox=dict(boxstyle='round,pad=0.3', fc='#F9F9F9', ec='#CCCCCC')) # ── Key principle ────────────────────────────────────────────────────────── ax.text(6.5, 0.2, 'KEY: Hydrostatic P ↑, Oncotic P unchanged → Net outward force → Fluid leaks into interstitium → PITTING, DEPENDENT EDEMA', ha='center', fontsize=8, fontweight='bold', color='white', bbox=dict(boxstyle='round,pad=0.3', fc='#2C3E50', ec='none')) plt.tight_layout() plt.savefig('/tmp/workspace/edema-diagrams/diagram1_hydrostatic.png', dpi=150, bbox_inches='tight') plt.close() print("Diagram 1 saved.") EOF
python3 << 'EOF' import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt import matplotlib.patches as mpatches from matplotlib.patches import FancyBboxPatch def box(ax, x, y, w, h, text, fc='#EAF4FB', ec='#2980B9', fontsize=9, bold=False, text_color='#1a1a2e'): rect = FancyBboxPatch((x - w/2, y - h/2), w, h, boxstyle="round,pad=0.03", fc=fc, ec=ec, lw=1.5, zorder=3) ax.add_patch(rect) weight = 'bold' if bold else 'normal' ax.text(x, y, text, ha='center', va='center', fontsize=fontsize, fontweight=weight, color=text_color, zorder=4, multialignment='center') def arrow(ax, x, y_start, y_end, color='#2C3E50'): ax.annotate('', xy=(x, y_end + 0.03), xytext=(x, y_start - 0.03), arrowprops=dict(arrowstyle='->', color=color, lw=2.0), zorder=5) def title_box(ax, text, color='#2C3E50'): ax.text(0.5, 0.97, text, transform=ax.transAxes, ha='center', va='top', fontsize=12, fontweight='bold', color='white', bbox=dict(boxstyle='round,pad=0.4', fc=color, ec='none')) # ═══════════════════════════════════════════════════════════════ # DIAGRAM 2 — Decreased Plasma Oncotic Pressure # ═══════════════════════════════════════════════════════════════ fig, ax = plt.subplots(figsize=(12, 10)) ax.set_xlim(0, 12); ax.set_ylim(0, 10) ax.axis('off') fig.patch.set_facecolor('white') title_box(ax, 'MECHANISM 2 — Decreased Plasma Oncotic Pressure (Hypoalbuminaemia) -> Edema', '#1B5E20') # Three sources of albumin loss / reduced production ax.text(6, 9.2, 'ALBUMIN is the main protein maintaining plasma oncotic pressure', ha='center', fontsize=9.5, fontweight='bold', color='#1B5E20', bbox=dict(boxstyle='round,pad=0.3', fc='#E8F5E9', ec='#1B5E20')) # Source boxes sources = [ (2.2, 7.8, 'LIVER (Production)', 'Cirrhosis\nAlcoholic liver disease\nChronic hepatitis', '#FFF9C4', '#F57F17'), (6.0, 7.8, 'KIDNEY (Loss)', 'Nephrotic syndrome\n(>3.5 g proteinuria/day)', '#E3F2FD', '#1565C0'), (9.8, 7.8, 'GUT (Absorption)', 'Malnutrition\nMalabsorption\nKwashiorkor', '#FCE4EC', '#880E4F'), ] for (x, y, title, detail, fc, ec) in sources: box(ax, x, y+0.3, 3.4, 0.55, title, fc=ec, ec=ec, fontsize=9, bold=True, text_color='white') box(ax, x, y-0.45, 3.4, 0.85, detail, fc=fc, ec=ec, fontsize=8.5) # Converge arrows to Hypoalbuminaemia for xi in [2.2, 6.0, 9.8]: ax.annotate('', xy=(6.0, 6.3 + 0.03), xytext=(xi, 7.0 - 0.03), arrowprops=dict(arrowstyle='->', color='#555', lw=1.8), zorder=5) # Central pathway steps = [ (6.0, 6.2, 'HYPOALBUMINAEMIA\n(Low plasma albumin)', '#FFCC80', '#E65100'), (6.0, 5.1, 'Plasma Oncotic (Colloid Osmotic) Pressure FALLS', '#FFE082', '#F57F17'), (6.0, 4.0, 'Oncotic P < Hydrostatic P\n(Inward force weakened)', '#EF9A9A', '#C62828'), (6.0, 2.9, 'Net Filtration out of capillary\nexceeds lymphatic return', '#CE93D8', '#6A1B9A'), (6.0, 1.8, 'GENERALISED PITTING OEDEMA\nPeriorbital (worse on waking) + Ascites + Pleural effusion', '#FFCDD2', '#B71C1C'), ] for (x, y, txt, fc, ec) in steps: bold = (y == 6.2 or y == 1.8) box(ax, x, y, 7.5, 0.72, txt, fc=fc, ec=ec, fontsize=9, bold=bold) for i in range(len(steps)-1): arrow(ax, 6.0, steps[i][1]-0.36, steps[i+1][1]+0.36, '#555') # Key note ax.text(6.0, 0.85, 'Cirrhosis: Ascites > peripheral oedema (portal HTN adds local hydrostatic component)', ha='center', fontsize=8, style='italic', color='#555', bbox=dict(boxstyle='round,pad=0.25', fc='#F9FBE7', ec='#CDDC39')) ax.text(6.0, 0.2, 'KEY: Oncotic P falls -> inward reabsorptive force reduced -> fluid accumulates generalized -> NON-dependent spread', ha='center', fontsize=8, fontweight='bold', color='white', bbox=dict(boxstyle='round,pad=0.25', fc='#1B5E20', ec='none')) plt.tight_layout() plt.savefig('/tmp/workspace/edema-diagrams/diagram2_oncotic.png', dpi=150, bbox_inches='tight') plt.close() print("Diagram 2 saved.") EOF
python3 << 'EOF' import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt from matplotlib.patches import FancyBboxPatch def box(ax, x, y, w, h, text, fc='#EAF4FB', ec='#2980B9', fontsize=9, bold=False, text_color='#1a1a2e'): rect = FancyBboxPatch((x - w/2, y - h/2), w, h, boxstyle="round,pad=0.03", fc=fc, ec=ec, lw=1.5, zorder=3) ax.add_patch(rect) ax.text(x, y, text, ha='center', va='center', fontsize=fontsize, fontweight='bold' if bold else 'normal', color=text_color, zorder=4, multialignment='center') def arrow(ax, x, y_start, y_end, color='#2C3E50'): ax.annotate('', xy=(x, y_end + 0.03), xytext=(x, y_start - 0.03), arrowprops=dict(arrowstyle='->', color=color, lw=2.0), zorder=5) def title_box(ax, text, color='#2C3E50'): ax.text(0.5, 0.97, text, transform=ax.transAxes, ha='center', va='top', fontsize=12, fontweight='bold', color='white', bbox=dict(boxstyle='round,pad=0.4', fc=color, ec='none')) # ═══════════════════════════════════════════════════════════════ # DIAGRAM 3 — Lymphatic Obstruction # ═══════════════════════════════════════════════════════════════ fig, ax = plt.subplots(figsize=(12, 10)) ax.set_xlim(0, 12); ax.set_ylim(0, 10) ax.axis('off') fig.patch.set_facecolor('white') title_box(ax, 'MECHANISM 3 — Lymphatic Obstruction (Lymphoedema) -> Edema', '#4A148C') # Normal function explanation box(ax, 6.0, 9.0, 10.5, 0.7, 'Lymphatics normally drain ~2-4 L/day of excess filtered fluid + leaked protein back to circulation', fc='#EDE7F6', ec='#4A148C', fontsize=9) # Three cause columns causes = [ (2.2, 'Post-Mastectomy\nLymphoedema', 'Axillary lymph node\ndissection for breast\ncancer surgery\n-> drainage pathway\ndestroyed', '#E1BEE7', '#7B1FA2'), (6.0, 'Filariasis\n(Elephantiasis)', 'Wuchereria bancrofti\n(parasitic nematode)\nlodges in lymphatics\n-> obstruction\n-> gross limb swelling', '#D1C4E9', '#512DA8'), (9.8, 'Milroy Disease\n(Congenital)', 'VEGFR3/FLT4\ngene mutation\n-> lymphatics fail\nto develop normally\n-> edema at birth', '#C5CAE9', '#283593'), ] for (x, title, detail, fc, ec) in causes: box(ax, x, 7.85, 3.3, 0.55, title, fc=ec, ec=ec, fontsize=9, bold=True, text_color='white') box(ax, x, 6.85, 3.3, 1.35, detail, fc=fc, ec=ec, fontsize=8.5) ax.annotate('', xy=(6.0, 5.8 + 0.03), xytext=(x, 6.17 - 0.03), arrowprops=dict(arrowstyle='->', color='#555', lw=1.8), zorder=5) # Central pathway steps = [ (6.0, 5.7, 'Lymphatic Channels: Destroyed / Obstructed / Absent', '#CE93D8', '#6A1B9A'), (6.0, 4.6, 'Filtered fluid AND protein\ncannot be cleared from interstitium', '#F3E5F5', '#7B1FA2'), (6.0, 3.5, 'Protein accumulates in interstitial space\n(raises interstitial oncotic pressure)', '#EF9A9A', '#B71C1C'), (6.0, 2.4, 'Protein stimulates FIBROSIS over time\n(chronic, progressive)', '#FFCC80', '#E65100'), (6.0, 1.3, 'NON-PITTING, "Woody/Brawny" Edema\n(does not pit — protein + fibrosis harden tissue)', '#FFCDD2', '#B71C1C'), ] for (x, y, txt, fc, ec) in steps: box(ax, x, y, 8.5, 0.72, txt, fc=fc, ec=ec, fontsize=9, bold=(y==5.7 or y==1.3)) for i in range(len(steps)-1): arrow(ax, 6.0, steps[i][1]-0.36, steps[i+1][1]+0.36, '#6A1B9A') ax.text(6.0, 0.35, 'KEY: Starling forces may be NORMAL -- problem is drainage failure -> protein-rich exudate -> NON-PITTING edema', ha='center', fontsize=8.5, fontweight='bold', color='white', bbox=dict(boxstyle='round,pad=0.28', fc='#4A148C', ec='none')) plt.tight_layout() plt.savefig('/tmp/workspace/edema-diagrams/diagram3_lymphatic.png', dpi=150, bbox_inches='tight') plt.close() print("Diagram 3 saved.") EOF
python3 << 'EOF' import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt from matplotlib.patches import FancyBboxPatch def box(ax, x, y, w, h, text, fc='#EAF4FB', ec='#2980B9', fontsize=9, bold=False, text_color='#1a1a2e'): rect = FancyBboxPatch((x - w/2, y - h/2), w, h, boxstyle="round,pad=0.03", fc=fc, ec=ec, lw=1.5, zorder=3) ax.add_patch(rect) ax.text(x, y, text, ha='center', va='center', fontsize=fontsize, fontweight='bold' if bold else 'normal', color=text_color, zorder=4, multialignment='center') def arrow(ax, x, y_start, y_end, color='#2C3E50'): ax.annotate('', xy=(x, y_end + 0.03), xytext=(x, y_start - 0.03), arrowprops=dict(arrowstyle='->', color=color, lw=2.0), zorder=5) def title_box(ax, text, color='#2C3E50'): ax.text(0.5, 0.97, text, transform=ax.transAxes, ha='center', va='top', fontsize=12, fontweight='bold', color='white', bbox=dict(boxstyle='round,pad=0.4', fc=color, ec='none')) # ═══════════════════════════════════════════════════════════════ # DIAGRAM 4 — Increased Capillary Permeability # ═══════════════════════════════════════════════════════════════ fig, ax = plt.subplots(figsize=(12, 10)) ax.set_xlim(0, 12); ax.set_ylim(0, 10) ax.axis('off') fig.patch.set_facecolor('white') title_box(ax, 'MECHANISM 4 — Increased Capillary Permeability -> Edema', '#BF360C') # Trigger explanation box(ax, 6.0, 9.0, 11.0, 0.7, 'Inflammatory mediators (histamine, bradykinin, cytokines, prostaglandins) open gaps in endothelial lining', fc='#FBE9E7', ec='#BF360C', fontsize=9) # Trigger causes columns triggers = [ (2.0, 'Localised Triggers', 'Burns\nInsect bites\nCellulitis\nLocalised allergy\nTrauma', '#FFCCBC', '#BF360C'), (6.0, 'Systemic Triggers', 'Anaphylaxis\nSepsis\nSevere inflammation\nGlyocalyx injury\n(critical illness)', '#FFAB91', '#D84315'), (10.0, 'Glycocalyx Damage\n(Modern concept)', 'Sepsis, hyperglycaemia,\nischaemia-reperfusion,\nexcessive IV crystalloids\n-> collapse of oncotic\nbarrier', '#FF8A65', '#BF360C'), ] for (x, title, detail, fc, ec) in triggers: box(ax, x, 7.85, 3.6, 0.55, title, fc=ec, ec=ec, fontsize=9, bold=True, text_color='white') box(ax, x, 6.85, 3.6, 1.35, detail, fc=fc, ec=ec, fontsize=8.5) ax.annotate('', xy=(6.0, 5.8 + 0.03), xytext=(x, 6.17 - 0.03), arrowprops=dict(arrowstyle='->', color='#BF360C', lw=1.8), zorder=5) # Central pathway steps = [ (6.0, 5.7, 'ENDOTHELIAL GAPS OPEN\n(Intercellular clefts widen / tight junctions disrupted)', '#FFCCBC', '#BF360C'), (6.0, 4.55, 'Fluid AND PROTEIN leak out\n(Hydrostatic/Oncotic pressures may be NORMAL)', '#FFAB91', '#D84315'), (6.0, 3.4, 'Protein-rich fluid (exudate) accumulates\nin interstitial space', '#EF9A9A', '#C62828'), (6.0, 2.25, 'Interstitial oncotic pressure rises\n(protein outside capillary pulls more fluid out)', '#CE93D8', '#6A1B9A'), (6.0, 1.1, 'PITTING or NON-PITTING EDEMA\n(Localised or Generalised depending on trigger)', '#FFCDD2', '#B71C1C'), ] for (x, y, txt, fc, ec) in steps: box(ax, x, y, 9.0, 0.72, txt, fc=fc, ec=ec, fontsize=9, bold=(y==5.7 or y==1.1)) for i in range(len(steps)-1): arrow(ax, 6.0, steps[i][1]-0.36, steps[i+1][1]+0.36, '#BF360C') ax.text(6.0, 0.3, 'KEY: Starling forces NOT necessarily altered -- structural breach of capillary wall -> protein-rich EXUDATE (cf. transudate in mech 1&2)', ha='center', fontsize=8, fontweight='bold', color='white', bbox=dict(boxstyle='round,pad=0.28', fc='#BF360C', ec='none')) plt.tight_layout() plt.savefig('/tmp/workspace/edema-diagrams/diagram4_permeability.png', dpi=150, bbox_inches='tight') plt.close() print("Diagram 4 saved.") EOF
python3 << 'EOF' import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt from matplotlib.patches import FancyBboxPatch def box(ax, x, y, w, h, text, fc='white', ec='gray', fontsize=9, bold=False, text_color='#1a1a2e'): rect = FancyBboxPatch((x - w/2, y - h/2), w, h, boxstyle="round,pad=0.04", fc=fc, ec=ec, lw=2, zorder=3) ax.add_patch(rect) ax.text(x, y, text, ha='center', va='center', fontsize=fontsize, fontweight='bold' if bold else 'normal', color=text_color, zorder=4, multialignment='center') def arrow_down(ax, x, y_start, y_end, color='#333'): ax.annotate('', xy=(x, y_end + 0.02), xytext=(x, y_start - 0.02), arrowprops=dict(arrowstyle='->', color=color, lw=2.0), zorder=5) def arrow_to(ax, x1, y1, x2, y2, color='#333'): ax.annotate('', xy=(x2, y2), xytext=(x1, y1), arrowprops=dict(arrowstyle='->', color=color, lw=1.8), zorder=5) # ═══════════════════════════════════════════════════════════════ # MASTER OVERVIEW DIAGRAM # ═══════════════════════════════════════════════════════════════ fig, ax = plt.subplots(figsize=(16, 11)) ax.set_xlim(0, 16); ax.set_ylim(0, 11) ax.axis('off') fig.patch.set_facecolor('white') # Main title ax.text(8, 10.5, 'PATHOPHYSIOLOGY OF EDEMA — Master Overview (Section 6)', ha='center', va='center', fontsize=14, fontweight='bold', color='white', bbox=dict(boxstyle='round,pad=0.5', fc='#1A237E', ec='none')) # STARLING EQUATION box at top center box(ax, 8, 9.5, 10, 0.7, 'STARLING EQUATION: Jv = Kf [ (Pc - Pi) - o(pc - pi) ]\nEdema when net filtration EXCEEDS lymphatic drainage capacity', fc='#E8EAF6', ec='#1A237E', fontsize=9, bold=False) # 4 mechanism boxes at top mechs = [ (2.0, 8.0, 'MECH 1\nHydrostatic P UP', '#1565C0', '#BBDEFB'), (6.0, 8.0, 'MECH 2\nOncotic P DOWN', '#1B5E20', '#C8E6C9'), (10.0, 8.0, 'MECH 3\nLymphatic Obstruction', '#4A148C', '#E1BEE7'), (14.0, 8.0, 'MECH 4\nCapillary Permeability UP', '#BF360C', '#FFCCBC'), ] for (x, y, txt, ec, fc) in mechs: box(ax, x, y, 3.5, 0.9, txt, fc=fc, ec=ec, fontsize=9.5, bold=True) arrow_to(ax, 8, 9.15, x, y+0.45, '#888') # Sub-causes under each mechanism subcauses = [ # Mech 1 (2.0, 6.7, 'Right HF -> peripheral edema\nLeft HF -> pulmonary edema\nDVT -> unilateral edema\nRenal failure, Drugs (amlodipine)\nProlonged standing', '#1565C0', '#E3F2FD'), # Mech 2 (6.0, 6.7, 'Cirrhosis (liver: low synthesis)\nNephrotic syndrome (kidney: loss)\nMalnutrition/Malabsorption\n(gut: low absorption)', '#1B5E20', '#E8F5E9'), # Mech 3 (10.0, 6.7, 'Post-mastectomy lymphoedema\nFilariasis (Wuchereria bancrofti)\nMilroy disease (congenital)\n-> Protein-rich interstitium', '#4A148C', '#F3E5F5'), # Mech 4 (14.0, 6.7, 'Localised: Burns, insect bites,\ncellulitis, local allergy\nSystemic: Anaphylaxis, Sepsis\nGlycocalyx damage (ICU)', '#BF360C', '#FBE9E7'), ] for (x, y, txt, ec, fc) in subcauses: box(ax, x, y, 3.6, 1.7, txt, fc=fc, ec=ec, fontsize=8) arrow_down(ax, x, mechs[subcauses.index((x,y,txt,ec,fc))][1]-0.45, y+0.85, ec) # Edema type row edema_types = [ (2.0, 5.0, 'PITTING\nDependent\nBilateral (usually)', '#1565C0', '#BBDEFB'), (6.0, 5.0, 'PITTING\nGeneralised\n(periorbital onset)', '#1B5E20', '#C8E6C9'), (10.0, 5.0, 'NON-PITTING\nWoody/Brawny\nLocalized', '#4A148C', '#E1BEE7'), (14.0, 5.0, 'PITTING or NON-PITTING\nLocalized or Generalised\n(depends on trigger)', '#BF360C', '#FFCCBC'), ] for i, (x, y, txt, ec, fc) in enumerate(edema_types): box(ax, x, y, 3.5, 0.9, txt, fc=fc, ec=ec, fontsize=8.5) arrow_down(ax, x, subcauses[i][1]-0.85, y+0.45, ec) # Fluid type row fluid_types = [ (2.0, 3.8, 'TRANSUDATE\n(protein-poor)', '#1565C0', '#E3F2FD'), (6.0, 3.8, 'TRANSUDATE\n(protein-poor)', '#1B5E20', '#E8F5E9'), (10.0, 3.8, 'PROTEIN-RICH\n(uncleared filtrate)', '#4A148C', '#F3E5F5'), (14.0, 3.8, 'EXUDATE\n(protein-rich)', '#BF360C', '#FBE9E7'), ] for i, (x, y, txt, ec, fc) in enumerate(fluid_types): box(ax, x, y, 3.3, 0.75, txt, fc=fc, ec=ec, fontsize=8.5) arrow_down(ax, x, edema_types[i][1]-0.45, y+0.38, ec) # All converge to edema box for x in [2.0, 6.0, 10.0, 14.0]: arrow_to(ax, x, 3.4, 8.0, 2.65, '#555') box(ax, 8.0, 2.5, 14, 0.8, 'EDEMA = Excess fluid accumulation in the interstitial space', fc='#FFF9C4', ec='#F57F17', fontsize=11, bold=True) # Mnemonic box(ax, 8.0, 1.55, 10.5, 0.75, 'MNEMONIC — "HOP" | Hydrostatic P up | Oncotic P down | Permeability up\n' '"Liver makes it, Gut absorbs it, Kidney loses it" (albumin sources)', fc='#E0F7FA', ec='#006064', fontsize=8.5) # Safety factors note ax.text(8.0, 0.6, 'Edema safety factors (lymphatics can increase flow 10-50x, interstitial pressure rises, protein washes out)' ' must ALL be OVERWHELMED before clinical edema appears', ha='center', fontsize=7.5, color='#555', style='italic', bbox=dict(boxstyle='round,pad=0.2', fc='#FAFAFA', ec='#CCC')) plt.tight_layout() plt.savefig('/tmp/workspace/edema-diagrams/diagram5_master_overview.png', dpi=150, bbox_inches='tight') plt.close() print("Master diagram saved.") EOF
ls -lh /tmp/workspace/edema-diagrams/
diagram1 hydrostatic
Image · PNG
diagram2 oncotic
Image · PNG
diagram3 lymphatic
Image · PNG
diagram4 permeability
Image · PNG
diagram5 master overview
Image · PNG
| Diagram | Mechanism | Edema Type | Fluid Type |
|---|---|---|---|
| 1 | Hydrostatic P up (Right HF / Left HF) | Pitting, dependent | Transudate |
| 2 | Oncotic P down (Hypoalbuminaemia) | Pitting, generalised | Transudate |
| 3 | Lymphatic obstruction (mastectomy, filariasis, Milroy) | Non-pitting, woody | Protein-rich |
| 4 | Capillary permeability up (sepsis, anaphylaxis, burns) | Pitting or non-pitting | Exudate |
| 5 | Master overview - all 4 + HOP mnemonic | All types | Summary |
Make a summary table comparing pitting vs non-pitting edema causes
python3 << 'EOF' import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt import matplotlib.patches as mpatches from matplotlib.patches import FancyBboxPatch import numpy as np fig, ax = plt.subplots(figsize=(18, 13)) ax.set_xlim(0, 18) ax.set_ylim(0, 13) ax.axis('off') fig.patch.set_facecolor('white') # ── Title ────────────────────────────────────────────────────────────────── ax.text(9, 12.5, 'PITTING vs NON-PITTING EDEMA — Comparison Summary Table', ha='center', va='center', fontsize=15, fontweight='bold', color='white', bbox=dict(boxstyle='round,pad=0.5', fc='#1A237E', ec='none')) # ── Column headers ───────────────────────────────────────────────────────── headers = ['Feature', 'PITTING EDEMA', 'NON-PITTING EDEMA'] col_x = [1.8, 7.2, 13.5] col_w = [3.0, 8.5, 8.5] header_colors = ['#37474F', '#1565C0', '#4A148C'] for i, (hdr, cx, cw, hc) in enumerate(zip(headers, col_x, col_w, header_colors)): rect = FancyBboxPatch((cx - cw/2, 11.4), cw, 0.75, boxstyle="round,pad=0.05", fc=hc, ec='white', lw=2, zorder=3) ax.add_patch(rect) ax.text(cx, 11.77, hdr, ha='center', va='center', fontsize=11, fontweight='bold', color='white', zorder=4) # ── Table rows ───────────────────────────────────────────────────────────── rows = [ # (Feature, Pitting, Non-Pitting) ('Definition', 'Pressing finger on tissue leaves\na temporary INDENTATION (pit)\nthat slowly refills', 'Pressing finger leaves NO indentation;\ntissue bounces back immediately\nor feels firm/woody'), ('Mechanism', 'Fluid is protein-POOR (transudate)\nMoves freely under pressure\n→ can be displaced momentarily', 'Fluid is protein-RICH or fibrotic\nProtein + fibrin + collagen harden tissue\n→ resists compression'), ('Fluid Type', 'TRANSUDATE\nLow protein (<3 g/dL)\nLow LDH, low specific gravity', 'EXUDATE or protein-rich lymph fluid\nHigh protein (>3 g/dL)\nHigh LDH, high specific gravity'), ('Causes\n(Hydrostatic)', '• Right heart failure (bilateral ankle/leg)\n• Left heart failure (pulmonary oedema)\n• Renal failure (bilateral)\n• Cirrhosis (ascites + leg)\n• Pregnancy\n• Prolonged standing (postural)', '— Not applicable —\n(hydrostatic cause\ngives pitting edema)'), ('Causes\n(Oncotic)', '• Nephrotic syndrome (periorbital + generalised)\n• Cirrhosis (hypoalbuminaemia)\n• Malnutrition / Kwashiorkor\n• Malabsorption syndromes', '— Not applicable —\n(oncotic cause\ngives pitting edema)'), ('Causes\n(Lymphatic)', '— Not applicable —\n(lymphatic obstruction\ngives NON-pitting)', '• Post-mastectomy lymphoedema\n• Filariasis / Elephantiasis\n (Wuchereria bancrofti)\n• Milroy disease (congenital)\n• Post-radiation lymphoedema'), ('Causes\n(Other)', '• DVT (unilateral, painful)\n• Venous insufficiency (bilateral)\n• Amlodipine / CCBs (arteriolar dilation)\n• Superior vena cava syndrome\n• Constrictive pericarditis', '• Hypothyroidism / Myxoedema\n (mucopolysaccharide deposition)\n• Lipoedema (fat deposition, bilateral legs)\n• Localised inflammation / cellulitis\n (early — protein exudate)'), ('Distribution', 'Dependent (gravity-dependent)\nAnkles, legs, sacrum if bedridden\nGeneralised in severe cases (anasarca)', 'Localised (lymph obstruction site)\nor Generalised (myxoedema)\nNOT typically gravity-dependent'), ('Onset', 'Gradual (HF, renal)\nAcute (DVT, anaphylaxis)', 'Usually chronic and progressive\n(lymphoedema, myxoedema)'), ('Key Exam\nFeatures', '• Pit depth graded 1+ to 4+\n• Associated: elevated JVP, S3 gallop,\n crackles, ascites, proteinuria\n• Responds to diuretics', '• No pitting on pressure\n• "Woody" or "brawny" texture\n• Skin thickening, hyperpigmentation\n• Does NOT respond to diuretics\n• Stemmer sign +ve in lymphoedema'), ('Investigations', 'BNP/NT-proBNP, Echo (HF)\nUrinalysis + albumin (nephrotic)\nLFTs + albumin (cirrhosis)\nDoppler USS (DVT)', 'Lymphoscintigraphy (lymphoedema)\nTSH / T4 (myxoedema)\nBiopsy if malignancy suspected'), ] row_heights = [0.62, 0.62, 0.62, 1.05, 0.9, 0.9, 1.0, 0.72, 0.62, 1.0, 0.82] row_colors_pit = ['#E3F2FD', '#BBDEFB'] * 10 row_colors_nonpit = ['#EDE7F6', '#D1C4E9'] * 10 row_colors_feat = ['#ECEFF1', '#CFD8DC'] * 10 y_cursor = 11.15 for idx, (feat, pit, nonpit) in enumerate(rows): h = row_heights[idx] y_mid = y_cursor - h / 2 # Feature cell rect_f = FancyBboxPatch((0.3, y_cursor - h), 3.0, h, boxstyle="square,pad=0", fc=row_colors_feat[idx], ec='#90A4AE', lw=0.8, zorder=2) ax.add_patch(rect_f) ax.text(1.8, y_mid, feat, ha='center', va='center', fontsize=8.5, fontweight='bold', color='#263238', zorder=3, multialignment='center') # Pitting cell rect_p = FancyBboxPatch((3.45, y_cursor - h), 7.8, h, boxstyle="square,pad=0", fc=row_colors_pit[idx], ec='#90A4AE', lw=0.8, zorder=2) ax.add_patch(rect_p) ax.text(7.35, y_mid, pit, ha='center', va='center', fontsize=8, color='#0D47A1', zorder=3, multialignment='center') # Non-pitting cell rect_n = FancyBboxPatch((11.4, y_cursor - h), 6.3, h, boxstyle="square,pad=0", fc=row_colors_nonpit[idx], ec='#90A4AE', lw=0.8, zorder=2) ax.add_patch(rect_n) ax.text(14.55, y_mid, nonpit, ha='center', va='center', fontsize=8, color='#311B92', zorder=3, multialignment='center') y_cursor -= h # ── Border around table ──────────────────────────────────────────────────── outer = FancyBboxPatch((0.3, y_cursor), 17.4, 11.15 - y_cursor, boxstyle="round,pad=0.05", fc='none', ec='#1A237E', lw=2, zorder=5) ax.add_patch(outer) # ── Mnemonic footer ──────────────────────────────────────────────────────── ax.text(9, y_cursor - 0.22, 'MNEMONIC | Pitting = "HOP": Hydrostatic P up, Oncotic P down, Permeability up | ' 'Non-Pitting = "LMF": Lymphatic obstruction, Myxoedema, Fibrosis/Lipoedema', ha='center', va='center', fontsize=9, fontweight='bold', color='white', bbox=dict(boxstyle='round,pad=0.35', fc='#263238', ec='none')) plt.tight_layout(pad=0.2) plt.savefig('/tmp/workspace/edema-diagrams/pitting_vs_nonpitting_table.png', dpi=160, bbox_inches='tight') plt.close() print("Table saved.") EOF
pitting vs nonpitting table
Image · PNG
explain the pathophysiology of all in simple terms with relatable examples for understanding
Body tissues → veins → Right heart → Lungs → Left heart → Body
| Mechanism | Fluid Type | Edema Type | Simple Image | |
|---|---|---|---|---|
| Mech 1 | Pressure too high | Watery (transudate) | Pitting, dependent | Overfilled hose leaking |
| Mech 2 | Sucking force too weak | Watery (transudate) | Pitting, generalised | Soup with no thickener |
| Mech 3 | Drain is blocked | Protein-rich | Non-pitting, woody | Storm drain demolished |
| Mech 4 | Net is torn | Protein-rich (exudate) | Pitting or non-pitting | Torn fishing net |
diagram for right heart failure due to edema
python3 << 'EOF' import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt from matplotlib.patches import FancyBboxPatch, FancyArrowPatch import matplotlib.patheffects as pe fig, ax = plt.subplots(figsize=(14, 17)) ax.set_xlim(0, 14) ax.set_ylim(0, 17) ax.axis('off') fig.patch.set_facecolor('#FAFAFA') # ── Helper functions ─────────────────────────────────────────────────────── def rbox(ax, x, y, w, h, text, fc='white', ec='#2980B9', fontsize=9, bold=False, text_color='#1a1a2e', radius=0.15): rect = FancyBboxPatch((x - w/2, y - h/2), w, h, boxstyle=f"round,pad={radius}", fc=fc, ec=ec, lw=2, zorder=3) ax.add_patch(rect) ax.text(x, y, text, ha='center', va='center', fontsize=fontsize, fontweight='bold' if bold else 'normal', color=text_color, zorder=4, multialignment='center', linespacing=1.4) def arr(ax, x1, y1, x2, y2, color='#2C3E50', lw=2.2, style='->'): ax.annotate('', xy=(x2, y2), xytext=(x1, y1), arrowprops=dict(arrowstyle=style, color=color, lw=lw, mutation_scale=18), zorder=5) def label_arrow(ax, x, y, txt, color='#555', fontsize=8): ax.text(x, y, txt, ha='center', va='center', fontsize=fontsize, color=color, style='italic', zorder=6) # ══════════════════════════════════════════════════════════════════════════ # TITLE # ══════════════════════════════════════════════════════════════════════════ ax.text(7, 16.5, 'RIGHT HEART FAILURE → PERIPHERAL EDEMA\nPathophysiology Diagram', ha='center', va='center', fontsize=14, fontweight='bold', color='white', bbox=dict(boxstyle='round,pad=0.5', fc='#0D47A1', ec='none')) # ══════════════════════════════════════════════════════════════════════════ # STEP 1 — Heart box (centre top) # ══════════════════════════════════════════════════════════════════════════ rbox(ax, 7, 15.1, 7.5, 0.9, 'RIGHT VENTRICLE DYSFUNCTION\n(Weakened / Failing pump)', fc='#FFCDD2', ec='#C62828', fontsize=10, bold=True, text_color='#B71C1C') arr(ax, 7, 14.65, 7, 14.2, '#C62828') label_arrow(ax, 8.2, 14.42, 'Cannot pump blood\nforward to lungs') # ══════════════════════════════════════════════════════════════════════════ # STEP 2 — Blood backs up # ══════════════════════════════════════════════════════════════════════════ rbox(ax, 7, 13.7, 8.5, 0.85, 'Blood backs up into Right Atrium → Superior & Inferior Vena Cava', fc='#FFCCBC', ec='#BF360C', fontsize=9, text_color='#BF360C') arr(ax, 7, 13.28, 7, 12.83, '#BF360C') label_arrow(ax, 8.8, 13.05, 'Venous congestion\n(traffic jam in veins)') # ══════════════════════════════════════════════════════════════════════════ # STEP 3 — Raised systemic venous pressure # ══════════════════════════════════════════════════════════════════════════ rbox(ax, 7, 12.35, 8.5, 0.85, 'RAISED SYSTEMIC VENOUS PRESSURE\n(Venous hypertension throughout body)', fc='#FFE082', ec='#F57F17', fontsize=9, bold=True, text_color='#E65100') arr(ax, 7, 11.92, 7, 11.47, '#F57F17') label_arrow(ax, 8.8, 11.7, 'Back-pressure\ntransmitted to capillaries') # ══════════════════════════════════════════════════════════════════════════ # STEP 4 — Capillary hydrostatic pressure # ══════════════════════════════════════════════════════════════════════════ rbox(ax, 7, 11.0, 8.5, 0.82, 'INCREASED CAPILLARY HYDROSTATIC PRESSURE\nOutward pushing force EXCEEDS oncotic suction force', fc='#FFF9C4', ec='#F9A825', fontsize=9, text_color='#1a1a2e') # Starling balance visual rbox(ax, 3.2, 9.9, 4.8, 1.1, 'Starling Balance\n\nHydrostatic P > Oncotic P\n(PUSH > PULL)', fc='#E8F5E9', ec='#2E7D32', fontsize=8.5, text_color='#1B5E20') ax.text(3.2, 9.47, 'Net OUTWARD force', ha='center', fontsize=8, color='#2E7D32', fontweight='bold') arr(ax, 7, 10.59, 5.65, 10.25, '#F9A825') # RAAS activation branch rbox(ax, 10.8, 9.9, 4.5, 1.1, 'Ineffective Arterial Volume\n\nActivates RAAS\n(Renin-Angiotensin-Aldosterone)', fc='#E3F2FD', ec='#1565C0', fontsize=8.5, text_color='#0D47A1') ax.text(10.8, 9.47, 'Na+ & Water retention (kidney)', ha='center', fontsize=8, color='#1565C0', fontweight='bold') arr(ax, 7, 10.59, 9.55, 10.25, '#1565C0') # Both arrows converge down arr(ax, 3.2, 9.35, 7, 8.7, '#2E7D32') arr(ax, 10.8, 9.35, 7, 8.7, '#1565C0') # ══════════════════════════════════════════════════════════════════════════ # STEP 5 — Fluid leaks out of capillaries # ══════════════════════════════════════════════════════════════════════════ rbox(ax, 7, 8.25, 9.0, 0.82, 'Fluid leaks OUT of capillaries into interstitial space\n(Protein-poor transudate)', fc='#B3E5FC', ec='#0277BD', fontsize=9, text_color='#01579B') arr(ax, 7, 7.84, 7, 7.39, '#0277BD') label_arrow(ax, 8.9, 7.6, 'Lymphatics overwhelmed\n(exceed 10-50x max capacity)') # ══════════════════════════════════════════════════════════════════════════ # STEP 6 — Lymphatics overwhelmed # ══════════════════════════════════════════════════════════════════════════ rbox(ax, 7, 6.93, 9.0, 0.82, 'Lymphatic Drainage OVERWHELMED\n(Filtration rate > max lymph flow capacity)', fc='#E1BEE7', ec='#6A1B9A', fontsize=9, text_color='#4A148C') arr(ax, 7, 6.52, 7, 6.07, '#6A1B9A') # ══════════════════════════════════════════════════════════════════════════ # STEP 7 — Peripheral Edema (main result) # ══════════════════════════════════════════════════════════════════════════ rbox(ax, 7, 5.55, 10.5, 0.88, 'PERIPHERAL EDEMA\n(Excess fluid accumulates in interstitial tissue)', fc='#FFCDD2', ec='#B71C1C', fontsize=11, bold=True, text_color='#B71C1C') # ══════════════════════════════════════════════════════════════════════════ # Clinical manifestations branch out # ══════════════════════════════════════════════════════════════════════════ arr(ax, 7, 5.11, 7, 4.72, '#B71C1C') ax.text(7, 4.55, 'CLINICAL MANIFESTATIONS', ha='center', fontsize=10, fontweight='bold', color='white', bbox=dict(boxstyle='round,pad=0.3', fc='#37474F', ec='none')) manifs = [ (1.5, 3.5, 'Bilateral Pitting\nAnkle / Leg Edema\n(Gravity dependent)', '#E3F2FD', '#1565C0'), (4.5, 3.5, 'Ascites\n(Fluid in abdomen)\n+ Hepatomegaly', '#E8F5E9', '#2E7D32'), (7.5, 3.5, 'Elevated JVP\n(Jugular Venous\nPressure)', '#FFF9C4', '#F57F17'), (10.5, 3.5, 'Anasarca\n(Severe generalised\nedema)', '#FCE4EC', '#880E4F'), (13.0, 3.5, 'Pleural\nEffusion\n(if severe)', '#F3E5F5', '#6A1B9A'), ] for (mx, my, mtxt, fc, ec) in manifs: rbox(ax, mx, my, 2.5, 1.3, mtxt, fc=fc, ec=ec, fontsize=8.5, text_color='#1a1a2e') arr(ax, 7, 4.25, mx, my + 0.65, ec, lw=1.5) # ══════════════════════════════════════════════════════════════════════════ # Why PITTING box # ══════════════════════════════════════════════════════════════════════════ rbox(ax, 7, 2.3, 11.5, 0.88, 'WHY PITTING? Leaked fluid is protein-POOR (transudate) — like water in a sponge\n' 'Pressing with finger temporarily displaces fluid → pit forms → slowly refills', fc='#E0F7FA', ec='#006064', fontsize=8.5, text_color='#004D40') # ══════════════════════════════════════════════════════════════════════════ # Treatment footer # ══════════════════════════════════════════════════════════════════════════ rbox(ax, 7, 1.35, 13.0, 0.82, 'TREATMENT: Diuretics (furosemide) | Restrict Na+ & fluid intake | Treat underlying cause\n' 'ACE inhibitors / ARBs / Beta-blockers (for HF) | IV route if bowel wall edema limits absorption', fc='#E8EAF6', ec='#283593', fontsize=8.5, text_color='#1A237E') # Analogy ribbon ax.text(7, 0.42, '"ANALOGY: Right heart failure = Blocked drain in a sink. Water (blood) cannot flow forward, backs up, and overflows into surrounding tissues (legs, abdomen)."', ha='center', fontsize=8.5, color='white', style='italic', bbox=dict(boxstyle='round,pad=0.3', fc='#263238', ec='none')) plt.tight_layout(pad=0.3) plt.savefig('/tmp/workspace/edema-diagrams/right_heart_failure_edema.png', dpi=160, bbox_inches='tight') plt.close() print("Diagram saved.") EOF
right heart failure edema
Image · PNG
postural edema
python3 << 'EOF' import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt from matplotlib.patches import FancyBboxPatch, FancyArrowPatch import matplotlib.patches as mpatches fig, ax = plt.subplots(figsize=(14, 18)) ax.set_xlim(0, 14) ax.set_ylim(0, 18) ax.axis('off') fig.patch.set_facecolor('#FAFAFA') def rbox(ax, x, y, w, h, text, fc='white', ec='#2980B9', fontsize=9, bold=False, text_color='#1a1a2e', radius=0.12): rect = FancyBboxPatch((x - w/2, y - h/2), w, h, boxstyle=f"round,pad={radius}", fc=fc, ec=ec, lw=2, zorder=3) ax.add_patch(rect) ax.text(x, y, text, ha='center', va='center', fontsize=fontsize, fontweight='bold' if bold else 'normal', color=text_color, zorder=4, multialignment='center', linespacing=1.45) def arr(ax, x1, y1, x2, y2, color='#2C3E50', lw=2.2): ax.annotate('', xy=(x2, y2), xytext=(x1, y1), arrowprops=dict(arrowstyle='->', color=color, lw=lw, mutation_scale=18), zorder=5) def side_note(ax, x, y, text, fc='#F5F5F5', ec='#BDBDBD', fontsize=7.8): rbox(ax, x, y, 3.6, 0.72, text, fc=fc, ec=ec, fontsize=fontsize, text_color='#424242', radius=0.1) # ══════════════════════════════════════════════════════════════════ # TITLE # ══════════════════════════════════════════════════════════════════ ax.text(7, 17.45, 'POSTURAL (GRAVITATIONAL) EDEMA\nPathophysiology Diagram', ha='center', va='center', fontsize=14, fontweight='bold', color='white', bbox=dict(boxstyle='round,pad=0.5', fc='#1A237E', ec='none')) # ══════════════════════════════════════════════════════════════════ # TRIGGER # ══════════════════════════════════════════════════════════════════ rbox(ax, 7, 16.3, 11.0, 0.88, 'PROLONGED STANDING / SITTING (Gravity acting on venous column)\n' 'e.g. Traffic police, factory workers, long-haul flight passengers, nurses', fc='#E8EAF6', ec='#3949AB', fontsize=9.5, bold=True, text_color='#1A237E') arr(ax, 7, 15.86, 7, 15.42, '#3949AB') # ══════════════════════════════════════════════════════════════════ # STEP 1 — Gravity effect # ══════════════════════════════════════════════════════════════════ rbox(ax, 7, 14.95, 10.5, 0.82, 'GRAVITY pulls blood column downward into dependent legs\n' 'Blood "pools" in lower limb veins (venous pooling)', fc='#BBDEFB', ec='#1565C0', fontsize=9, text_color='#0D47A1') # Analogy side note side_note(ax, 12.1, 14.95, 'Analogy:\nWater column in a tall pipe\n— pressure greatest at bottom', fc='#E3F2FD', ec='#90CAF9') arr(ax, 7, 14.54, 7, 14.09, '#1565C0') ax.text(8.6, 14.32, 'Weight of blood column\nincreases venous pressure', ha='left', fontsize=7.8, color='#1565C0', style='italic') # ══════════════════════════════════════════════════════════════════ # STEP 2 — Venous pressure rises # ══════════════════════════════════════════════════════════════════ rbox(ax, 7, 13.62, 10.5, 0.82, 'INCREASED LOCAL VENOUS PRESSURE in dependent legs\n' '(Hydrostatic pressure rises proportional to height of blood column above)', fc='#FFE082', ec='#F9A825', fontsize=9, text_color='#E65100') side_note(ax, 12.1, 13.62, 'Heart & oncotic pressure\nremain UNCHANGED\nOnly local venous P rises', fc='#FFF9C4', ec='#F9A825') arr(ax, 7, 13.21, 7, 12.76, '#F9A825') # ══════════════════════════════════════════════════════════════════ # STEP 3 — Capillary hydrostatic pressure # ══════════════════════════════════════════════════════════════════ rbox(ax, 7, 12.3, 10.5, 0.82, 'RAISED CAPILLARY HYDROSTATIC PRESSURE (in leg capillaries only)\n' 'Outward pushing force now exceeds oncotic inward suction force', fc='#FFCC80', ec='#EF6C00', fontsize=9, text_color='#BF360C') # Starling equation mini-box rbox(ax, 3.0, 11.25, 5.2, 1.0, 'Starling: Jv = Kf[(Pc - Pi) - o(pc - pi)]\n\n' 'Pc rises -> Pc - Pi increases\n-> Net OUTWARD filtration', fc='#E8F5E9', ec='#2E7D32', fontsize=8, text_color='#1B5E20') arr(ax, 7, 11.89, 5.6, 11.62, '#EF6C00') arr(ax, 7, 11.89, 7, 11.44, '#EF6C00') # ══════════════════════════════════════════════════════════════════ # STEP 4 — Fluid leaks out # ══════════════════════════════════════════════════════════════════ rbox(ax, 7, 10.98, 10.5, 0.82, 'FLUID LEAKS OUT of leg capillaries into interstitial tissue\n' 'Protein-poor transudate (albumin stays inside — oncotic pressure unchanged)', fc='#B3E5FC', ec='#0277BD', fontsize=9, text_color='#01579B') side_note(ax, 12.1, 10.98, 'No cardiac failure\nNo kidney/liver disease\nNo protein loss', fc='#E0F7FA', ec='#0097A7') arr(ax, 7, 10.57, 7, 10.12, '#0277BD') # ══════════════════════════════════════════════════════════════════ # STEP 5 — Lymphatic safety factors # ══════════════════════════════════════════════════════════════════ rbox(ax, 7, 9.66, 10.5, 0.82, 'LYMPHATIC SAFETY FACTORS activate (initially protective):\n' 'Lymph flow increases up to 10-50x | Interstitial pressure rises | Protein washed out', fc='#C8E6C9', ec='#2E7D32', fontsize=9, text_color='#1B5E20') arr(ax, 7, 9.25, 7, 8.8, '#2E7D32') ax.text(8.6, 9.0, 'If standing continues\nlymphatics get overwhelmed', ha='left', fontsize=7.8, color='#555', style='italic') # ══════════════════════════════════════════════════════════════════ # STEP 6 — Edema # ══════════════════════════════════════════════════════════════════ rbox(ax, 7, 8.34, 10.5, 0.82, 'PITTING EDEMA of feet, ankles and lower legs\n' '(Bilateral, dependent, soft, pitting — fluid is gravity-dependent)', fc='#FFCDD2', ec='#C62828', fontsize=10, bold=True, text_color='#B71C1C') # ══════════════════════════════════════════════════════════════════ # KEY FEATURES box # ══════════════════════════════════════════════════════════════════ arr(ax, 7, 7.93, 7, 7.55, '#C62828') ax.text(7, 7.38, 'KEY FEATURES', ha='center', fontsize=10, fontweight='bold', color='white', bbox=dict(boxstyle='round,pad=0.3', fc='#37474F', ec='none')) features = [ (1.8, 6.35, 'ONSET\n& TIMING', 'Develops during the day\nWorse by evening\nResolves overnight\nwith leg elevation', '#E3F2FD', '#1565C0'), (5.5, 6.35, 'DISTRIBUTION', 'Bilateral\nSymmetrical\nFeet + ankles + legs\nNOT face or arms', '#E8F5E9', '#2E7D32'), (9.2, 6.35, 'CHARACTER', 'Pitting (soft)\nNo pain\nNo erythema\nTransient / reversible', '#FFF9C4', '#F57F17'), (12.5, 6.35, 'DIFFERENTIALS\nto EXCLUDE', 'DVT (unilateral, painful)\nHF (elevated JVP)\nRenal (proteinuria)\nCirrhosis (ascites)', '#FCE4EC', '#880E4F'), ] for (fx, fy, ftitle, fdetail, fc, ec) in features: rbox(ax, fx, fy+0.35, 2.9, 0.55, ftitle, fc=ec, ec=ec, fontsize=8.5, bold=True, text_color='white') rbox(ax, fx, fy-0.6, 2.9, 1.15, fdetail, fc=fc, ec=ec, fontsize=8.2, text_color='#1a1a2e') arr(ax, 7, 7.1, fx, fy+0.62, ec, lw=1.6) # ══════════════════════════════════════════════════════════════════ # RESOLUTION section # ══════════════════════════════════════════════════════════════════ rbox(ax, 7, 4.8, 12.5, 0.82, 'RESOLUTION — Elevating legs removes gravity effect:\n' 'Venous pressure falls -> Capillary P normalises -> Fluid reabsorbed by lymphatics -> Edema resolves', fc='#E8F5E9', ec='#1B5E20', fontsize=9, text_color='#1B5E20') # ══════════════════════════════════════════════════════════════════ # ANALOGY box # ══════════════════════════════════════════════════════════════════ rbox(ax, 7, 3.9, 13.0, 0.75, 'ANALOGY: Think of a tall glass of water with a small hole at the bottom.\n' 'The higher the water column (standing longer), the more pressure at the hole, the more water leaks out.', fc='#FFF8E1', ec='#FFB300', fontsize=8.8, text_color='#4E342E') # ══════════════════════════════════════════════════════════════════ # COMPARISON with Pathological Edema # ══════════════════════════════════════════════════════════════════ ax.text(7, 3.2, 'HOW POSTURAL EDEMA DIFFERS FROM PATHOLOGICAL EDEMA', ha='center', fontsize=9.5, fontweight='bold', color='white', bbox=dict(boxstyle='round,pad=0.3', fc='#455A64', ec='none')) diff_data = [ ('Feature', 'Postural Edema', 'Right Heart Failure', 'Nephrotic Syndrome'), ('Cause', 'Gravity / prolonged standing', 'Weak right ventricle', 'Albumin loss in urine'), ('JVP', 'Normal', 'RAISED', 'Normal'), ('Resolves with\nleg elevation', 'YES — quickly', 'NO / partial', 'NO'), ('Other signs', 'None', 'SOB, ascites, hepatomegaly', 'Frothy urine, periorbital edema'), ('Treatment', 'Leg elevation, movement', 'Diuretics, ACEi/ARB', 'Steroids, low-salt diet'), ] col_positions = [1.6, 5.0, 9.0, 12.7] col_widths = [2.8, 3.6, 3.6, 3.6] row_y_start = 2.95 row_h = 0.38 row_colors = ['#CFD8DC', '#ECEFF1'] header_colors_t = ['#455A64', '#1565C0', '#BF360C', '#1B5E20'] for ri, row in enumerate(diff_data): for ci, (cell, cx, cw) in enumerate(zip(row, col_positions, col_widths)): yy = row_y_start - ri * row_h if ri == 0: fc_c = header_colors_t[ci] tc = 'white' fw = 'bold' else: fc_c = row_colors[ri % 2] tc = '#1a1a2e' fw = 'normal' rect = FancyBboxPatch((cx - cw/2, yy - row_h/2), cw, row_h, boxstyle="square,pad=0", fc=fc_c, ec='#90A4AE', lw=0.8, zorder=2) ax.add_patch(rect) ax.text(cx, yy, cell, ha='center', va='center', fontsize=7.6, fontweight=fw, color=tc, zorder=3, multialignment='center') # ══════════════════════════════════════════════════════════════════ # Footer # ══════════════════════════════════════════════════════════════════ ax.text(7, 0.35, 'KEY: Postural edema = pure MECHANICAL effect of gravity on venous pressure. ' 'No cardiac, renal, or hepatic disease. Reversible with position change.', ha='center', fontsize=8.5, fontweight='bold', color='white', bbox=dict(boxstyle='round,pad=0.32', fc='#1A237E', ec='none')) plt.tight_layout(pad=0.3) plt.savefig('/tmp/workspace/edema-diagrams/postural_edema.png', dpi=160, bbox_inches='tight') plt.close() print("Postural edema diagram saved.") EOF
postural edema
Image · PNG
| Feature | Postural Edema | Right Heart Failure |
|---|---|---|
| JVP | Normal | Raised |
| Resolves with elevation | Yes, quickly | No |
| Other signs | None | SOB, ascites, hepatomegaly |
| Treatment | Leg elevation, movement | Diuretics, ACEi |