how this skill actually works

You don't invoke dataviz by name. It loads automatically whenever Claude Code is about to write chart, graph, or dashboard code — an HTML artifact, inline SVG, a matplotlib/plotly/d3 script, a chart shared into Slack — the same way a skill for a specific framework loads when you're editing that framework's files. The difference it makes is concrete, not just theoretical — same prompt, same data, same "chart new signups by acquisition channel," two different outcomes:
Email Organic Paid social Referral
Email
54%
Organic
38%
Paid social
92%
Referral
71%
✗ A typical unguided result — a legend restating a single series, a different hardcoded hue per bar doing no identity work, categories left in whatever order they were typed, and colors that won't budge in dark mode because they were never tied to the page's own theme.
Paid social
Referral
Email
Organic
✓ What dataviz produces for the identical request — one hue pulled from the page's own accent color (so it themes correctly), sorted by value, nothing left for the reader to decode.
That's the whole value proposition in one comparison: the left chart isn't wrong, exactly — it's just what happens when nothing is enforcing a decision at each step. The skill exists so every chart Claude produces gets the right side by default, not just the ones you happen to review closely. Under the hood, Claude works through a fixed procedure instead of improvising:
  1. Pick the form. What job is the data doing — magnitude, identity, polarity, a single headline number? Sometimes the honest answer is "not a chart."
  2. Assign color by that job — categorical, sequential, diverging, or status — never picked first, never picked by eye.
  3. Validate the palette. This is the step that's easy to skip and easiest to get wrong by hand: instead of reasoning about whether two hues "look different enough," the skill runs a real contrast/colorblind-safety check against the pair and rejects anything that fails, rather than trusting a guess.
  4. Apply the mark specs — bar thickness, rounded data-ends, the gap and ring spacers, sparing labels.
  5. Add the hover layer by default, since an HTML/SVG chart is interactive unless there's a specific reason it shouldn't be.
  6. Run a final accessibility pass — legend rules, a non-visual fallback, dark mode as its own pass.
  7. Render it and actually look at it before calling it done — the earlier steps check color and spec, not whether labels collide or something overflows.
For the signups chart above: step 1 decided "single measure, magnitude" before any markup existed, which is what ruled out a color per bar in step 2. Steps 3 and 6 are the ones a plain prompt won't get by asking generically for "a nice chart" — they need to actually be true of the request, not just implied:
  • Say what the data's job is, or let it infer. "Chart X by Y" is enough — naming the comparison ("compare," "over time," "vs a target") helps it pick the form faster, but isn't required.
  • Ask for what step 6 doesn't do automatically in every context. "Make this colorblind-safe," "add a table view," "check this in dark mode" — these get applied more deliberately when named, instead of only the default pass.
  • Avoid "make it colorful" or "use bright colors." That phrasing directly fights step 2 — color is assigned by the job the data needs done, not by how vivid the reader wants it to look. If a chart genuinely needs more visual weight, ask for that on the marks (thicker bars, a stronger accent) instead.
  • Push back on a specific step if something's off, rather than asking to "redo it" — "the legend's redundant, drop it" or "these two colors are too close" targets the actual step that needs a second pass.
That's the whole skill — a fixed procedure so the decisions above get made the same way every time, instead of being reinvented per chart.

related topics

Claude Skills — what a skill is, and how dataviz fits alongside the others Claude Code ships with.
Agents & Subagents — the other main way to specialize Claude for a task.
Hooks & Automation — automation that runs on every matching event, rather than only when explicitly invoked.