Claude-skills charting

Select the right Python charting library (seaborn, matplotlib, graphviz) and produce publication-quality static visualizations. Use when creating charts, plots, graphs, diagrams, heatmaps, visualizations from data, or when choosing between matplotlib/seaborn/graphviz. Also triggers for network diagrams, flowcharts, dependency trees, state machines, and entity-relationship diagrams. For interactive browser-rendered charts or uploaded data exploration, defer to charting-vega-lite instead.

install
source · Clone the upstream repo
git clone https://github.com/oaustegard/claude-skills
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/oaustegard/claude-skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/charting" ~/.claude/skills/oaustegard-claude-skills-charting && rm -rf "$T"
manifest: charting/SKILL.md
source content

Charting: Python Static Visualizations

Select the optimal Python charting library and produce clean, publication-quality output.

Library Selection Framework

Choose the library based on what the visualization represents, not habit.

Seaborn — DEFAULT for statistical/analytical charts

Seaborn wraps matplotlib with better defaults, tighter pandas integration, and fewer lines of code. Reach for seaborn first when the data lives in a DataFrame and the goal is analytical.

Use for: distributions (histograms, KDEs, violin plots, ECDFs), categorical comparisons (box plots, swarm plots, strip plots, bar plots), correlation (heatmaps, pair plots, regression plots), grouped/faceted views (

FacetGrid
,
catplot
,
relplot
).

Why: Automatic axis labeling from column names, coherent color palettes, built-in aggregation with confidence intervals, and

hue
/
col
/
row
faceting with minimal code.

Practical rule: If the code would call

plt.bar()
,
plt.hist()
,
plt.scatter()
, or build a heatmap with
plt.imshow()
— use the seaborn equivalent instead. It will look better with less effort.

Matplotlib — fine-grained control and non-standard layouts

Drop to raw matplotlib only when seaborn doesn't support the chart type or when pixel-level layout control is required.

Use for: custom multi-panel figures mixing chart types, unusual annotations (arrows, shaded regions, custom legends), non-standard axes (polar, broken axes, insets), animations, image overlays, or any layout where the default seaborn API is insufficient.

Combine with seaborn: Seaborn plots return matplotlib

Axes
objects. Apply matplotlib customization on top of seaborn output rather than rebuilding from scratch.

Graphviz — graph/network structures

Graphviz operates in a fundamentally different domain: nodes and edges, not x/y data.

Use for: dependency trees, flowcharts, state machines, org charts, entity-relationship diagrams, DAGs, call graphs, any directed or undirected graph structure.

Python interface: Use the

graphviz
Python package (installed). Create
graphviz.Digraph()
or
graphviz.Graph()
, add nodes/edges, render to PNG/SVG/PDF.

import graphviz
g = graphviz.Digraph(format='png')
g.node('A', 'Start')
g.node('B', 'Process')
g.edge('A', 'B')
g.render('/home/claude/output', cleanup=True)

Layout engines:

dot
(hierarchical, default),
neato
(spring model),
fdp
(force-directed),
circo
(circular),
twopi
(radial). Set via
g.engine = 'neato'
.

Vega-Lite — interactive browser charts

When the user wants interactive, browser-rendered visualizations (tooltips, zoom, selection, filtering) or uploads data for exploratory charting, defer to the

charting-vega-lite
skill. That skill handles React artifact generation with inline data islands.

Decision shortcut: Static image file → this skill. Interactive artifact → charting-vega-lite.

Quick Reference: Chart Type → Library

NeedLibraryFunction
Histogram / KDEseaborn
sns.histplot()
,
sns.kdeplot()
Box / Violin / Swarmseaborn
sns.boxplot()
,
sns.violinplot()
Bar (categorical)seaborn
sns.barplot()
,
sns.countplot()
Correlation heatmapseaborn
sns.heatmap()
Scatter + regressionseaborn
sns.scatterplot()
,
sns.regplot()
Pair plot (multi-var)seaborn
sns.pairplot()
Faceted gridseaborn
sns.FacetGrid
,
catplot
,
relplot
Time series lineseaborn
sns.lineplot()
(handles CI bands)
Custom multi-panelmatplotlib
fig, axes = plt.subplots()
Polar / radarmatplotlib
projection='polar'
Annotated diagramsmatplotlib
ax.annotate()
, arrows, patches
Dependency treegraphviz
Digraph
Flowchart / FSMgraphviz
Digraph
with shape attrs
ER diagramgraphviz
Graph
with record shapes
Network graphgraphviz
Graph
with layout engine

Production Defaults

Apply these defaults to produce clean output without per-chart fiddling.

Seaborn Setup

import seaborn as sns
import matplotlib.pyplot as plt

sns.set_theme(style="whitegrid", palette="muted", font_scale=1.1)

Style options:

whitegrid
(default, good for most),
white
(cleaner for publications),
darkgrid
(data-dense plots),
ticks
(minimal).

Figure Sizing and DPI

fig, ax = plt.subplots(figsize=(10, 6))
# Or for seaborn figure-level functions:
g = sns.catplot(..., height=6, aspect=1.5)

# Save at publication quality
plt.savefig('/home/claude/chart.png', dpi=150, bbox_inches='tight', facecolor='white')

Use

dpi=150
for screen/web output,
dpi=300
for print. Always use
bbox_inches='tight'
to avoid clipped labels.

Color Guidance

  • Categorical:
    "muted"
    ,
    "Set2"
    ,
    "tab10"
    — distinct, accessible
  • Sequential:
    "viridis"
    ,
    "YlOrRd"
    ,
    "Blues"
    — ordered magnitude
  • Diverging:
    "RdBu"
    ,
    "coolwarm"
    — centered on zero/midpoint
  • Avoid:
    "jet"
    ,
    "rainbow"
    — perceptually non-uniform, colorblind-hostile

Common Refinements

# Rotate x-labels if overlapping
plt.xticks(rotation=45, ha='right')

# Remove top/right spines for cleaner look
sns.despine()

# Thousands separator for large numbers
ax.yaxis.set_major_formatter(plt.FuncFormatter(lambda x, _: f'{x:,.0f}'))

Output Workflow

  1. Create chart in
    /home/claude/
  2. Save as PNG (default) or SVG (if user needs vector)
  3. Copy to
    /mnt/user-data/outputs/
  4. Present via
    present_files

Always

plt.close()
after saving to free memory.