Generate professional circuit diagrams using schemdraw Python library. Creates vector graphics (SVG/PDF/PNG) from natural language descriptions. Components: resistors, capacitors, inductors, diodes, transistors, opamps, ICs, logic gates, etc. Use when: (1) User requests circuit diagrams or schematics, (2) User wants publication-quality output, (3) User needs SVG/PDF for documentation, (4) Complex circuits with ICs/opamps/digital logic, (5) User mentions schemdraw or wants alternative to ASCII circuits.
Generate professional circuit diagrams using schemdraw Python library. Creates vector graphics (SVG/PDF/PNG) from natural language descriptions. Components: resistors, capacitors, inductors, diodes, transistors, opamps, ICs, logic gates, etc. Use when: (1) User requests circuit diagrams or schematics, (2) User wants publication-quality output, (3) User needs SVG/PDF for documentation, (4) Complex circuits with ICs/opamps/digital logic, (5) User mentions schemdraw or wants alternative to ASCII circuits.
Schemdraw Circuit Generator
Generate professional, publication-quality circuit diagrams using schemdraw Python library. Outputs to vector formats (SVG, PDF) or raster (PNG).
This workflow builds diagrams step-by-step with visual confirmation at each stage. Use this for complex circuits or when starting fresh.
A. Connection List - Write explicit connection list showing all component pins
B. Incremental Build Loop - Build one component/section at a time:
Add ONE component or connection (e.g., "IC only", "add GND connection", "add R1")
Execute - Run Python script and save SVG
Visual Check - Generate screenshot via HTML wrapper + headless browser
User Confirmation - Show screenshot, get approval before proceeding
REPEAT - Go back to step 1 for next component until circuit complete
Why this works:
Catches issues immediately when they occur
Easy to debug single changes
User can guide spacing, positioning, and layout decisions
Prevents compound errors that are hard to untangle
C. Final Verification - Once all components added:
Generate final screenshot
Trace each connection from Step A connection list
Verify all component values, labels, pin numbers present
D. Complete - Deliver connection list AND final diagram
⚡ ALTERNATIVE: All-at-Once Approach(Only for simple circuits or experienced users)
Use this workflow ONLY when:
Circuit is simple (< 5 components)
You have high confidence in layout
User explicitly requests complete diagram in one shot
A. Connection List - Write explicit connection list showing all component pins
B. Generate Complete Code - Create schemdraw code implementing ALL connections
C. Execute - Run Python script and save SVG
D. Visual Verification (MANDATORY) - Perform comprehensive visual assessment
Generate screenshot via HTML wrapper + headless browser
LIST ALL PROBLEMS FIRST (don't fix one-by-one - you'll forget issues!)
Apply ALL fixes at once
Confirm with fresh screenshot
REPEAT until all problems resolved
E. Final Confirmation - Trace each signal path from connection list
If violations found: Return to B with fixes
If clean: Proceed to F
F. Complete - Deliver both connection list AND diagram
⚠️ Warning: All-at-once approach often requires multiple fix iterations for complex circuits. Incremental approach is more reliable.
Visual Verification Checklist (MANDATORY)
🚨 CRITICAL REALITY: Only Human Visual Feedback is Reliable
AI visual assessment is NOT reliable for layout verification. AI may report "all connections traceable" while humans see obvious layout problems. Therefore:
✅ Generate screenshots for HUMAN review - Always provide visual output
✅ Wait for human feedback - Don't make assumptions about visual quality
❌ Don't trust AI visual verification - It misses layout issues humans easily spot
❌ Don't claim "complete" without user confirmation - User must see and approve
The Human-Driven Verification Loop
This is like HTML+CSS development - requires human eyes to judge visual quality.
GENERATE SCREENSHOT - Create visual output for user to review
SHOW TO USER - Present screenshot and ask for feedback
LISTEN TO HUMAN FEEDBACK - User will identify spacing, overlap, or clarity issues
FIX BASED ON USER INPUT - Apply changes user requests
REPEAT - Generate new screenshot, show to user, iterate until approved
Key insight: Users see layout problems AI cannot detect. Trust human feedback over AI assessment.
Visual Verification Categories
1. Connection Visibility Test
"Technically connected" ≠ "Visually connected"
For each connection in your connection list:
✅ Can you visually TRACE the line end-to-end?
✅ Are junction dots visible at split points?
❌ Are lines overlapping IC edges? (Human can't see the connection!)
❌ Are lines hidden behind component bodies?
❌ Are connection points ambiguous?
Common failure: Line connects to IC pin at the edge of the IC box → looks disconnected even though code is correct.
Fix: Route connections AWAY from IC edges using Manhattan routing:
# ❌ WRONG - line touches IC edge, invisible
elm.Line().at(junction).to(ic.PIN)
# ✅ CORRECT - route away from edge first
elm.Line().at(junction).down(0.5)
elm.Line().left(SMALL_SPACING) # Clear the IC edge
elm.Dot()
elm.Line().down(0.5)
elm.Dot()
elm.Line().right(SMALL_SPACING + 1.0) # Now visible approaching pin
2. Label Overlap Detection
🚨 CRITICAL RULE: Labels must NEVER overlap component symbols
Common overlap zones:
Labels on component symbols - ❌ FORBIDDEN (e.g., "10kΩ" text on resistor zigzag)
Adjacent components on same signal path (R1 ↔ R2)
IC center label ↔ pin labels (IC name ↔ VOUT)
Component labels ↔ value labels
Labels ↔ junction dots or lines
Visual test questions:
❌ Is label text sitting ON TOP of component symbol? (resistor, capacitor, inductor)
❌ Are any characters touching between different labels?
❌ Is label text crowded or cramped?
✅ Can you clearly read each label independently?
✅ Can you see the complete component symbol without text obscuring it?
Fix priority order:
First: Increase spacing - Most effective, cleanest solution
HORIZONTAL_SPACING = 1.5# Increase from 1.0
VERTICAL_SPACING = 1.5# Increase from 1.0
SMALL_SPACING = 0.75# Increase from 0.5
Second: Adjust label position - Change loc parameter
# R1/R2 overlap example:
elm.Resistor().label('R1\n10kΩ', loc='top', ofst=0.2) # Push up
elm.Resistor().label('R2\n1kΩ', loc='left') # Move to opposite side
Third: Reduce font size - Only if spacing isn't feasible
.label('U2\nLM2596S', fontsize=10) # Reduce from 11
Fourth: Add offset - Fine-tune position
.label('IC', ofst=-0.3) # Shift left by 0.3 units
3. Line Overlap Detection
🚨 CRITICAL RULE: Lines touching IC edges = Connection ambiguity
Problem areas:
Lines touching/overlapping IC box edges - ❌ FORBIDDEN ("Is this connected?" - impossible to tell!)
Lines crossing component bodies
Lines crossing other lines without junction
Lines crossing ground symbols
Fix rules:
NEVER use .to(ic.PIN) directly - creates line touching IC edge
Use .at() to position connections explicitly
Use Manhattan routing (horizontal → vertical → horizontal only)
Add intermediate junction dots to clarify path
Route around component bodies, not through them
Leave visible gap between IC edge and incoming lines
Example - Correct IC connection:
# ❌ WRONG - line touches IC edge
elm.Line().at(junction).to(ic.VIN)
# ✅ CORRECT - visible gap before IC edge
elm.Line().at(junction).right(1.0) # Stop BEFORE IC edge# IC connects from current position automatically
4. Definition of "Complete"
A diagram is complete ONLY when:
✅ Code executes without errors
✅ SVG generates successfully
✅ USER has visually reviewed screenshot and approved (MOST IMPORTANT)
✅ USER confirms all connections are traceable
✅ USER confirms no visual issues (overlaps, spacing, clarity)
✅ Every item from connection list is verified in diagram
🚨 CRITICAL: Never claim "complete" without explicit user approval of visual output!
AI cannot reliably assess visual quality. Only human confirmation counts.
Screenshot Generation for USER Review
Purpose: Generate visual output for HUMAN evaluation, not AI assessment.
Use HTML wrapper + headless browser to create screenshots for user review. The headless-browser skill is an external dependency (installed from Takazudo/zudo-test-wisdom — not part of this repo). If it isn't installed, degrade gracefully with a warning instead of failing the whole workflow:
IC connects via sequential flow - current position flows to first left pin automatically
Use .at(ic.pinname) to start FROM a specific pin
Use .at(junction) BEFORE routing TO a pin to avoid edge overlap
Pin names are anchors: ic.VIN, ic.GND, ic.FB, ic.VOUT
Example of proper IC connection:
# Create junction BEFORE IC
elm.Dot()
pre_ic_junction = d.here
# IC connects automatically from current position (sequential flow)
ic = elm.Ic(pins=[...])
# Route from junction to IC pin explicitly
elm.Line().at(pre_ic_junction).down(1.0)
elm.Dot()
elm.Line().right(1.0) # Now connects to IC.PIN visibly
Using Context7 for Documentation
CRITICAL: Schemdraw has extensive features. When you need specific syntax, advanced features, or uncommon components, use context7:
mcp__context7__get-library-docs(
context7CompatibleLibraryID: "/cdelker/schemdraw",
mode: "code",
topic: "your specific topic"
)
When to use context7:
Uncommon components not in references/components.md
Advanced features (custom elements, annotations, etc.)
import schemdraw
from schemdraw import elements as elm
with schemdraw.Drawing(file='output.svg') as d:
elm.Resistor().label('1kΩ')
elm.Capacitor().down().label('10µF')
Element Chaining
Elements chain sequentially, each picking up where last ended:
elm.Resistor().right().label('R1') # Goes right
elm.Capacitor().down().label('C1') # Goes down from R1's end
elm.Line().left() # Goes left from C1's end
1. Consistent Label Positioning for Vertical Components
Problem: Labels on vertical components (resistors, capacitors going up/down) need consistent positioning to avoid overlaps and maintain professional appearance.
Solution: Use loc='bot', ofst=0.5 pattern for all vertical components:
# For components going upward
elm.Capacitor().up(2.0).label('C3\n470µF\n25V', loc='bot', ofst=0.5)
elm.Ground().flip() # Flipped ground at top# For components going downward
elm.Resistor().down().label('R1\n10kΩ', loc='bot', ofst=0.5)
elm.Resistor().down().label('R2\n1kΩ', loc='bot', ofst=0.5)
elm.Ground() # Normal ground at bottom
Why this works:loc='bot' anchors label at component's bottom reference point, ofst=0.5 shifts it right, positioning label cleanly on the right side of the component body without overlapping the symbol or connection lines.
2. IC Edge Padding for Label Clearance
Problem: IC center label (e.g., "U2 LM2596S") overlaps with pin labels on the right side.
Solution: Use adequate edgepadW parameter instead of label offsets:
Why this works: Widening the IC box is cleaner than using label offsets. Typical values: edgepadW=2.5 for ICs with 5+ pins.
3. Precise Junction Positioning
Problem: Need junction at exact midpoint for symmetrical connections.
Solution: Calculate position mathematically:
# For horizontal rail between two pins
junction_y = (ic.VIN[1] + ic.ON[1]) / 2# Build entire rail at calculated height
elm.Dot(open=True).at((x_position, junction_y)).label('+15V', loc='left')
elm.Line().right(2.0)
elm.Dot()
# ... all elements at same Y coordinate
Why this works: Calculating exact coordinates ensures straight lines and symmetrical layout. No diagonal connections or misaligned junctions.
4. Proper Push/Pop Stack Management
Problem: Multiple branches require careful stack management to return to correct positions.
Solution: Track push/pop pairs systematically:
elm.Dot()
junction1 = d.here
d.push() # Save junction1# Branch 1
elm.Line().right(1.0)
elm.Dot()
junction2 = d.here
d.push() # Save junction2# Branch 2
elm.Line().right(1.0)
elm.Dot(open=True)
# Return to junction2
d.pop() # Now at junction2# Continue from junction2
elm.Line().down(0.5)
elm.Resistor()...
# Return to junction1
d.pop() # Now at junction1
Rule: Every d.push() must have a matching d.pop(). Stack structure: LIFO (Last In, First Out).
5. Ground Symbol Orientation
Problem: Ground symbols appear upside-down when components go upward.
Solution: Use .flip() for upward-facing components:
# Component going UP - flip ground
elm.Capacitor().up(2.0)
elm.Ground().flip() # Ground symbol at top, points down# Component going DOWN - normal ground
elm.Resistor().down()
elm.Ground() # Ground symbol at bottom, points down
Rule: Ground always "points down" toward earth. Flip when it's physically above the component.
6. User Correction Responsiveness
Problem: User says "NO!" or expresses frustration - you misunderstood the request.
Solution:
STOP immediately - Don't continue with wrong approach
Re-read user's EXACT words - What did they literally say?
Use exact parameters specified - "right side" means loc='right', not loc='left'
Show result immediately - Generate screenshot, don't assume it's correct
Wait for confirmation - Let user verify before proceeding
Example from session:
User: "the RIGHT side of the capacitor symbol"
Wrong: loc='left' (causes "NO!!!")
Correct: loc='right' (what they literally requested)
7. Spacing Adjustments
Problem: User requests specific spacing changes during build.
Solution: Be responsive to spacing requests:
# User: "halve the line there"
elm.Line().right(1.0) # Changed from 2.0# User: "change distance 1 -> 0.5 for each line"
elm.Line().down(0.5) # Changed from 1.0
elm.Resistor()...
elm.Line().down(0.5) # All spacing changed consistently
Why this matters: Small spacing adjustments (0.5 vs 1.0) significantly impact readability and label overlap prevention.
Quick Tips
Black foreground with transparent background - Always use font='Arial', color='black', transparent=True for web documentation
Start simple - Use patterns from patterns.md as starting point
Query context7 - For components/features not in references
Save references - Assign elements to variables: Q1 = elm.BjtNpn()
Use dots - Always at T-junctions, open dots for terminals
Check anchors - Use correct anchor names for element type
Manhattan routing - Use .toy() and .tox() for clean lines
Increase spacing - d.config(unit=3) if too cramped
SVG format - Best for documentation (vector, scalable)
Consistent labels - Use loc='bot', ofst=0.5 for vertical components
Listen carefully - When user corrects you, use their EXACT words
Output Formats
# SVG (recommended - vector, scalable)with schemdraw.Drawing(
file='circuit.svg',
font='Arial',
fontsize=11,
color='black',
transparent=True
) as d:
d.config(unit=3)
# ... components ...# PNG (raster, for compatibility)# Note: Generate SVG first, then save as PNG
d.save('circuit.png', dpi=300, transparent=True)
# PDF (for print)with schemdraw.Drawing(
file='circuit.pdf',
font='Arial',
fontsize=11,
color='black',
transparent=True
) as d:
d.config(unit=3)
# ... components ...
Black Foreground with Transparent Background (Default)
All diagrams should use black foreground with transparent background by default:
with schemdraw.Drawing(
font='Arial', # Sans-serif font
fontsize=11,
color='black', # Black foreground
transparent=True# Transparent background
) as d:
d.config(unit=3)
# ... components ...
Why transparent background with black foreground:
Allows HTML container background to show through (e.g., custom background colors)
Black lines and text are visible on light container backgrounds
Works seamlessly with web-based documentation (Docusaurus, etc.)
Professional appearance with clean contrast
Integrates with any light-themed documentation
Solid background (if specifically requested):
# Dark theme with solid black background and white foregroundwith schemdraw.Drawing(
font='Arial',
fontsize=11,
color='white',
bgcolor='black'
) as d:
# ... components ...# Light theme with solid white background and black foregroundwith schemdraw.Drawing(
font='Arial',
fontsize=11,
color='black',
bgcolor='white'
) as d:
# ... components ...
Example: Simple Voltage Divider
import schemdraw
from schemdraw import elements as elm
# Black foreground with transparent background (default)with schemdraw.Drawing(
file='voltage_divider.svg',
font='Arial',
fontsize=11,
color='black',
transparent=True
) as d:
elm.SourceV().label('12V')
elm.Line().right(d.unit/2)
elm.Resistor().down().label('R1\n10kΩ')
elm.Dot()
d.push()
elm.Line().right(d.unit/2).dot(open=True).label('Vout\n(6V)', 'right')
d.pop()
elm.Resistor().down().label('R2\n10kΩ')
elm.Ground()
When to Use This Skill
User requests circuit diagrams or schematics
Publication-quality output needed
Vector graphics (SVG/PDF) for documentation
Complex circuits with ICs, opamps, logic
Alternative to ASCII art diagrams
Technical papers or presentations
When NOT to Use
User specifically wants ASCII art (use ascii-circuit-diagram-creator instead)