Viz
by robdmc
Data visualization and inspection skill. Use when user asks to plot, chart, graph, or visualize data from files or marimo notebooks. Also use for DataFrame inspection when user wants to "show", "display", or "see" data structure (columns, dtypes, first N rows). Supports matplotlib/seaborn for plots, marimo notebook extraction, and artifact management in .viz/.
Skill Details
Repository Files
9 files in this skill directory
name: viz description: Data visualization and inspection skill. Use when user asks to plot, chart, graph, or visualize data from files or marimo notebooks. Also use for DataFrame inspection when user wants to "show", "display", or "see" data structure (columns, dtypes, first N rows). Supports matplotlib/seaborn for plots, marimo notebook extraction, and artifact management in .viz/. allowed-tools: Read, Write(.viz/_draft.py), Glob(.viz/), Grep(.viz/), Bash(rm -f .viz/_draft.py), Bash(python {SKILL_DIR}/scripts/viz_runner.py:*), Bash(uv run --directory {SKILL_DIR}/scripts python *), Bash(open *)
Viz Skill: Data Visualization and Inspection
CRITICAL: Never use heredocs (
<< 'EOF') to pass scripts to viz_runner.py. Always use the Write tool to create.viz/_draft.py, then pass--file .viz/_draft.pyto the runner.
Contents
- Purpose
- Input Specification
- Intent Detection
- Artifact Management
- Skill Workflow
- Refinement and Regeneration
- Marimo Notebook Support (see references/marimo.md)
- Library Selection and Styling (see references/styling.md)
Purpose
This skill directly executes visualizations. The calling agent provides a visualization spec along with data context, and the skill:
- Infers the data loading code from the provided context
- Generates the complete plotting script
- Executes it via the
viz_runner.pyhelper - Returns artifact paths for the caller to reference
Key pattern:
Caller (with data context) → Skill (infers data loading, generates script, executes) → Plot appears
Input Specification
Required
- Visualization spec: What to plot (chart type, axes, title, special features)
Data Context (one of these forms)
- Database + query: "Data from
/full/path/to/data.ddb, tableforecast, columns month, members" - SQL query: "Run this SQL:
SELECT * FROM forecast WHERE year >= 2024" - Code snippet: "Load data like this:
df = pd.read_parquet('/full/path/to/data.parquet')" - File path: "CSV at
/tmp/data.csvwith columns X, Y, Z"
CRITICAL: Absolute Paths Required — Scripts execute from .viz/, not the caller's directory. All file paths must be absolute.
Optional
- Suggested ID: A name hint (e.g.,
pop_bar,churn_trend). The runner ensures uniqueness.
Intent Detection
Before generating any code, analyze the user's request to determine the appropriate mode.
Inspection Mode (use --show)
Use when the user wants to see the data itself, not a visualization:
- "Show me the dataframe"
- "Display the first N rows"
- "What does the data look like?"
- "What columns are in X?"
Action: Use --show flag. Do NOT generate plot code.
Visualization Mode (generate plot)
Use when the user wants a chart, graph, or visual representation:
- "Plot the data"
- "Create a chart of..."
- "Visualize the trend"
- "Bar chart showing..."
Action: Generate matplotlib/seaborn code, write to temp file, execute via runner.
Ambiguous Requests
If unclear (e.g., "show me X over time"):
- If the request mentions chart types (bar, line, scatter) → visualization
- If the request is about structure/columns/rows → inspection
- When in doubt, use
--showfirst (it's cheaper), then offer to plot
Existing Plot References
If user references a plot by ID (e.g., "regenerate pop_bar", "modify the cosine_wave plot"):
- Check if
.viz/<id>.pyexists - If yes, read the script and follow the Refinement and Regeneration workflow
- If no, inform user the plot wasn't found and offer to list available plots with
--list
Action: python {SKILL_DIR}/scripts/viz_runner.py --list shows all available plots.
View Mode (open images)
Use when the user wants to see existing plot images:
- "Show me all my plots"
- "Open the images" / "View what I've created"
- "Let me see the sine_wave plot"
- "Compare plot1 and plot2"
- "Show me the recent plots"
Selecting which images to open:
-
Explicit ID reference: User names a plot → open that specific PNG
- "open the sine_wave" →
open -a Preview .viz/sine_wave.png
- "open the sine_wave" →
-
Recent context: User just created a plot or discussed one → open that one
- After generating
forecast_chart: "let me see it" →open -a Preview .viz/forecast_chart.png
- After generating
-
All plots: User asks for everything or uses plural without specifics
- "show me my plots" / "open all images" →
open -a Preview .viz/*.png
- "show me my plots" / "open all images" →
-
Subset by pattern: User describes a category or pattern
- "show me the forecast plots" → use
--listto find matching IDs, then open those
- "show me the forecast plots" → use
-
Comparison: User wants to compare specific plots
- "compare X and Y" →
open -a Preview .viz/X.png .viz/Y.png
- "compare X and Y" →
-
Ambiguous: When unclear which plot(s) the user means
- Run
--listfirst, then ask or infer from context
- Run
Action: Use open -a Preview to open PNG files. Use --list first if needed to identify which plots exist.
Artifact Management
All artifacts are managed in .viz/ via the helper script.
Helper: viz_runner.py
python {SKILL_DIR}/scripts/viz_runner.py --file .viz/_draft.py --id NAME --desc "Description"
The runner:
- Creates
.viz/if needed and adds it to.gitignore - Ensures ID uniqueness (appends
_2,_3, etc. if collision) - Injects
plt.savefig('.viz/<id>.png', dpi=150, bbox_inches='tight')beforeplt.show() - Writes the script to
.viz/<id>.py - Executes the script
- Writes metadata to
.viz/<id>.json
Output Format
Terminal output:
Plot: pop_bar
"Bar chart of members by month"
png: .viz/pop_bar.png
List and Cleanup
python {SKILL_DIR}/scripts/viz_runner.py --list # Show all visualizations
python {SKILL_DIR}/scripts/viz_runner.py --clean # Remove all files
Viewing Plots
Open plots in Preview (macOS):
open -a Preview .viz/*.png # All plots
open -a Preview .viz/my_plot.png # Single plot
open -a Preview .viz/plot1.png .viz/plot2.png # Multiple specific plots
Skill Workflow
CRITICAL: Do NOT use heredocs (<< 'EOF'). Use the temp file pattern:
- Infer data loading: Generate Python code to load/create the DataFrame using absolute paths
- Generate visualization: Add matplotlib/seaborn code for the requested plot
- Write to temp file: Run
rm -f .viz/_draft.pyfirst, then use the Write tool to create.viz/_draft.pywith the complete script - Execute via runner:
The runner reads the temp file, deletes it, then writes the final script topython {SKILL_DIR}/scripts/viz_runner.py --file .viz/_draft.py --id suggested_name --desc "Short description".viz/<id>.py. - Return to caller: Report final ID and paths
Example Tool Sequence
1. Bash tool → rm -f .viz/_draft.py (delete stale draft if present)
2. Write tool → .viz/_draft.py (complete Python script)
3. Bash tool → python viz_runner.py --file .viz/_draft.py --id my_plot --desc "..."
Why no heredocs? Heredocs clutter the console output and require extra permissions. The temp file pattern is cleaner.
Important: Do NOT Auto-Read PNGs
Do NOT automatically read the PNG into context after generating a plot. The plot window opens via plt.show(), so the user can already see it.
Only read the PNG when:
- The user explicitly asks you to analyze the graph
- You need to learn something from the visual output
Instead, offer to open it:
open -a Preview .viz/pop_bar.png # Single plot (macOS)
open -a Preview .viz/*.png # All plots
ID Watermarks
Plots include a small, semi-transparent watermark showing the plot ID in the bottom-right corner by default. This helps track plots during iterative development.
Disabling Watermarks
Add --no-watermark for clean/production versions:
python {SKILL_DIR}/scripts/viz_runner.py --file .viz/_draft.py --id my_plot --no-watermark
When to Disable Watermarks
Recognize these user requests as triggers for --no-watermark:
- "clean version" / "clean copy"
- "for presentation" / "presentation quality"
- "production ready" / "final version"
- "no watermark" / "without ID"
- "export quality"
Refinement and Regeneration
Refining an Existing Plot
- Read the existing script from
.viz/<id>.py - Apply modifications
- Execute with a new ID (e.g.,
pop_bar_2)
Regenerating a Plot
To regenerate while preserving the original:
- Read the existing script from
.viz/<id>.py - Write to temp file and execute via runner with the same ID:
rm -f .viz/_draft.py # Write script content to .viz/_draft.py python {SKILL_DIR}/scripts/viz_runner.py --file .viz/_draft.py --id pop_bar --desc "Regenerated"
The runner's get_unique_id() will automatically create pop_bar_2, pop_bar_3, etc. if the ID exists, preserving the original.
Marimo Notebook Support
For extracting and plotting data from marimo notebooks, see references/marimo.md.
Key features:
- Extract variables via AST-based dependency analysis
- Prune notebooks to only required cells
--showmode for data inspection--target-linefor capturing intermediate state
Library Selection and Styling
For guidance on choosing between matplotlib/seaborn and publication quality standards, see references/styling.md.
Related Skills
Xlsx
Comprehensive spreadsheet creation, editing, and analysis with support for formulas, formatting, data analysis, and visualization. When Claude needs to work with spreadsheets (.xlsx, .xlsm, .csv, .tsv, etc) for: (1) Creating new spreadsheets with formulas and formatting, (2) Reading or analyzing data, (3) Modify existing spreadsheets while preserving formulas, (4) Data analysis and visualization in spreadsheets, or (5) Recalculating formulas
Clickhouse Io
ClickHouse database patterns, query optimization, analytics, and data engineering best practices for high-performance analytical workloads.
Clickhouse Io
ClickHouse database patterns, query optimization, analytics, and data engineering best practices for high-performance analytical workloads.
Analyzing Financial Statements
This skill calculates key financial ratios and metrics from financial statement data for investment analysis
Data Storytelling
Transform data into compelling narratives using visualization, context, and persuasive structure. Use when presenting analytics to stakeholders, creating data reports, or building executive presentations.
Team Composition Analysis
This skill should be used when the user asks to "plan team structure", "determine hiring needs", "design org chart", "calculate compensation", "plan equity allocation", or requests organizational design and headcount planning for a startup.
Startup Financial Modeling
This skill should be used when the user asks to "create financial projections", "build a financial model", "forecast revenue", "calculate burn rate", "estimate runway", "model cash flow", or requests 3-5 year financial planning for a startup.
Kpi Dashboard Design
Design effective KPI dashboards with metrics selection, visualization best practices, and real-time monitoring patterns. Use when building business dashboards, selecting metrics, or designing data visualization layouts.
Dbt Transformation Patterns
Master dbt (data build tool) for analytics engineering with model organization, testing, documentation, and incremental strategies. Use when building data transformations, creating data models, or implementing analytics engineering best practices.
Startup Metrics Framework
This skill should be used when the user asks about "key startup metrics", "SaaS metrics", "CAC and LTV", "unit economics", "burn multiple", "rule of 40", "marketplace metrics", or requests guidance on tracking and optimizing business performance metrics.
