- name
- tufte-data-visualization
- description
- Generate Tufte-compliant charts and visualizations following principles from Edward Tufte's foundational books on data visualization
- triggers
- ["make a chart","create a visualization","design a dashboard","apply Tufte principles","improve this chart","what chart should I use","visualize this data","create a data visualization"]
# Tufte Data Visualization Skill
> Skill by [ara.so](https://ara.so) — Claude Code Skills collection.
A Claude Code skill that transforms chart requests into Tufte-compliant visualizations distilled from Edward R. Tufte's three foundational books: *The Visual Display of Quantitative Information*, *Envisioning Information*, and *Visual Explanations*.
## Installation
```bash
git clone https://github.com/aref-vc/tufte-claude-skill.git ~/.claude/skills/tufte
```
The skill auto-loads on Claude Code's next launch. Verify with `/tufte` or by asking Claude to "make a chart."
Update:
```bash
cd ~/.claude/skills/tufte && git pull
```
Uninstall:
```bash
rm -rf ~/.claude/skills/tufte
```
## Core Principles
The skill applies ten principles from Tufte's work:
1. **Show the data** — every decision asks "does this help see the data?"
2. **Maximize data-ink ratio** — ink that changes when data changes is data-ink
3. **Erase non-data-ink** — remove frame boxes, gridlines, minor ticks
4. **Erase redundant data-ink** — one encoding per quantity
5. **Graphical integrity** — lie factor 0.95-1.05, bars start at zero
6. **Small multiples** — N charts on shared scale vs. one chart with N lines
7. **Layering and separation** — data on top, labels next, scaffolding faintest
8. **Micro/macro readings** — readable from afar and up close
9. **Smallest effective difference** — subtle distinctions, gray + one accent
10. **Word-data integration** — sparklines in sentences, numbers near visuals
## Chart Selection
The skill picks chart types based on your data structure and goal:
| Data shape | Goal | Chart type |
|------------|------|------------|
| 1 value over time | Show trend | Sparkline |
| 5-20 categories | Compare | Dot plot (sorted) |
| 20+ categories | Compare | Table with inline sparklines |
| Two time periods | Show change | Slopegraph |
| Part-to-whole | Show composition | Sorted table with % bars |
| Time series, multiple | Compare trends | Small multiples |
| Distribution | Show spread | Strip plot or quantile dot plot |
| Funnel/steps | Show drop-off | Horizontal bars (% of start) |
| Geographic | Show regional patterns | Choropleth (sequential single-hue) |
| Cohort/grid | Show patterns | Table with values + sequential color |
## Usage Patterns
### Basic Chart Generation
```javascript
// Request: "Make a chart of monthly revenue for the last 12 months"
// Output: Self-contained HTML with inline SVG sparkline
<!DOCTYPE html>
<html>
<head>
<style>
body { font-family: "Gill Sans", sans-serif; margin: 40px; }
.sparkline { display: inline-block; vertical-align: middle; margin: 0 8px; }
</style>
</head>
<body>
<div>
<span style="font-size: 32px; font-weight: 600;">$847K</span>
<svg class="sparkline" width="120" height="30" viewBox="0 0 120 30">
<polyline
points="0,20 10,18 20,15 30,16 40,14 50,12 60,10 70,8 80,9 90,6 100,4 110,2"
fill="none"
stroke="#555"
stroke-width="1.5"
/>
<circle cx="0" cy="20" r="2" fill="#555" />
<circle cx="110" cy="2" r="2" fill="#555" />
</svg>
<span style="color: #999; font-size: 14px;">Jan $620K → Dec $847K</span>
</div>
</body>
</html>
```
### Dot Plot for Category Comparison
```html
<!-- Request: "Compare sales by product category" -->
<svg width="600" height="300" viewBox="0 0 600 300">
<!-- Sorted by value, highest first -->
<text x="10" y="30" font-size="14" fill="#333">Electronics</text>
<circle cx="450" cy="26" r="4" fill="#333" />
<text x="460" y="30" font-size="12" fill="#666">$2.4M</text>
<text x="10" y="60" font-size="14" fill="#333">Furniture</text>
<circle cx="380" cy="56" r="4" fill="#333" />
<text x="390" y="60" font-size="12" fill="#666">$1.8M</text>
<text x="10" y="90" font-size="14" fill="#333">Office Supplies</text>
<circle cx="320" cy="86" r="4" fill="#333" />
<text x="330" y="90" font-size="12" fill="#666">$1.3M</text>
<!-- Light reference line at max -->
<line x1="150" y1="0" x2="150" y2="300" stroke="#e0e0e0" stroke-width="1" />
</svg>
```
### Small Multiples for Time Series
```javascript
// Request: "Show revenue trend by region"
// Output: React component with Recharts
import { LineChart, Line, ResponsiveContainer } from 'recharts';
const data = {
North: [12, 15, 14, 18, 20, 22, 24, 26, 25, 28, 30, 32],
South: [8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
East: [15, 16, 14, 15, 17, 18, 20, 22, 21, 23, 25, 27],
West: [10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21]
};
export default function RegionalTrends() {
return (
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '20px' }}>
{Object.entries(data).map(([region, values]) => (
<div key={region}>
<div style={{ fontSize: '18px', fontWeight: 600, marginBottom: '8px' }}>
{region}: ${values[values.length - 1]}K
</div>
<ResponsiveContainer width="100%" height={80}>
<LineChart data={values.map((v, i) => ({ value: v }))}>
<Line
type="monotone"
dataKey="value"
stroke="#555"
strokeWidth={1.5}
dot={false}
/>
</LineChart>
</ResponsiveContainer>
</div>
))}
</div>
);
}
```
### Slopegraph for Period Comparison
```html
<!-- Request: "Compare Q2 vs Q3 revenue by team" -->
<svg width="400" height="300" viewBox="0 0 400 300">
<!-- Left labels (Q2) -->
<text x="10" y="50" font-size="13" fill="#666">Q2</text>
<text x="10" y="30" font-size="14" fill="#333">Sales: $120K</text>
<text x="10" y="80" font-size="14" fill="#333">Marketing: $95K</text>
<text x="10" y="130" font-size="14" fill="#333">Product: $85K</text>
<text x="10" y="180" font-size="14" fill="#333">Support: $60K</text>
<!-- Right labels (Q3) -->
<text x="390" y="50" font-size="13" fill="#666" text-anchor="end">Q3</text>
<text x="390" y="20" font-size="14" fill="#d73027" text-anchor="end">Sales: $145K</text>
<text x="390" y="70" font-size="14" fill="#333" text-anchor="end">Marketing: $110K</text>
<text x="390" y="120" font-size="14" fill="#333" text-anchor="end">Product: $98K</text>
<text x="390" y="170" font-size="14" fill="#333" text-anchor="end">Support: $68K</text>
<!-- Lines connecting periods (steepest in accent color) -->
<line x1="140" y1="30" x2="250" y2="20" stroke="#d73027" stroke-width="2" />
<line x1="140" y1="80" x2="250" y2="70" stroke="#999" stroke-width="1" />
<line x1="140" y1="130" x2="250" y2="120" stroke="#999" stroke-width="1" />
<line x1="140" y1="180" x2="250" y2="170" stroke="#999" stroke-width="1" />
</svg>
```
### Dashboard with KPI Table
```html
<!-- Request: "Build a dashboard for four key metrics" -->
<!DOCTYPE html>
<html>
<head>
<style>
table { border-collapse: collapse; font-family: "Gill Sans", sans-serif; }
th { text-align: left; font-weight: 600; font-size: 13px;
color: #666; padding: 8px 12px; border-bottom: 1px solid #ddd; }
td { padding: 8px 12px; font-size: 14px; }
.metric { font-weight: 600; font-size: 18px; }
.delta { font-size: 13px; color: #666; }
.alert { color: #d73027; }
</style>
</head>
<body>
<table>
<thead>
<tr>
<th>Metric</th>
<th>Current</th>
<th>10-month trend</th>
<th>vs Target</th>
</tr>
</thead>
<tbody>
<tr>
<td>Revenue</td>
<td class="metric">$2.4M</td>
<td>
<svg width="80" height="20">
<polyline points="0,15 8,14 16,12 24,13 32,11 40,9 48,8 56,6 64,7 72,4"
fill="none" stroke="#555" stroke-width="1.5" />
</svg>
</td>
<td class="delta">+8%</td>
</tr>
<tr>
<td>Active Users</td>
<td class="metric">12.5K</td>
<td>
<svg width="80" height="20">
<polyline points="0,12 8,11 16,10 24,11 32,12 40,13 48,14 56,15 64,16 72,17"
fill="none" stroke="#d73027" stroke-width="1.5" />
</svg>
</td>
<td class="delta alert">-12%</td>
</tr>
<tr>
<td>Conversion</td>
<td class="metric">3.2%</td>
<td>
<svg width="80" height="20">
<polyline points="0,14 8,14 16,13 24,13 32,12 40,12 48,11 56,11 64,10 72,10"
fill="none" stroke="#555" stroke-width="1.5" />
</svg>
</td>
<td class="delta">+5%</td>
</tr>
<tr>
<td>NPS</td>
<td class="metric">67</td>
<td>
<svg width="80" height="20">
<polyline points="0,10 8,10 16,11 24,10 32,9 40,9 48,8 56,8 64,7 72,7"
fill="none" stroke="#555" stroke-width="1.5" />
</svg>
</td>
<td class="delta">+2%</td>
</tr>
</tbody>
</table>
</body>
</html>
```
### React Component with Tufte Theme
```jsx
// Request: "Create a time series chart in React"
View on GitHub