sim-plot: Matplotlib Visualization
SkillDev toolsVisualize Virtuoso simulation results as matplotlib charts. Use after: (1) sim sweep — line plot of measurements vs swept variable, (2) sim corner — grouped bar chart across PVT corners, (3) sim measure — horizontal bar of scalar measurements, (4) AC/Bode plot from PSF getData results (magnitude + phase), (5) process_data lookup tables — gm/Id curves for all L values. Auto-detects chart type from JSON structure. Saves PNG via plot_sim.py.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the sim-plot: Matplotlib Visualization skill
What this skill tells your AI
The instructions your AI receives, as published by deanyou/virtuoso-cli in .agents/skills/sim-plot/SKILL.md and read by ahel’s review.
Pipe --format json output into plot_sim.py to get charts. The script
lives at .Codex/skills/sim-plot/scripts/plot_sim.py.
Usage by Chart Type
1. Parameter Sweep → Line Plot
virtuoso sim sweep \
--var W34 --from 2e-6 --to 24e-6 --step 4e-6 \
--analysis dc \
--expr 'openResults("/tmp/opt/psf") selectResult('"'"'acSweep) dB20(value(VF("net1") 1))' \
--format json | \
python3 .Codex/skills/sim-plot/scripts/plot_sim.py \
--output plots/w34_sweep.png \
--title "5T OTA: Gain vs W34"
Or save JSON first then plot:
virtuoso sim sweep ... --format json > /tmp/sweep.json
python3 .Codex/skills/sim-plot/scripts/plot_sim.py \
--input /tmp/sweep.json --output plots/sweep.png
Expected JSON structure:
{
"variable": "W34",
"headers": ["W34", "gain_dB", "gbw_hz"],
"data": [
{"W34": "2e-06", "gain_dB": "9.9", "gbw_hz": "9e5"},
{"W34": "8e-06", "gain_dB": "42.3", "gbw_hz": "1.14e7"}
]
}
2. Corner Analysis → Grouped Bar Chart
virtuoso sim corner --file corners.json --format json | \
python3 .Codex/skills/sim-plot/scripts/plot_sim.py \
--output plots/corner.png --title "PVT Corner Results"
Expected JSON structure:
{
"corners": 3,
"headers": ["corner", "temp", "gain_dB", "gbw_hz"],
"data": [
{"corner": "tt", "temp": "27", "gain_dB": "43.2", "gbw_hz": "1.15e7"},
{"corner": "ff", "temp": "27", "gain_dB": "40.1", "gbw_hz": "1.4e7"},
{"corner": "ss", "temp": "27", "gain_dB": "45.8", "gbw_hz": "9.2e6"}
]
}
3. Scalar Measurements → Horizontal Bar Chart
virtuoso sim measure --analysis dcOp \
--expr 'getData("I0.NM0:gm" ?result "dcOpInfo")' \
--expr 'getData("I0.NM0:gds" ?result "dcOpInfo")' \
--format json | \
python3 .Codex/skills/sim-plot/scripts/plot_sim.py \
--output plots/oppoint.png
4. AC Bode Plot
The AC PSF data must be converted to the Bode JSON format first. Use Ocean
getData to extract frequency, magnitude, and phase:
# Step 1: Get frequency and output data from PSF
virtuoso skill exec '
openResults("/tmp/opt_5t_ota/psf")
selectResult('"'"'acSweep)
RB__vout = VF("net1")
RB__freq = frequency(RB__vout)
RB__mag = dB20(RB__vout)
RB__ph = phase(RB__vout)
list(
sprintf(nil "%s" RB__freq)
sprintf(nil "%s" RB__mag)
sprintf(nil "%s" RB__ph)
)
' --format json > /tmp/ac_raw.json
# Step 2: Codex converts to Bode JSON format and plots
# (Codex writes a small Python conversion + call)
Bode JSON format accepted by plot_sim.py:
{
"freq": [1, 10, 100, 1000, 10000, 100000, 1000000, 10000000],
"mag_db": [43.2, 43.2, 43.1, 42.8, 40.0, 30.0, 20.0, 0.1],
"phase_deg": [-1, -5, -10, -30, -60, -120, -160, -178]
}
The plot shows:
- Top: Magnitude vs frequency (dB), marks GBW (0 dB crossing)
- Bottom: Phase vs frequency (°), marks phase margin at GBW
5. gm/Id Lookup Table → Transistor Curves
python3 .Codex/skills/sim-plot/scripts/plot_sim.py \
--input process_data/smic13mmrf/nmos_lookup.json \
--output plots/nmos_gmid.png \
--title "NMOS gm/Id Lookup (SMIC 0.13µm)"
Produces 4 subplots:
- Gain (dB) vs gm/Id for each L
- fT (GHz) vs gm/Id
- Id (µA/µm) vs gm/Id (linear)
- Id (µA/µm) vs gm/Id (log)
Common Workflows
After a W-sweep optimization run
# Already have the data from this session's 5T OTA sweep:
echo '{
"status": "success",
"variable": "W34",
"headers": ["W34", "gain_dB", "gbw_hz", "gm_uS", "gmId"],
"data": [
{"W34": "2e-06", "gain_dB": "9.9", "gbw_hz": "9e5", "gm_uS": "174", "gmId": "7.0"},
{"W34": "4e-06", "gain_dB": "36.0", "gbw_hz": "1.08e7","gm_uS": "366", "gmId": "11.8"},
{"W34": "8e-06", "gain_dB": "42.3", "gbw_hz": "1.14e7","gm_uS": "371", "gmId": "11.9"},
{"W34": "16e-06","gain_dB": "43.2", "gbw_hz": "1.15e7","gm_uS": "372", "gmId": "11.9"},
{"W34": "24e-06","gain_dB": "43.3", "gbw_hz": "1.14e7","gm_uS": "372", "gmId": "11.9"}
]
}' | python3 .Codex/skills/sim-plot/scripts/plot_sim.py \
--output plots/5t_ota_w34.png --title "5T OTA: Gain & GBW vs W34 (PMOS load)"
After process char
python3 .Codex/skills/sim-plot/scripts/plot_sim.py \
--input process_data/smic13mmrf/nmos_lookup.json \
--output plots/nmos_char.png
Script Location
.Codex/skills/sim-plot/scripts/plot_sim.py
Requirements: Python 3.8+, matplotlib, numpy
Check: python3 -c "import matplotlib, numpy; print('OK')"
Install if missing:
pip install matplotlib numpy
Output
- Saves PNG to
--outputpath (default:sim_plot.pngin current dir) - Prints:
Chart saved: /path/to/output.png - DPI: 150 by default (
--dpi 300for publication quality)
Signals
- GitHub stars
- 32
- Forks
- 10
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
sim-plot- Source
- github.com/deanyou/virtuoso-cli