graphing

작성자: anthropic

표 형식 데이터에서 차트킷 기본 요소를 사용하여 정제된 차트(시계열, 막대, 선, 영역, 원형, 산점도 또는 데이터에 적합한 기타 모든 유형)를 구성합니다.

npx skills add https://github.com/anthropics/claude-tag-plugins --skill graphing

Graphing

You write the plotting code. The kit provides the parts that should stay consistent across every chart: typography, color derivation from the background, the title and caption frame, and offline HTML packaging. Everything about the chart itself is your judgement applied to the data in front of you.

The primitives

Import chartkit by putting this skill's scripts/ directory on sys.path. Use its absolute path, not a relative path, since your working directory is the user's project. The examples below write it as /path/to/graphing/scripts; substitute the real path.

Relevant primitives:

  • theme(bg, font): sets matplotlib rcParams and returns resolved colors. Foreground colors derive from background luminance, so a dark bg produces a correct dark chart. Fields: bg dark text muted grid spine accent secondary series font_css.
  • palette(n, base): n colors. No base cycles the default series, a hex base builds a ramp from it, a list cycles the list.
  • finish(ax, title, subtitle, source): The typographic frame. Left-aligned bold title, muted subtitle, small provenance caption.
  • save(fig, stem, formats, dpi): Writes stem.png, stem.svg, or both. Returns the paths.
  • write_html(out, data, component_js, title, bg, font): Self-contained interactive page. Inlines React, ReactDOM, react-is, and Recharts from third_party/ so the file opens offline. Your component reads window.__CHART_DATA__ and renders into #root.
  • zero_fill_days(pairs) rolling_mean(values, w) log_floor(values): Small data helpers for the gotchas listed below. Use them only when they fit.

Steps

  1. Look at the data and decide what it deserves. Shape, count, and meaning drive the choice: trends over time want lines or day bars, ranked categories want horizontal bars, parts of a whole with few slices can be a pie, correlation wants a scatter. Nothing limits you to those: stacked areas, dual axes, small multiples, annotated thresholds are all just code you write.

  2. Infer colors from context. Check your conversation and memory for design indicators: a tailwind config, CSS variables, or brand guidelines, and consider the semantic meaning of the data (red or amber for errors, green for success). Pass the destination background to theme(bg=...) and brand colors to palette(base=...) or directly. Fall back to the defaults only when nothing is inferable. The font defaults to Inter and only changes when the user names a typeface or the destination has a documented brand font.

  3. Write a short script in your scratchpad that imports chartkit, builds the figure with plain matplotlib (or a Recharts component for interactive output), calls finish, and saves.

  4. Render and look at the result. Read the PNG back and check it with your own eyes before handing it over: labels legible, nothing overlapping, colors distinguishable, the story of the data actually visible. Fix and re-render until it is right.

The shape of a chart script

PNG or SVG via matplotlib:

import sys
sys.path.insert(0, "/path/to/graphing/scripts")
import chartkit as ck
import matplotlib.pyplot as plt

c = ck.theme()                       # or theme(bg="#0f1419") for a dark surface
fig, ax = plt.subplots(figsize=(10, 5))
# ...plain matplotlib against the data, using c.accent, c.secondary, ck.palette(...)
ck.finish(ax, title="What the chart shows", subtitle="scope or time range",
          source="source: where the data came from, date")
print(ck.save(fig, "out/report", formats=("png", "svg")))

Interactive HTML via Recharts, written as plain React.createElement with no JSX and no build step:

component = """
(function () {
  var e = React.createElement
  var R = window.Recharts
  var DATA = window.__CHART_DATA__
  function App() {
    return e(R.ResponsiveContainer, { width: "100%", height: 420 },
      e(R.LineChart, { data: DATA },
        e(R.CartesianGrid, { stroke: "GRID", vertical: false }),
        e(R.XAxis, { dataKey: "x" }), e(R.YAxis, null),
        e(R.Tooltip, null),
        e(R.Line, { dataKey: "y", stroke: "ACCENT", strokeWidth: 2.4,
                    dot: false, isAnimationActive: false })))
  }
  ReactDOM.createRoot(document.getElementById("root")).render(e(App))
})()
"""
ck.write_html("out/report.html", data, component, title="What the chart shows")

