Write a shortnote One thyroid neoplasms. Classification and... Make it point wise. Uh, so that I can write easily in exam.
thyroid carcinoma types histology papillary follicular medullary anaplastic

This line graph illustrates the epidemiological trends in the distribution of thyroid cancer cases by histological type from 1980 to 2012. The data, expressed as a percentage of all thyroid cancer cases, shows a prominent increase in papillary carcinoma, which rose from approximately 60% in 1980 to over 90% by 2012. Conversely, other histological subtypes show a steady decline in relative proportion over the same period. Follicular carcinoma, which initially accounted for nearly 25% of cases, decreased significantly. Medullary and anaplastic carcinomas, along with a category labeled as 'others,' remained at low percentages and trended downward toward the end of the study period. This visualization emphasizes the shifting landscape of thyroid pathology, highlighting the increasing dominance of papillary carcinoma in clinical diagnosis and incidence relative to non-papillary types. The graph serves as an educational resource for oncology and endocrinology, illustrating longitudinal changes in cancer subtypes within a specific population context.

Histology image obtained from thyroid tissue showing medullary thyroid carcinoma with extracellular amyloid deposits in the tumor stroma and a foreign body-type giant cell reaction surrounding the amyloid. The slide is a paraffin-embedded tissue section stained with Hematoxylin and Eosin, visualized under light microscopy. The malignant parafollicular C-cells form nests and sheets with uniform, round to polygonal cells and granular cytoplasm, displaying salt-and-pepper nuclear characteristics. A conspicuous, pink, amorphous extracellular matrix represents calcitonin-derived amyloid within and around tumor nests; multinucleated giant cells and macrophages are present at the periphery, reflecting a foreign body-type granulomatous response to amyloid deposition. Congo red staining (not shown here) would typically reveal apple-green birefringence under polarized light, confirming amyloid. This histology is characteristic of medullary thyroid carcinoma (MTC) and helps distinguish it from papillary, follicular, or anaplastic thyroid cancers. Diagnostic significance rests on the co-occurrence of C-cell neoplasia and amyloid, a hallmark of MTC, with possible associations to calcitonin gene-related peptide and RET oncogene alterations. Clinically, MTC presents with a neck mass and elevated serum calcitonin and CEA; amyloid-rich stroma reflects tumor biology and has prognostic implications. The image supports educational and diagnostic use in pathology, endocrine oncology, and medical education.

This histopathology image depicts thyroid tissue demonstrating papillary thyroid carcinoma features on bright-field light microscopy after Hematoxylin and Eosin staining. The specimen, a surgical thyroid tissue section, reveals papillary architecture with branching fronds and fibrovascular cores infiltrating the surrounding parenchyma. Tumor cells are columnar to cuboidal with enlarged, optically dense nuclei showing characteristic clearing (Orphan Annie eye), nuclear grooves, and occasional intranuclear inclusions. The nuclear features are conspicuous and serve as the diagnostic hallmark of PTC, distinguishing it from benign thyroid tissue and other malignancies. In many regions, the papillary cores and tumor clusters are surrounded by delicate fibrous stroma, with occasional calcified psammoma bodies that may be present within the papillae. Capsular or lymphovascular invasion may be evident in invasive disease, correlating with higher staging. The image highlights the propensity of PTC to metastasize to cervical lymph nodes, a clinically relevant consideration in surgical planning, neck dissection, and prognosis. This slide also provides a reference for differential diagnosis including follicular variant of papillary thyroid carcinoma, follicular thyroid carcinoma, medullary thyroid carcinoma, and anaplastic/poorly differentiated thyroid carcinomas. Clinically, these histologic features guide treatment strategies and correlate with tumor behavior and patient outcome.

This gross pathology photograph shows four cross-sectional views of a thyroid tumor resected from the neck in a patient with medullary thyroid carcinoma. Imaging modality: gross surgical pathology photography; blue background and a 1 cm scale bar provide size reference. The four specimens display solid, tan-gray to pink-tan nodules with lobulated contours and variable firmness. Cut surfaces reveal heterogeneous texture with pale, fibrous to yellowish tissue and focal hemorrhagic areas; margins appear irregular, reflecting tumor invasion into adjacent thyroid parenchyma. Overall architecture shows complete or near-complete replacement of normal thyroid tissue by focal to multifocal neoplastic nodules. While definitive diagnosis requires microscopic evaluation, these gross features are compatible with a malignant neuroendocrine neoplasm of parafollicular C-cell origin. Medullary thyroid carcinoma often demonstrates pale, tan to gray cut surfaces with firm consistency and gross heterogeneity; histology typically shows nests of polygonal cells with amyloid stroma and calcitonin immunoreactivity. Clinically, MTC may secrete calcitonin and CEA and is associated with MEN2 syndromes; surgical management and prognosis hinge on stage and nodal involvement. This image is valuable for education on gross morphology, differential diagnosis versus papillary, follicular, and anaplastic carcinomas, and for correlating gross findings with radiologic and histopathologic workflows.
| Type | Origin | Frequency |
|---|---|---|
| Papillary Thyroid Carcinoma (PTC) | Follicular epithelium | ~85% (most common) |
| Follicular Thyroid Carcinoma (FTC) | Follicular epithelium | ~10% |
| Medullary Thyroid Carcinoma (MTC) | Parafollicular C cells | ~5% |
| Anaplastic (Undifferentiated) | Follicular epithelium | ~1-2% (most aggressive) |
| Sporadic | Familial | |
|---|---|---|
| % | ~70% | ~30% |
| Age | 5th-6th decade | Younger |
| RET mutation | Acquired (~50%) | Germline (all cases) |
| Associated with | - | MEN 2A, MEN 2B, FMTC |
| Feature | Papillary | Follicular | Medullary | Anaplastic |
|---|---|---|---|---|
| Frequency | 85% | 10% | 5% | 1-2% |
| Origin | Follicular epi | Follicular epi | C cells | Follicular epi |
| Spread | Lymphatic | Hematogenous | Both | Direct invasion |
| Marker | - | - | Calcitonin, CEA | - |
| Key mutation | BRAF | RAS, PAX8-PPARG | RET | TP53 |
| Psammoma bodies | Yes | No | No | No |
| Amyloid stroma | No | No | Yes | No |
| 10-yr survival | >95% | ~85% | ~50-65% | <5% |
| Prognosis | Best | Good | Intermediate | Worst |
| Feature | Adenoma | Carcinoma |
|---|---|---|
| Capsule | Intact, complete | Breached (capsular invasion) |
| Vascular invasion | Absent | Present |
| FNA | Cannot distinguish | Cannot distinguish |
| Definitive diagnosis | Histology after excision | Histology after excision |
Exam tip: Most examiners ask: (1) nuclear features of PTC, (2) how to distinguish follicular adenoma vs. carcinoma, (3) amyloid in MTC, (4) prognosis order, and (5) mutations (BRAF = PTC, RAS = FTC, RET = MTC, TP53 = Anaplastic).