Substitute real colors from the theme into the component and keep isAnimationActive: false so the chart is complete the moment the file opens.

Judgement, not flags

These are the defaults of good charts. Deviate when the data argues for it.

  • Rotate x labels only when they would otherwise collide. Short labels stay horizontal.
  • Cap bar width when there are few categories. Two bars should not fill the canvas edge to edge.
  • Label bars with their values when there are roughly a dozen or fewer. Axes and gridlines are for reading trends, not exact values.
  • Rank categorical bars by value unless the categories have a natural order.
  • Long category names read better on a horizontal bar chart.
  • A title states what the chart shows. A subtitle carries the time range or scope. The source caption says where the data came from and when. Skip any of them only deliberately.
  • Legends only when there is more than one series. A single series is named by the title.
  • Annotate the chart with what matters: a deploy line, a threshold, the peak, the anomaly the user asked about. An annotation the reader did not need is clutter.

Gotchas the helpers exist for

  • Calendar gaps: a timeseries with missing days misleads on a continuous axis. zero_fill_days fills them with zero. Skip it when zeros would be the lie (sparse sampling rather than absence of events).
  • Rolling averages: rolling_mean is trailing, early points average what exists so far. Do not center it on data that ends today.
  • Log scales: bars whose value equals the axis minimum get zero height. log_floor gives a lower bound one decade down.
  • Negative values: matplotlib handles them, but check the y limits include them and add a zero line when bars go both ways. Recharts y domains default to starting at zero, so pass an explicit domain on the YAxis when data is negative or log scaled.

Verification

Run a minimal render and look at it.

python3 -c "
import sys
sys.path.insert(0, '/path/to/graphing/scripts')
import chartkit as ck
import matplotlib.pyplot as plt
c = ck.theme()
fig, ax = plt.subplots(figsize=(8, 4))
ax.bar(['A', 'B', 'C'], [10, 30, 20], color=c.accent, width=0.5)
ck.finish(ax, title='chartkit smoke test')
print(ck.save(fig, '/tmp/ck_smoke'))
"

Confirm a non-empty PNG is written, then read it back and check it renders correctly.

anthropic의 다른 스킬

access
anthropic
Discord 채널 접근을 관리합니다 — 페어링 승인, 허용 목록 편집, DM/그룹 정책 설정. 사용자가 페어링 요청, 승인, 허용된 사람 확인 등을 요청할 때 사용합니다.
official
session-report
anthropic
~/.claude/projects 트랜스크립트에서 Claude Code 세션 사용량(토큰, 캐시, 하위 에이전트, 스킬, 고비용 프롬프트)에 대한 탐색 가능한 HTML 보고서를 생성합니다.
official
build-mcp-server
anthropic
이 스킬은 사용자가 "MCP 서버 구축", "MCP 생성", "MCP 통합 만들기", "Claude용 API 래핑", "도구 노출" 등을 요청할 때 사용해야 합니다.
official
cookbook-audit
anthropic
Anthropic Cookbook 노트북을 루브릭에 따라 감사합니다. 노트북 리뷰나 감사가 요청될 때마다 사용하세요.
official
handle-complaint
anthropic
들어오는 고객 불만을 처음부터 끝까지 처리합니다 — 맥락을 파악하고, 응답을 작성하며, 운영상의 수정을 제안합니다. 선택적으로 이메일이나 티켓 ID를 받습니다…
official
use-case-triage
anthropic
처리 활동이 PIA, 필수 GDPR DPIA가 필요한지 또는 진행 가능한지 신속히 판단하여 개인정보 처리방침 충돌을 표시하고 적절한 경로로 안내합니다…
official
board-minutes
anthropic
이사회 또는 위원회 회의록을 사내 형식으로 작성합니다. 캘린더에서 예정된 이사회 및 위원회 회의를 자동으로 감지하고, 안건을 요청한 후…
official
renewal-tracker
anthropic
유지 관리되는 갱신 등록부를 기반으로 취소 마감일이 다가오는 계약을 표시하고 통지 기간이 종료되기 전에 경고합니다. 사용자가 요청할 때 사용합니다.
official