Create a high density, high yielding image based... Flashcard I can use. Before exam to revise and remember all the important points regarding this shortnote
mkdir -p /tmp/workspace/thyroid-flashcard && ls /tmp/workspace/thyroid-flashcard/
~/thyroid-flashcard/create_flashcard.py
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
from matplotlib.patches import FancyBboxPatch, FancyArrowPatch
import matplotlib.gridspec as gridspec
import numpy as np
# ── Canvas ──────────────────────────────────────────────────────────────────
fig = plt.figure(figsize=(22, 30), facecolor='#0a0a1a')
# ── Colour palette ───────────────────────────────────────────────────────────
BG = '#0a0a1a'
TITLE_BG = '#1a1a3e'
PTC_C = '#1565C0' # deep blue
FTC_C = '#1B5E20' # deep green
MTC_C = '#6A1B9A' # deep purple
ANA_C = '#B71C1C' # deep red
BEN_C = '#E65100' # deep orange
NIF_C = '#00695C' # teal
HDR_TXT = '#FFFFFF'
SUB_TXT = '#E0E0E0'
YEL = '#FFD600'
CYN = '#00E5FF'
GRN = '#69F0AE'
RED = '#FF5252'
ORA = '#FFAB40'
PNK = '#F48FB1'
WHT = '#FFFFFF'
LGR = '#B0BEC5'
def box(ax, x, y, w, h, color, alpha=0.85, radius=0.015):
fancy = FancyBboxPatch((x, y), w, h,
boxstyle=f"round,pad=0.005,rounding_size={radius}",
linewidth=1.2, edgecolor=color,
facecolor=color, alpha=alpha,
transform=ax.transAxes, zorder=3)
ax.add_patch(fancy)
def hdr(ax, x, y, w, h, color, title, fs=11):
box(ax, x, y, w, h, color, alpha=0.95)
ax.text(x + w/2, y + h/2, title, transform=ax.transAxes,
ha='center', va='center', fontsize=fs, fontweight='bold',
color=WHT, zorder=5)
def txt(ax, x, y, s, color=SUB_TXT, fs=8.2, bold=False, ha='left', va='top'):
fw = 'bold' if bold else 'normal'
ax.text(x, y, s, transform=ax.transAxes,
ha=ha, va=va, fontsize=fs, color=color,
fontweight=fw, zorder=6, linespacing=1.55)
def dot(ax, x, y, color=YEL, size=5):
ax.plot(x, y, 'o', color=color, markersize=size,
transform=ax.transAxes, zorder=7)
# ── Main axis (covers entire figure) ────────────────────────────────────────
ax = fig.add_axes([0, 0, 1, 1])
ax.set_xlim(0, 1); ax.set_ylim(0, 1)
ax.axis('off')
ax.set_facecolor(BG)
# ═══════════════════════════════════════════════════════════════════════════
# TITLE BAR
# ═══════════════════════════════════════════════════════════════════════════
box(ax, 0.01, 0.965, 0.98, 0.030, '#1a1a3e', alpha=1.0)
ax.text(0.5, 0.981, '🧬 THYROID NEOPLASMS — HIGH-YIELD EXAM FLASHCARD',
transform=ax.transAxes, ha='center', va='center',
fontsize=15, fontweight='bold', color=YEL, zorder=8)
ax.text(0.5, 0.968, 'Robbins Pathology | Classification · Features · Mutations · Prognosis',
transform=ax.transAxes, ha='center', va='center',
fontsize=8, color=LGR, zorder=8)
# ═══════════════════════════════════════════════════════════════════════════
# ROW 1 ─ Classification banner
# ═══════════════════════════════════════════════════════════════════════════
hdr(ax, 0.01, 0.930, 0.98, 0.028, '#263238', '▌ CLASSIFICATION OF THYROID TUMORS', fs=10)
# Benign block
box(ax, 0.01, 0.880, 0.185, 0.044, BEN_C, alpha=0.30)
hdr(ax, 0.01, 0.916, 0.185, 0.016, BEN_C, 'BENIGN', fs=8)
txt(ax, 0.020, 0.910, '• Follicular Adenoma (most common)\n• Toxic (Functioning) Adenoma\n• Hurthle Cell Adenoma', fs=7.8)
# Malignant block
box(ax, 0.205, 0.880, 0.780, 0.044, '#37474F', alpha=0.30)
hdr(ax, 0.205, 0.916, 0.780, 0.016, '#37474F', 'MALIGNANT', fs=8)
# Four type pills
for i, (label, pct, col) in enumerate([
('Papillary (PTC)', '85 %', PTC_C),
('Follicular (FTC)', '10 %', FTC_C),
('Medullary (MTC)', '5 %', MTC_C),
('Anaplastic', '1–2 %', ANA_C),
]):
xi = 0.210 + i * 0.192
box(ax, xi, 0.882, 0.180, 0.030, col, alpha=0.85)
ax.text(xi + 0.090, 0.905, label, transform=ax.transAxes,
ha='center', va='center', fontsize=8.0, fontweight='bold', color=WHT, zorder=8)
ax.text(xi + 0.090, 0.888, pct, transform=ax.transAxes,
ha='center', va='center', fontsize=8.5, color=YEL, fontweight='bold', zorder=8)
# ═══════════════════════════════════════════════════════════════════════════
# ROW 2 ─ PTC | FTC (side by side)
# ═══════════════════════════════════════════════════════════════════════════
# --- PTC card ---
box(ax, 0.01, 0.620, 0.485, 0.250, PTC_C, alpha=0.12)
hdr(ax, 0.01, 0.848, 0.485, 0.024, PTC_C, '① PAPILLARY THYROID CARCINOMA (PTC) — Most Common (85%)', fs=9.5)
txt(ax, 0.022, 0.838, '🔬 ORIGIN:', CYN, fs=8.2, bold=True)
txt(ax, 0.120, 0.838, 'Follicular epithelium', fs=8.2)
txt(ax, 0.022, 0.826, '⚡ MUTATION:', CYN, fs=8.2, bold=True)
txt(ax, 0.120, 0.826, 'BRAF (40–65%) | RAS (10–30%) | RET/PTC rearrangement (10–20%) [mutually exclusive]', fs=8.2)
txt(ax, 0.022, 0.814, '☢ RISK FACTOR:', CYN, fs=8.2, bold=True)
txt(ax, 0.130, 0.814, 'Ionizing radiation (Chernobyl ↑ in children)', fs=8.2)
txt(ax, 0.022, 0.799, '📌 MORPHOLOGY — HALLMARKS:', YEL, fs=8.5, bold=True)
lines_ptc_m = [
'• Branching papillae with fibrovascular stalks',
'• "Orphan Annie Eye" nuclei → optically clear / ground-glass',
'• Intranuclear pseudo-inclusions + nuclear grooves',
'• Psammoma bodies (concentric calcifications) ✔',
'• Lymphatic invasion common; vascular invasion UNCOMMON',
'• Multifocal lesions possible',
]
for i, l in enumerate(lines_ptc_m):
col = GRN if 'Orphan' in l or 'Psammoma' in l else SUB_TXT
txt(ax, 0.022, 0.788 - i*0.0115, l, col, fs=8.0)
txt(ax, 0.022, 0.716, '🔗 SPREAD:', CYN, fs=8.2, bold=True)
txt(ax, 0.100, 0.716, 'LYMPHATIC (cervical LN mets in 50%) — blood-borne uncommon', fs=8.2)
txt(ax, 0.022, 0.704, '🏥 PRESENTATION:', CYN, fs=8.2, bold=True)
txt(ax, 0.150, 0.704, 'Painless neck mass | Cold nodule on scan | FNA → nuclear features', fs=8.2)
txt(ax, 0.022, 0.692, '📊 PROGNOSIS:', CYN, fs=8.2, bold=True)
ax.text(0.100, 0.693, '10-yr survival > 95% ★ BEST', transform=ax.transAxes,
ha='left', va='top', fontsize=9, fontweight='bold', color=GRN, zorder=8)
txt(ax, 0.022, 0.680, '⚠ NOTE:', ORA, fs=8.2, bold=True)
txt(ax, 0.085, 0.680, 'Cervical LN mets do NOT worsen prognosis significantly', fs=8.2)
txt(ax, 0.022, 0.668, '🧪 FNA:', CYN, fs=8.2, bold=True)
txt(ax, 0.070, 0.668, 'Can diagnose PTC (nuclear features visible on aspirate)', fs=8.2)
txt(ax, 0.022, 0.655, '🔖 VARIANTS:', ORA, fs=8.2, bold=True)
txt(ax, 0.100, 0.655, 'Encapsulated follicular variant (PAX8-PPARG ↑) | Tall cell | Diffuse sclerosing', fs=8.0)
txt(ax, 0.022, 0.643, '🔵 NIFTP:', PNK, fs=8.2, bold=True)
txt(ax, 0.085, 0.643, 'Reclassified from encapsulated follicular PTC → borderline (NOT carcinoma); no RAI needed', fs=7.8)
txt(ax, 0.022, 0.630, '🧬 PATH:', CYN, fs=8.2, bold=True)
txt(ax, 0.075, 0.630, 'MAP Kinase pathway activation', fs=8.2)
# --- FTC card ---
box(ax, 0.505, 0.620, 0.485, 0.250, FTC_C, alpha=0.12)
hdr(ax, 0.505, 0.848, 0.485, 0.024, FTC_C, '② FOLLICULAR THYROID CARCINOMA (FTC) — 10%', fs=9.5)
txt(ax, 0.517, 0.838, '🔬 ORIGIN:', CYN, fs=8.2, bold=True)
txt(ax, 0.615, 0.838, 'Follicular epithelium', fs=8.2)
txt(ax, 0.517, 0.826, '⚡ MUTATION:', CYN, fs=8.2, bold=True)
txt(ax, 0.615, 0.826, 'RAS (most common) | PAX8-PPARG fusion (2;3)(q13;p25) in 50% | PIK3CA | PTEN', fs=8.0)
txt(ax, 0.517, 0.814, '☣ RISK FACTOR:', CYN, fs=8.2, bold=True)
txt(ax, 0.630, 0.814, 'Iodine deficiency / endemic goiter', fs=8.2)
txt(ax, 0.517, 0.799, '📌 MORPHOLOGY — HALLMARKS:', YEL, fs=8.5, bold=True)
lines_ftc_m = [
'• Looks similar to follicular adenoma (cannot distinguish on FNA!)',
'• CAPSULAR INVASION ★ KEY diagnostic feature',
'• VASCULAR INVASION ★ (endovascular tumour plugs)',
'• Minimal invasive vs. Widely invasive forms',
'• NO psammoma bodies, NO papillary nuclei',
]
for i, l in enumerate(lines_ftc_m):
col = RED if 'CAPSULAR' in l or 'VASCULAR' in l else SUB_TXT
txt(ax, 0.517, 0.788 - i*0.0115, l, col, fs=8.0)
txt(ax, 0.517, 0.730, '🔗 SPREAD:', CYN, fs=8.2, bold=True)
txt(ax, 0.595, 0.730, 'HEMATOGENOUS — lung, bone, liver, brain (cannon-ball mets)', fs=8.2)
txt(ax, 0.517, 0.718, ' ', fs=8.2)
txt(ax, 0.517, 0.718, 'LN mets UNCOMMON (opposite of PTC)', ORA, fs=8.0)
txt(ax, 0.517, 0.706, '🏥 PRESENTATION:', CYN, fs=8.2, bold=True)
txt(ax, 0.655, 0.706, 'Painless cold nodule | FNA → cannot distinguish from adenoma', fs=8.2)
txt(ax, 0.517, 0.694, '🔑 DIAGNOSIS:', CYN, fs=8.2, bold=True)
txt(ax, 0.618, 0.694, 'Histology AFTER surgical excision + capsule evaluation (not FNA)', fs=8.2)
txt(ax, 0.517, 0.682, '📊 PROGNOSIS:', CYN, fs=8.2, bold=True)
ax.text(0.595, 0.683, '10-yr survival ~85% ★ Good', transform=ax.transAxes,
ha='left', va='top', fontsize=9, fontweight='bold', color=GRN, zorder=8)
txt(ax, 0.517, 0.670, '⚠ NOTE:', ORA, fs=8.2, bold=True)
txt(ax, 0.580, 0.670, 'Widely invasive form → worse outcome', fs=8.2)
txt(ax, 0.517, 0.658, '🧬 PATH:', CYN, fs=8.2, bold=True)
txt(ax, 0.570, 0.658, 'PI3K/AKT + RAS pathway mutations shared with adenoma & anaplastic', fs=8.0)
# ═══════════════════════════════════════════════════════════════════════════
# ROW 3 ─ MTC | Anaplastic
# ═══════════════════════════════════════════════════════════════════════════
# --- MTC card ---
box(ax, 0.01, 0.360, 0.485, 0.250, MTC_C, alpha=0.12)
hdr(ax, 0.01, 0.588, 0.485, 0.024, MTC_C, '③ MEDULLARY THYROID CARCINOMA (MTC) — 5%', fs=9.5)
txt(ax, 0.022, 0.578, '🔬 ORIGIN:', CYN, fs=8.2, bold=True)
txt(ax, 0.100, 0.578, 'Parafollicular C cells (NOT follicular epithelium!)', GRN, fs=8.2, bold=True)
txt(ax, 0.022, 0.566, '⚡ MUTATION:', CYN, fs=8.2, bold=True)
txt(ax, 0.100, 0.566, 'RET proto-oncogene (tyrosine kinase receptor)', fs=8.2)
txt(ax, 0.022, 0.553, '👨👩👧 TYPES:', YEL, fs=8.5, bold=True)
# MTC table
headers = ['', 'Sporadic', 'Familial']
rows_mtc = [
['%', '~70 %', '~30 %'],
['Age', '5th–6th decade', 'Younger age'],
['RET mut', 'Acquired (~50 %)', 'Germline (ALL cases)'],
['Association', '—', 'MEN 2A, MEN 2B, FMTC'],
]
col_x = [0.022, 0.140, 0.310]
row_y = 0.543
for hi, h in enumerate(headers):
c = YEL if hi > 0 else SUB_TXT
txt(ax, col_x[hi], row_y, h, c, fs=8.0, bold=True)
for ri, row in enumerate(rows_mtc):
for ci, cell in enumerate(row):
c = CYN if ci == 0 else (ORA if 'Germline' in cell else SUB_TXT)
txt(ax, col_x[ci], row_y - 0.013*(ri+1), cell, c, fs=7.8)
txt(ax, 0.022, 0.482, '📌 MORPHOLOGY — HALLMARKS:', YEL, fs=8.5, bold=True)
lines_mtc_m = [
'• Nests / sheets of polygonal-to-spindle cells',
'• AMYLOID in stroma ★ PATHOGNOMONIC (calcitonin-derived)',
' → stains with Congo red → apple-green birefringence',
'• Salt-and-pepper nuclear chromatin',
'• Calcitonin granules in cytoplasm',
]
for i, l in enumerate(lines_mtc_m):
col = PNK if 'AMYLOID' in l else (ORA if 'Congo' in l else SUB_TXT)
txt(ax, 0.022, 0.471 - i*0.0115, l, col, fs=8.0)
txt(ax, 0.022, 0.410, '🔬 TUMOUR MARKERS:', CYN, fs=8.2, bold=True)
ax.text(0.160, 0.411, 'CALCITONIN + CEA', transform=ax.transAxes,
ha='left', va='top', fontsize=9.5, fontweight='bold', color=PNK, zorder=8)
txt(ax, 0.022, 0.398, '🔗 SPREAD:', CYN, fs=8.2, bold=True)
txt(ax, 0.100, 0.398, 'Lymphatic + Hematogenous (both)', fs=8.2)
txt(ax, 0.022, 0.386, '🏥 FEATURES:', CYN, fs=8.2, bold=True)
txt(ax, 0.110, 0.386, 'Neck mass | Diarrhea (calcitonin/VIP) | Flushing', fs=8.2)
txt(ax, 0.022, 0.374, '🔵 MEN 2A:', ORA, fs=8.2, bold=True)
txt(ax, 0.095, 0.374, 'MTC + Phaeochromocytoma + Hyperparathyroidism', fs=8.2)
txt(ax, 0.022, 0.362, '🔴 MEN 2B:', ORA, fs=8.2, bold=True)
txt(ax, 0.095, 0.362, 'MTC + Phaeochromocytoma + Mucosal neuromas + Marfanoid habitus', fs=8.2)
txt(ax, 0.022, 0.372, '', fs=8.2)
txt(ax, 0.022, 0.373, '📊 PROGNOSIS:', fs=7, color=CYN, bold=True)
ax.text(0.120, 0.374, '10-yr survival ~50–65% (Intermediate)', transform=ax.transAxes,
ha='left', va='top', fontsize=8.5, fontweight='bold', color=ORA, zorder=8)
# --- Anaplastic card ---
box(ax, 0.505, 0.360, 0.485, 0.250, ANA_C, alpha=0.12)
hdr(ax, 0.505, 0.588, 0.485, 0.024, ANA_C, '④ ANAPLASTIC THYROID CARCINOMA — Most Lethal', fs=9.5)
txt(ax, 0.517, 0.578, '🔬 ORIGIN:', CYN, fs=8.2, bold=True)
txt(ax, 0.595, 0.578, 'Follicular epithelium (de novo OR dedifferentiation of PTC/FTC)', fs=8.2)
txt(ax, 0.517, 0.566, '⚡ MUTATION:', CYN, fs=8.2, bold=True)
txt(ax, 0.595, 0.566, 'TP53 loss ★ MOST SPECIFIC | RAS | PIK3CA (+ prior PTC/FTC mutations)', RED, fs=8.2)
txt(ax, 0.517, 0.554, '👴 AGE:', CYN, fs=8.2, bold=True)
txt(ax, 0.570, 0.554, 'Usually >65 years', fs=8.2)
txt(ax, 0.517, 0.540, '📌 MORPHOLOGY — HALLMARKS:', YEL, fs=8.5, bold=True)
lines_ana_m = [
'• Highly pleomorphic, undifferentiated cells',
'• Abundant mitoses + extensive necrosis',
'• Patterns: Spindle cell / Giant cell / Small cell',
'• Rapidly invasive — infiltrates trachea, vessels, nerves',
'• Often arises in background of differentiated carcinoma',
]
for i, l in enumerate(lines_ana_m):
col = RED if 'pleomorphic' in l or 'invasive' in l else SUB_TXT
txt(ax, 0.517, 0.529 - i*0.0115, l, col, fs=8.0)
txt(ax, 0.517, 0.470, '🏥 PRESENTATION:', CYN, fs=8.2, bold=True)
txt(ax, 0.655, 0.470, 'Rapidly enlarging FIXED neck mass (days to weeks)', RED, fs=8.2, bold=True)
txt(ax, 0.517, 0.458, ' :', fs=8.2)
txt(ax, 0.517, 0.458, 'Symptoms:', CYN, fs=8.2, bold=True)
txt(ax, 0.590, 0.458, 'Dysphagia | Hoarseness | Stridor | SVC syndrome', fs=8.2)
txt(ax, 0.517, 0.446, '🔴 STAGING:', CYN, fs=8.2, bold=True)
ax.text(0.593, 0.447, 'ALL anaplastic carcinomas = Stage IV at diagnosis', transform=ax.transAxes,
ha='left', va='top', fontsize=8.5, fontweight='bold', color=RED, zorder=8)
txt(ax, 0.517, 0.434, '📊 PROGNOSIS:', CYN, fs=8.2, bold=True)
ax.text(0.618, 0.435, '< 5% 5-yr survival | Median survival = 6 months ★ WORST', transform=ax.transAxes,
ha='left', va='top', fontsize=9, fontweight='bold', color=RED, zorder=8)
txt(ax, 0.517, 0.422, '💊 TX NOTE:', ORA, fs=8.2, bold=True)
txt(ax, 0.595, 0.422, 'BRAF-mutant anaplastic → Dabrafenib + Trametinib (targeted)', fs=8.0)
txt(ax, 0.517, 0.410, '🧬 PATHOGENESIS:', CYN, fs=8.2, bold=True)
txt(ax, 0.635, 0.410, 'Stepwise dedifferentiation (PTC → FTC → Anaplastic) over time', fs=8.0)
# ═══════════════════════════════════════════════════════════════════════════
# ROW 4 ─ Comparison Table
# ═══════════════════════════════════════════════════════════════════════════
hdr(ax, 0.01, 0.328, 0.98, 0.024, '#263238', '▌ MASTER COMPARISON TABLE', fs=10)
cols = ['Feature', 'PTC 85%', 'FTC 10%', 'MTC 5%', 'Anaplastic 1-2%']
col_x2 = [0.014, 0.210, 0.390, 0.570, 0.750]
col_colors = [LGR, PTC_C, FTC_C, MTC_C, ANA_C]
# header row
for ci, (h, cx) in enumerate(zip(cols, col_x2)):
box(ax, cx, 0.304, 0.188, 0.020, col_colors[ci], alpha=0.85)
ax.text(cx + 0.094, 0.314, h, transform=ax.transAxes,
ha='center', va='center', fontsize=8.2, fontweight='bold', color=WHT, zorder=8)
rows_cmp = [
['Origin', 'Follicular epi', 'Follicular epi', 'C cells ★', 'Follicular epi'],
['Key mutation', 'BRAF ★', 'RAS + PAX8-PPARG★', 'RET ★', 'TP53 ★'],
['Spread', 'Lymphatic ★', 'Hematogenous ★', 'Both', 'Direct invasion'],
['Psammoma', '✔ YES ★', '✘ No', '✘ No', '✘ No'],
['Amyloid', '✘ No', '✘ No', '✔ YES ★', '✘ No'],
['Tumour marker', '—', '—', 'Calcitonin+CEA ★', '—'],
['FNA diagnosis', '✔ YES', '✘ CANNOT', 'Can suggest', 'Yes'],
['10-yr survival','> 95% BEST', '~85 % Good', '50–65% Intermediate','< 5% WORST'],
['Prognosis', '★★★★★', '★★★★', '★★★', '★'],
]
row_y_start = 0.299
row_h = 0.022
for ri, row in enumerate(rows_cmp):
bg_alpha = 0.10 if ri % 2 == 0 else 0.04
box(ax, 0.014, row_y_start - (ri+1)*row_h, 0.972, row_h, '#FFFFFF', alpha=bg_alpha)
for ci, (cell, cx) in enumerate(zip(row, col_x2)):
special_cols = {
('BRAF ★', 1): YEL, ('RAS + PAX8-PPARG★', 2): YEL,
('RET ★', 3): YEL, ('TP53 ★', 4): YEL,
('Lymphatic ★', 1): CYN, ('Hematogenous ★', 2): ORA,
('✔ YES ★', 1): GRN, ('✔ YES ★', 3): PNK,
('Calcitonin+CEA ★', 3): PNK,
('> 95% BEST', 1): GRN, ('~85 % Good', 2): GRN,
('50–65% Intermediate', 3): ORA, ('< 5% WORST', 4): RED,
('C cells ★', 3): PNK,
('✘ CANNOT', 2): RED,
}
c = special_cols.get((cell, ci), SUB_TXT if ci > 0 else CYN)
fw = 'bold' if ci == 0 or '★' in cell else 'normal'
ax.text(cx + 0.005, row_y_start - (ri+1)*row_h + row_h/2,
cell, transform=ax.transAxes,
ha='left', va='center', fontsize=7.6, color=c, fontweight=fw, zorder=8)
# ═══════════════════════════════════════════════════════════════════════════
# ROW 5 ─ Follicular Adenoma vs Carcinoma | Risk Factors | Exam Tips
# ═══════════════════════════════════════════════════════════════════════════
bottom_y = row_y_start - (len(rows_cmp)+1)*row_h - 0.008
# Adenoma vs Carcinoma
box(ax, 0.01, bottom_y, 0.315, 0.098, BEN_C, alpha=0.12)
hdr(ax, 0.01, bottom_y + 0.080, 0.315, 0.018, BEN_C, '▌ ADENOMA vs CARCINOMA', fs=8.5)
lines_avc = [
('Capsule:', 'INTACT (adenoma) vs BREACHED (carcinoma) ★'),
('Vasc. invasion:', 'Absent (adenoma) vs Present (carcinoma) ★'),
('FNA:', 'Cannot distinguish either ★'),
('Diagnosis:', 'Histology after EXCISION + capsule eval'),
('Prognosis:', 'Adenoma = excellent (no recurrence)'),
]
for i, (label, val) in enumerate(lines_avc):
txt(ax, 0.020, bottom_y + 0.073 - i*0.013, label, CYN, fs=7.8, bold=True)
txt(ax, 0.105, bottom_y + 0.073 - i*0.013, val, SUB_TXT if i > 0 else RED, fs=7.8)
# Risk Factors
box(ax, 0.335, bottom_y, 0.315, 0.098, '#1a237e', alpha=0.20)
hdr(ax, 0.335, bottom_y + 0.080, 0.315, 0.018, '#1a237e', '▌ RISK FACTORS', fs=8.5)
rf = [
('PTC:', 'Ionizing radiation (esp. childhood)'),
('FTC:', 'Iodine deficiency / endemic goiter'),
('MTC:', 'RET germline mutation / MEN 2'),
('Anaplastic:', 'Prior PTC or FTC (dedifferentiation)'),
('Cold nodule:','10% risk of malignancy → FNA needed'),
]
for i, (label, val) in enumerate(rf):
c = [PTC_C, FTC_C, MTC_C, ANA_C, ORA][i]
txt(ax, 0.345, bottom_y + 0.073 - i*0.013, label, c, fs=7.8, bold=True)
txt(ax, 0.415, bottom_y + 0.073 - i*0.013, val, SUB_TXT, fs=7.8)
# Exam tips
box(ax, 0.660, bottom_y, 0.330, 0.098, YEL, alpha=0.10)
hdr(ax, 0.660, bottom_y + 0.080, 0.330, 0.018, '#F57F17', '▌ ⭐ EXAM MUST-KNOWS', fs=8.5)
tips = [
'• Orphan Annie nuclei + Psammoma = PTC',
'• Capsular/vascular invasion = FTC (not adenoma)',
'• Amyloid stroma + Calcitonin = MTC',
'• Fastest growing + worst = Anaplastic (TP53)',
'• FNA cannot dx FTC (need excision)',
'• RET germline → screen family for MTC',
'• BRAF = PTC | RAS = FTC | RET = MTC | TP53 = Anaplastic',
]
for i, t in enumerate(tips):
col = YEL if i == 6 else SUB_TXT
txt(ax, 0.668, bottom_y + 0.073 - i*0.011, t, col, fs=7.6)
# ═══════════════════════════════════════════════════════════════════════════
# Footer
# ═══════════════════════════════════════════════════════════════════════════
ax.text(0.5, 0.008, 'Source: Robbins & Kumar Basic Pathology | For exam revision only',
transform=ax.transAxes, ha='center', va='bottom',
fontsize=7.5, color='#546E7A', style='italic', zorder=8)
# ── Save ─────────────────────────────────────────────────────────────────────
plt.tight_layout(pad=0)
plt.savefig('/tmp/workspace/thyroid-flashcard/thyroid_neoplasms_flashcard.png',
dpi=180, bbox_inches='tight', facecolor=BG, edgecolor='none')
print("Saved!")
plt.close()
cd /tmp/workspace/thyroid-flashcard && python create_flashcard.py 2>&1
~/thyroid-flashcard/create_flashcard_v2.py
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
from matplotlib.patches import FancyBboxPatch
import numpy as np
# ── Canvas ──────────────────────────────────────────────────────────────────
fig = plt.figure(figsize=(24, 32), facecolor='#0a0a1a')
# ── Colour palette ───────────────────────────────────────────────────────────
BG = '#0a0a1a'
PTC_C = '#1565C0'
FTC_C = '#1B5E20'
MTC_C = '#7B1FA2'
ANA_C = '#B71C1C'
BEN_C = '#E65100'
HDR_TXT = '#FFFFFF'
SUB_TXT = '#E0E0E0'
YEL = '#FFD600'
CYN = '#00E5FF'
GRN = '#69F0AE'
RED = '#FF5252'
ORA = '#FFAB40'
PNK = '#F48FB1'
WHT = '#FFFFFF'
LGR = '#B0BEC5'
DARK = '#263238'
def box(ax, x, y, w, h, color, alpha=0.85, radius=0.01):
fancy = FancyBboxPatch((x, y), w, h,
boxstyle=f"round,pad=0.003,rounding_size={radius}",
linewidth=1.0, edgecolor=color,
facecolor=color, alpha=alpha,
transform=ax.transAxes, zorder=3)
ax.add_patch(fancy)
def outline_box(ax, x, y, w, h, color, alpha=0.15, lw=1.5, radius=0.01):
fancy = FancyBboxPatch((x, y), w, h,
boxstyle=f"round,pad=0.003,rounding_size={radius}",
linewidth=lw, edgecolor=color,
facecolor=color, alpha=alpha,
transform=ax.transAxes, zorder=3)
ax.add_patch(fancy)
def hdr(ax, x, y, w, h, color, title, fs=11):
box(ax, x, y, w, h, color, alpha=0.92)
ax.text(x + w/2, y + h/2, title, transform=ax.transAxes,
ha='center', va='center', fontsize=fs, fontweight='bold',
color=WHT, zorder=5)
def txt(ax, x, y, s, color=SUB_TXT, fs=8.2, bold=False, ha='left', va='top'):
fw = 'bold' if bold else 'normal'
ax.text(x, y, s, transform=ax.transAxes,
ha=ha, va=va, fontsize=fs, color=color,
fontweight=fw, zorder=6, linespacing=1.5)
# ── Main axis ────────────────────────────────────────────────────────────────
ax = fig.add_axes([0, 0, 1, 1])
ax.set_xlim(0, 1); ax.set_ylim(0, 1)
ax.axis('off')
ax.set_facecolor(BG)
# ═══════════════════════════════════════════════════════════════════════════
# TITLE BAR
# ═══════════════════════════════════════════════════════════════════════════
box(ax, 0.01, 0.966, 0.98, 0.030, '#1a1a3e', alpha=1.0)
ax.text(0.5, 0.982, 'THYROID NEOPLASMS | HIGH-YIELD EXAM FLASHCARD',
transform=ax.transAxes, ha='center', va='center',
fontsize=16, fontweight='bold', color=YEL, zorder=8,
fontfamily='DejaVu Sans')
ax.text(0.5, 0.969, 'Classification | Mutations | Morphology | Spread | Prognosis [Robbins & Kumar Basic Pathology]',
transform=ax.transAxes, ha='center', va='center',
fontsize=8.5, color=LGR, zorder=8)
# ═══════════════════════════════════════════════════════════════════════════
# SECTION 1: Classification Banner
# ═══════════════════════════════════════════════════════════════════════════
hdr(ax, 0.01, 0.932, 0.98, 0.026, DARK, 'SECTION 1 : CLASSIFICATION OF THYROID TUMORS', fs=10)
# Benign
outline_box(ax, 0.01, 0.878, 0.185, 0.048, BEN_C, alpha=0.18)
hdr(ax, 0.01, 0.914, 0.185, 0.016, BEN_C, 'BENIGN', fs=8.5)
txt(ax, 0.018, 0.908, '* Follicular Adenoma (MC)', fs=8.0)
txt(ax, 0.018, 0.897, '* Toxic (Functioning) Adenoma', fs=8.0)
txt(ax, 0.018, 0.886, '* Hurthle Cell Adenoma', fs=8.0)
# Malignant label
hdr(ax, 0.205, 0.914, 0.785, 0.016, DARK, 'MALIGNANT', fs=8.5)
# Four type pills in a row
pill_data = [
('PAPILLARY (PTC)', '85%', PTC_C),
('FOLLICULAR (FTC)', '10%', FTC_C),
('MEDULLARY (MTC)', '5%', MTC_C),
('ANAPLASTIC', '1-2%', ANA_C),
]
for i, (label, pct, col) in enumerate(pill_data):
xi = 0.210 + i*0.193
outline_box(ax, xi, 0.879, 0.183, 0.033, col, alpha=0.90)
box(ax, xi, 0.879, 0.183, 0.033, col, alpha=0.80)
ax.text(xi + 0.0915, 0.901, label, transform=ax.transAxes,
ha='center', va='center', fontsize=8.2, fontweight='bold', color=WHT, zorder=8)
ax.text(xi + 0.0915, 0.885, pct, transform=ax.transAxes,
ha='center', va='center', fontsize=9.5, color=YEL, fontweight='bold', zorder=8)
# ═══════════════════════════════════════════════════════════════════════════
# SECTION 2: PTC + FTC side by side
# ═══════════════════════════════════════════════════════════════════════════
hdr(ax, 0.01, 0.848, 0.98, 0.023, DARK, 'SECTION 2 : CARCINOMA DETAILS', fs=10)
# ---- PTC card ----
outline_box(ax, 0.01, 0.605, 0.485, 0.238, PTC_C, alpha=0.15, lw=2.0)
hdr(ax, 0.01, 0.828, 0.485, 0.018, PTC_C, '[1] PAPILLARY THYROID CARCINOMA (PTC) | Most Common 85%', fs=9.5)
def ptc(x, y, label, val, lc=CYN, vc=SUB_TXT):
txt(ax, x, y, label, lc, fs=8.0, bold=True)
txt(ax, x+0.10, y, val, vc, fs=8.0)
ptc(0.022, 0.820, 'ORIGIN:', 'Follicular epithelium')
ptc(0.022, 0.809, 'MUTATION:', 'BRAF (40-65%) | RAS (10-30%) | RET/PTC rearrangement (10-20%) [mutually exclusive]', vc=YEL)
ptc(0.022, 0.798, 'PATHWAY:', 'MAP Kinase activation')
ptc(0.022, 0.787, 'RISK:', 'Ionizing radiation esp. childhood (Chernobyl -> children PTC surge)')
txt(ax, 0.022, 0.774, 'MORPHOLOGY HALLMARKS:', YEL, fs=8.5, bold=True)
morph_ptc = [
('*', 'Branching papillae with fibrovascular stalks', SUB_TXT),
('* [KEY]', '"Orphan Annie Eye" nuclei -> optically clear / ground-glass appearance', GRN),
('* [KEY]', 'Intranuclear pseudo-inclusions + nuclear grooves', GRN),
('* [KEY]', 'PSAMMOMA BODIES (concentric calcifications in papillae cores)', GRN),
('*', 'Lymphatic invasion common; vascular invasion UNCOMMON', SUB_TXT),
('*', 'Multifocal lesions possible; well-circumscribed or infiltrative', SUB_TXT),
]
for i, (bullet, line, col) in enumerate(morph_ptc):
txt(ax, 0.022, 0.763 - i*0.0115, bullet, ORA, fs=7.8, bold=True)
txt(ax, 0.068, 0.763 - i*0.0115, line, col, fs=7.8)
txt(ax, 0.022, 0.693, 'SPREAD:', CYN, fs=8.0, bold=True)
txt(ax, 0.098, 0.693, 'LYMPHATIC -> Cervical LN metastasis in up to 50% of cases', fs=8.0, color=CYN)
txt(ax, 0.022, 0.682, 'NOTE:', ORA, fs=8.0, bold=True)
txt(ax, 0.075, 0.682, 'Cervical LN mets do NOT significantly worsen prognosis', fs=8.0, color=ORA)
txt(ax, 0.022, 0.671, 'PRESENTATION:', CYN, fs=8.0, bold=True)
txt(ax, 0.148, 0.671, 'Painless neck mass | Cold nodule on scan | FNA -> can diagnose (nuclear features)', fs=7.8, color=SUB_TXT)
txt(ax, 0.022, 0.660, 'PROGNOSIS:', CYN, fs=8.0, bold=True)
ax.text(0.110, 0.661, '10-year survival >95% BEST PROGNOSIS (STAR)', transform=ax.transAxes,
ha='left', va='top', fontsize=9.5, fontweight='bold', color=GRN, zorder=8)
txt(ax, 0.022, 0.649, 'VARIANTS:', ORA, fs=8.0, bold=True)
txt(ax, 0.095, 0.649, 'Encapsulated follicular variant | Tall cell | Diffuse sclerosing', fs=7.8, color=SUB_TXT)
txt(ax, 0.022, 0.638, 'NIFTP:', PNK, fs=8.0, bold=True)
txt(ax, 0.078, 0.638, 'Reclassified from follicular variant PTC -> borderline (NOT carcinoma); no RAI needed', fs=7.6, color=PNK)
txt(ax, 0.022, 0.617, 'PSAMMOMA BODIES absent in FTC and MTC -- exclusive to PTC', ORA, fs=7.8, bold=True)
# ---- FTC card ----
outline_box(ax, 0.505, 0.605, 0.485, 0.238, FTC_C, alpha=0.15, lw=2.0)
hdr(ax, 0.505, 0.828, 0.485, 0.018, FTC_C, '[2] FOLLICULAR THYROID CARCINOMA (FTC) | 10%', fs=9.5)
def ftc(x, y, label, val, lc=CYN, vc=SUB_TXT):
txt(ax, x, y, label, lc, fs=8.0, bold=True)
txt(ax, x+0.10, y, val, vc, fs=8.0)
ftc(0.517, 0.820, 'ORIGIN:', 'Follicular epithelium')
ftc(0.517, 0.809, 'MUTATION:', 'RAS (MC) | PAX8-PPARG fusion t(2;3)(q13;p25) in ~50% | PIK3CA | PTEN loss', vc=YEL)
ftc(0.517, 0.798, 'PATHWAY:', 'PI3K/AKT + RAS signaling')
ftc(0.517, 0.787, 'RISK:', 'Dietary iodine deficiency / endemic goiter')
txt(ax, 0.517, 0.774, 'MORPHOLOGY HALLMARKS:', YEL, fs=8.5, bold=True)
morph_ftc = [
('*', 'Resembles follicular adenoma on gross and FNA -- CANNOT DISTINGUISH', RED),
('* [KEY]', 'CAPSULAR INVASION -> KEY diagnostic criterion', RED),
('* [KEY]', 'VASCULAR INVASION -> endovascular tumor plugs in vessel walls', RED),
('*', 'Minimal invasive: capsule breach only', SUB_TXT),
('*', 'Widely invasive: extensive vascular + tissue invasion (worse prognosis)', SUB_TXT),
('*', 'NO psammoma bodies | NO papillary nuclear features', LGR),
]
for i, (bullet, line, col) in enumerate(morph_ftc):
txt(ax, 0.517, 0.763 - i*0.0115, bullet, ORA, fs=7.8, bold=True)
txt(ax, 0.563, 0.763 - i*0.0115, line, col, fs=7.8)
ftc(0.517, 0.693, 'SPREAD:', 'HEMATOGENOUS -> Lung, Bone, Liver, Brain (cannon-ball metastases)', lc=CYN, vc=ORA)
txt(ax, 0.517, 0.682, 'NOTE:', ORA, fs=8.0, bold=True)
txt(ax, 0.572, 0.682, 'LN metastasis UNCOMMON (opposite of PTC)', ORA, fs=8.0)
ftc(0.517, 0.671, 'DIAGNOSIS:', 'Requires EXCISION + histology -- FNA is INSUFFICIENT', lc=CYN, vc=RED)
txt(ax, 0.517, 0.660, 'PROGNOSIS:', CYN, fs=8.0, bold=True)
ax.text(0.617, 0.661, '10-year survival ~85% GOOD', transform=ax.transAxes,
ha='left', va='top', fontsize=9.5, fontweight='bold', color=GRN, zorder=8)
ftc(0.517, 0.649, 'NOTE:', 'Widely invasive form -> significantly worse outcome', lc=ORA, vc=ORA)
ftc(0.517, 0.638, 'KEY POINT:', 'RAS + PIK3CA mutations shared with adenoma and anaplastic carcinoma', lc=PNK, vc=SUB_TXT)
# ═══════════════════════════════════════════════════════════════════════════
# SECTION 3: MTC + Anaplastic side by side
# ═══════════════════════════════════════════════════════════════════════════
# ---- MTC card ----
outline_box(ax, 0.01, 0.345, 0.485, 0.254, MTC_C, alpha=0.15, lw=2.0)
hdr(ax, 0.01, 0.590, 0.485, 0.018, MTC_C, '[3] MEDULLARY THYROID CARCINOMA (MTC) | 5%', fs=9.5)
txt(ax, 0.022, 0.581, 'ORIGIN:', CYN, fs=8.0, bold=True)
ax.text(0.100, 0.582, 'Parafollicular C cells [NOT follicular epithelium!]', transform=ax.transAxes,
ha='left', va='top', fontsize=8.5, fontweight='bold', color=PNK, zorder=8)
txt(ax, 0.022, 0.570, 'MUTATION:', CYN, fs=8.0, bold=True)
txt(ax, 0.100, 0.570, 'RET proto-oncogene (tyrosine kinase receptor -> constitutive activation)', YEL, fs=8.0)
# MTC type table header
txt(ax, 0.022, 0.557, 'TYPES:', YEL, fs=8.5, bold=True)
# Column headers
cx = [0.022, 0.160, 0.330]
box(ax, 0.022, 0.533, 0.465, 0.019, '#37474F', alpha=0.80)
for ci, h in enumerate(['Feature', 'Sporadic (70%)', 'Familial (30%)']):
ax.text(cx[ci] + 0.005, 0.543, h, transform=ax.transAxes,
ha='left', va='center', fontsize=8.0, fontweight='bold', color=YEL, zorder=8)
rows_m = [
['Age at Dx', '5th-6th decade', 'Younger (childhood/young adult)'],
['RET mutation','Acquired, ~50% cases', 'Germline (100% of cases)'],
['Association', 'None', 'MEN 2A | MEN 2B | FMTC'],
['Screening', 'Not required for family', 'Screen ALL family members'],
]
for ri, row in enumerate(rows_m):
bg = 0.10 if ri%2==0 else 0.04
box(ax, 0.022, 0.514 - ri*0.018, 0.465, 0.018, '#FFFFFF', alpha=bg)
for ci, cell in enumerate(row):
c = CYN if ci==0 else (ORA if 'Germline' in cell or 'MEN' in cell or 'Screen ALL' in cell else SUB_TXT)
ax.text(cx[ci]+0.005, 0.523 - ri*0.018, cell, transform=ax.transAxes,
ha='left', va='center', fontsize=7.7, color=c, zorder=8)
txt(ax, 0.022, 0.507, 'MORPHOLOGY HALLMARKS:', YEL, fs=8.5, bold=True)
morph_mtc = [
('* [KEY]', 'AMYLOID deposits in stroma -> PATHOGNOMONIC', PNK),
('*', 'Amyloid derived from calcitonin; Congo red stain -> apple-green birefringence', ORA),
('*', 'Nests / sheets of polygonal-to-spindle cells', SUB_TXT),
('*', 'Salt-and-pepper nuclear chromatin (neuroendocrine pattern)', SUB_TXT),
('*', 'Calcitonin granules in cytoplasm', SUB_TXT),
]
for i, (bullet, line, col) in enumerate(morph_mtc):
txt(ax, 0.022, 0.497 - i*0.0115, bullet, ORA, fs=7.8, bold=True)
txt(ax, 0.068, 0.497 - i*0.0115, line, col, fs=7.8)
txt(ax, 0.022, 0.433, 'TUMOUR MARKERS:', CYN, fs=8.0, bold=True)
ax.text(0.163, 0.434, 'CALCITONIN + CEA (both elevated)', transform=ax.transAxes,
ha='left', va='top', fontsize=10, fontweight='bold', color=PNK, zorder=8)
txt(ax, 0.022, 0.422, 'SPREAD:', CYN, fs=8.0, bold=True)
txt(ax, 0.094, 0.422, 'Lymphatic + Hematogenous (both routes)', SUB_TXT, fs=8.0)
txt(ax, 0.022, 0.411, 'FEATURES:', CYN, fs=8.0, bold=True)
txt(ax, 0.106, 0.411, 'Neck mass | Diarrhea (calcitonin/VIP) | Flushing', SUB_TXT, fs=8.0)
txt(ax, 0.022, 0.400, 'MEN 2A:', ORA, fs=8.0, bold=True)
txt(ax, 0.087, 0.400, 'MTC + Phaeochromocytoma + Hyperparathyroidism', SUB_TXT, fs=8.0)
txt(ax, 0.022, 0.389, 'MEN 2B:', ORA, fs=8.0, bold=True)
txt(ax, 0.087, 0.389, 'MTC + Phaeochromocytoma + Mucosal neuromas + Marfanoid habitus', SUB_TXT, fs=8.0)
txt(ax, 0.022, 0.378, 'PROGNOSIS:', CYN, fs=8.0, bold=True)
ax.text(0.118, 0.379, '10-yr survival ~50-65% INTERMEDIATE', transform=ax.transAxes,
ha='left', va='top', fontsize=9, fontweight='bold', color=ORA, zorder=8)
txt(ax, 0.022, 0.359, 'Germline RET mutation -> familial type -> SCREEN ALL FIRST-DEGREE RELATIVES', RED, fs=8.0, bold=True)
# ---- Anaplastic card ----
outline_box(ax, 0.505, 0.345, 0.485, 0.254, ANA_C, alpha=0.15, lw=2.0)
hdr(ax, 0.505, 0.590, 0.485, 0.018, ANA_C, '[4] ANAPLASTIC THYROID CARCINOMA | MOST LETHAL', fs=9.5)
txt(ax, 0.517, 0.581, 'ORIGIN:', CYN, fs=8.0, bold=True)
txt(ax, 0.598, 0.581, 'Follicular epithelium (de novo OR dedifferentiation from PTC/FTC)', SUB_TXT, fs=8.0)
txt(ax, 0.517, 0.570, 'MUTATION:', CYN, fs=8.0, bold=True)
ax.text(0.598, 0.571, 'TP53 loss [MOST SPECIFIC] + RAS + PIK3CA (accumulate on top of PTC/FTC mutations)', transform=ax.transAxes,
ha='left', va='top', fontsize=8.0, color=RED, zorder=8)
txt(ax, 0.517, 0.559, 'AGE:', CYN, fs=8.0, bold=True)
txt(ax, 0.565, 0.559, 'Usually >65 years (oldest age group)', SUB_TXT, fs=8.0)
txt(ax, 0.517, 0.548, 'PATHWAY:', CYN, fs=8.0, bold=True)
txt(ax, 0.598, 0.548, 'Stepwise dedifferentiation -> PTC/FTC -> Anaplastic', SUB_TXT, fs=8.0)
txt(ax, 0.517, 0.535, 'MORPHOLOGY HALLMARKS:', YEL, fs=8.5, bold=True)
morph_ana = [
('* [KEY]', 'Highly pleomorphic, undifferentiated cells', RED),
('*', 'Abundant mitoses + extensive necrosis', RED),
('*', 'Three patterns: Spindle cell / Giant cell / Small cell', SUB_TXT),
('*', 'Rapidly invasive -- trachea, vessels, nerves, esophagus', RED),
('*', 'Often arises in background of differentiated carcinoma', SUB_TXT),
]
for i, (bullet, line, col) in enumerate(morph_ana):
txt(ax, 0.517, 0.524 - i*0.0115, bullet, ORA, fs=7.8, bold=True)
txt(ax, 0.563, 0.524 - i*0.0115, line, col, fs=7.8)
txt(ax, 0.517, 0.462, 'PRESENTATION:', CYN, fs=8.0, bold=True)
ax.text(0.640, 0.463, 'RAPIDLY enlarging FIXED neck mass (days to weeks)', transform=ax.transAxes,
ha='left', va='top', fontsize=8.5, fontweight='bold', color=RED, zorder=8)
txt(ax, 0.517, 0.451, 'SYMPTOMS:', CYN, fs=8.0, bold=True)
txt(ax, 0.603, 0.451, 'Dysphagia | Hoarseness | Stridor | SVC syndrome', SUB_TXT, fs=8.0)
txt(ax, 0.517, 0.440, 'STAGING:', CYN, fs=8.0, bold=True)
ax.text(0.590, 0.441, 'ALL anaplastic = STAGE IV at diagnosis (by definition)', transform=ax.transAxes,
ha='left', va='top', fontsize=8.5, fontweight='bold', color=RED, zorder=8)
txt(ax, 0.517, 0.429, 'PROGNOSIS:', CYN, fs=8.0, bold=True)
ax.text(0.617, 0.430, 'Median survival = 6 months | <5% 5-yr | WORST', transform=ax.transAxes,
ha='left', va='top', fontsize=10, fontweight='bold', color=RED, zorder=8)
txt(ax, 0.517, 0.418, 'TREATMENT:', CYN, fs=8.0, bold=True)
txt(ax, 0.607, 0.418, 'BRAF-mutant: Dabrafenib + Trametinib (targeted therapy)', SUB_TXT, fs=8.0)
txt(ax, 0.517, 0.407, 'KEY NOTE:', ORA, fs=8.0, bold=True)
txt(ax, 0.607, 0.407, 'Urgently compresses trachea -> surgical emergency may be needed', SUB_TXT, fs=8.0)
txt(ax, 0.517, 0.396, 'PATHOGENESIS:', CYN, fs=8.0, bold=True)
txt(ax, 0.641, 0.396, 'Shared mutations with well-differentiated carcinomas (RAS, PIK3CA) + TP53 added = anaplastic', SUB_TXT, fs=7.8)
txt(ax, 0.517, 0.360, 'TP53 loss drives the conversion from differentiated to undifferentiated carcinoma', RED, fs=8.0, bold=True)
# ═══════════════════════════════════════════════════════════════════════════
# SECTION 4: Master Comparison Table
# ═══════════════════════════════════════════════════════════════════════════
hdr(ax, 0.01, 0.315, 0.98, 0.023, DARK, 'SECTION 3 : MASTER COMPARISON TABLE', fs=10)
cols = ['Feature', 'Papillary (85%)', 'Follicular (10%)', 'Medullary (5%)', 'Anaplastic (1-2%)']
col_x2 = [0.013, 0.205, 0.393, 0.581, 0.769]
col_colors = [DARK, PTC_C, FTC_C, MTC_C, ANA_C]
col_w = [0.190, 0.186, 0.186, 0.186, 0.218]
for ci, (h, cx, cw, cc) in enumerate(zip(cols, col_x2, col_w, col_colors)):
box(ax, cx, 0.293, cw, 0.020, cc, alpha=0.88)
ax.text(cx + cw/2, 0.303, h, transform=ax.transAxes,
ha='center', va='center', fontsize=8.3, fontweight='bold', color=WHT, zorder=8)
rows_cmp = [
['Origin', 'Follicular epi', 'Follicular epi', 'C cells [KEY]', 'Follicular epi'],
['Key Mutation', 'BRAF [KEY]', 'RAS + PAX8-PPARG[KEY]','RET [KEY]', 'TP53 [KEY]'],
['Spread', 'LYMPHATIC [KEY]', 'HEMATOGENOUS [KEY]', 'Both', 'Direct invasion'],
['Psammoma bodies', 'YES [KEY]', 'NO', 'NO', 'NO'],
['Amyloid stroma', 'NO', 'NO', 'YES [KEY]', 'NO'],
['Tumour marker', 'None specific', 'None specific', 'Calcitonin + CEA[KEY]','None specific'],
['FNA diagnosis', 'YES (nuclear feat.)', 'CANNOT dx (capsule)', 'Suggestive', 'YES'],
['10-yr survival', '>95% BEST', '~85% Good', '50-65% Intermed.', '<5% WORST'],
['Prognosis rank', '1st (best)', '2nd', '3rd', '4th (worst)'],
]
row_h2 = 0.025
row_y_start = 0.289
for ri, row in enumerate(rows_cmp):
bg_alpha = 0.10 if ri%2==0 else 0.04
box(ax, 0.013, row_y_start - (ri+1)*row_h2, 0.974, row_h2, '#FFFFFF', alpha=bg_alpha)
for ci, (cell, cx, cw) in enumerate(zip(row, col_x2, col_w)):
special = {
('BRAF [KEY]', 1): YEL, ('RAS + PAX8-PPARG[KEY]', 2): YEL,
('RET [KEY]', 3): YEL, ('TP53 [KEY]', 4): YEL,
('LYMPHATIC [KEY]', 1): CYN, ('HEMATOGENOUS [KEY]', 2): ORA,
('YES [KEY]', 1): GRN, ('YES [KEY]', 3): PNK,
('Calcitonin + CEA[KEY]', 3): PNK,
('>95% BEST', 1): GRN, ('~85% Good', 2): GRN,
('50-65% Intermed.', 3): ORA, ('<5% WORST', 4): RED,
('C cells [KEY]', 3): PNK, ('CANNOT dx (capsule)', 2): RED,
('1st (best)', 1): GRN, ('2nd', 2): GRN,
('3rd', 3): ORA, ('4th (worst)', 4): RED,
}
c = special.get((cell, ci), SUB_TXT if ci > 0 else CYN)
fw = 'bold' if ci == 0 or '[KEY]' in cell or 'BEST' in cell or 'WORST' in cell else 'normal'
ax.text(cx + 0.006, row_y_start - (ri+1)*row_h2 + row_h2/2,
cell, transform=ax.transAxes,
ha='left', va='center', fontsize=7.7, color=c, fontweight=fw, zorder=8)
# ═══════════════════════════════════════════════════════════════════════════
# SECTION 5: Three bottom boxes
# ═══════════════════════════════════════════════════════════════════════════
bot_top = row_y_start - (len(rows_cmp)+1)*row_h2 - 0.010
box_h = 0.105
# Box A: Adenoma vs Carcinoma
outline_box(ax, 0.01, bot_top, 0.315, box_h, BEN_C, alpha=0.18, lw=1.5)
hdr(ax, 0.01, bot_top + box_h - 0.018, 0.315, 0.018, BEN_C, 'ADENOMA vs CARCINOMA', fs=8.8)
a_rows = [
('Capsule:', 'Intact, complete (Adenoma)', 'BREACHED (Carcinoma) [KEY]'),
('Vasc. invasion:', 'Absent (Adenoma)', 'Present (Carcinoma) [KEY]'),
('FNA:', 'CANNOT DISTINGUISH either [KEY]', ''),
('Diagnosis:', 'Histology after EXCISION + capsule evaluation', ''),
('Prognosis:', 'Adenoma = excellent (no recurrence)', ''),
]
for i, (label, v1, v2) in enumerate(a_rows):
txt(ax, 0.020, bot_top + box_h - 0.025 - i*0.015, label, CYN, fs=7.7, bold=True)
c = RED if '[KEY]' in v1 else SUB_TXT
txt(ax, 0.110, bot_top + box_h - 0.025 - i*0.015, v1, c, fs=7.6)
# Box B: Risk Factors
outline_box(ax, 0.335, bot_top, 0.315, box_h, '#1a237e', alpha=0.20, lw=1.5)
hdr(ax, 0.335, bot_top + box_h - 0.018, 0.315, 0.018, '#3949AB', 'RISK FACTORS PER TYPE', fs=8.8)
rf = [
('PTC:', 'Ionizing radiation (esp. childhood)', PTC_C),
('FTC:', 'Iodine deficiency / endemic goiter', FTC_C),
('MTC:', 'RET germline mutation | MEN 2', MTC_C),
('Anaplastic:', 'Dedifferentiation from PTC or FTC', ANA_C),
('Cold nodule:', '10% risk of malignancy -> FNA needed', ORA),
]
for i, (label, val, c) in enumerate(rf):
txt(ax, 0.345, bot_top + box_h - 0.025 - i*0.015, label, c, fs=7.8, bold=True)
txt(ax, 0.410, bot_top + box_h - 0.025 - i*0.015, val, SUB_TXT, fs=7.7)
# Box C: Exam Must Knows
outline_box(ax, 0.660, bot_top, 0.330, box_h, '#F57F17', alpha=0.15, lw=1.5)
hdr(ax, 0.660, bot_top + box_h - 0.018, 0.330, 0.018, '#F57F17', 'EXAM MUST-KNOWS [HIGH YIELD]', fs=8.8)
tips = [
('Orphan Annie nuclei + Psammoma bodies = PTC', YEL),
('Capsular/vascular invasion = FTC (not adenoma)', YEL),
('Amyloid stroma + Calcitonin = MTC', YEL),
('Fastest growing + worst prognosis = Anaplastic (TP53)', YEL),
('FNA cannot diagnose FTC (need excision)', RED),
('RET germline -> screen family for MTC', ORA),
('BRAF=PTC | RAS=FTC | RET=MTC | TP53=Anaplastic', PNK),
]
for i, (t, c) in enumerate(tips):
txt(ax, 0.668, bot_top + box_h - 0.025 - i*0.013, t, c, fs=7.6)
# ═══════════════════════════════════════════════════════════════════════════
# Footer
# ═══════════════════════════════════════════════════════════════════════════
ax.text(0.5, 0.006, 'Source: Robbins & Kumar Basic Pathology | For exam revision only | All rights reserved.',
transform=ax.transAxes, ha='center', va='bottom',
fontsize=7.5, color='#546E7A', style='italic', zorder=8)
# Subtle left border stripe per section
for y, c in [(0.605, PTC_C), (0.605, FTC_C), (0.345, MTC_C), (0.345, ANA_C)]:
pass # already handled by outline_box
plt.savefig('/tmp/workspace/thyroid-flashcard/thyroid_neoplasms_flashcard.png',
dpi=180, bbox_inches='tight', facecolor=BG, edgecolor='none',
pad_inches=0.15)
print("Done!")
plt.close()
cd /tmp/workspace/thyroid-flashcard && python create_flashcard_v2.py 2>&1
ls -lh /tmp/workspace/thyroid-flashcard/thyroid_neoplasms_flashcard.png && python3 -c "from PIL import Image; img = Image.open('/tmp/workspace/thyroid-flashcard/thyroid_neoplasms_flashcard.png'); print('Size:', img.size, 'Mode:', img.mode)"
thyroid neoplasms flashcard
Image · PNG
| Section | Content |
|---|---|
| Section 1 | Full classification - Benign vs Malignant, all 4 types with % frequency |
| Section 2 | PTC + FTC detailed cards - origin, mutations, morphology hallmarks, spread, prognosis |
| Section 3 | MTC + Anaplastic detailed cards - including MEN 2A vs 2B table, TP53, staging |
| Section 4 | Master comparison table - all 4 carcinomas vs 9 features side by side |
| Section 5 | Adenoma vs Carcinoma |
[KEY] tags mark the single most examiner-favorite fact in each row