Claude
Skills
Sign in
Back

Observable Plot

Included with Lifetime
$97 forever

Create data visualizations using Observable Plot's declarative grammar of graphics

Generalvisualizationdataplotchartgraphicsd3scripts

What this skill does


# Observable Plot

Observable Plot is a JavaScript library for exploratory data visualization. It uses a declarative grammar of graphics to create meaningful visualizations quickly by composing marks, scales, and transforms.

## What is Observable Plot?

Observable Plot helps you turn data into visualizations by mapping data columns to visual properties. Instead of specifying chart types, you compose visual elements (marks) with data transformations (transforms) and encodings (scales).

**Key principle**: Maximize configuration, minimize external JavaScript. Plot handles data processing, layout, axes, and legends through its declarative API.

## Five Core Concepts

### 1. Marks

Marks are visual elements that represent data. Plot provides 30+ mark types:

- **Point marks**: `dot`, `image`, `text`
- **Rectangular marks**: `barX`, `barY`, `cell`, `rect`
- **Line marks**: `line`, `lineX`, `lineY`, `area`, `areaX`, `areaY`
- **Reference marks**: `ruleX`, `ruleY`, `tickX`, `tickY`, `frame`, `grid`
- **Geographic marks**: `geo`, `sphere`, `graticule`
- **Relational marks**: `arrow`, `link`, `tree`, `vector`
- **Density marks**: `contour`, `density`, `hexgrid`, `raster`
- **Statistical marks**: `boxX`, `boxY`, `linearRegressionY`
- **Utility marks**: `axis`, `tip`

### 2. Scales

Scales map abstract data values to visual values (position, color, size, etc.). Plot automatically infers scales from your data and mark specifications.

**Scale types**:
- Continuous: `linear`, `log`, `sqrt`, `pow`, `time`, `utc`
- Discrete: `point`, `band`, `ordinal`
- Color: sequential, diverging, categorical, cyclical schemes

### 3. Transforms

Transforms process data within the Plot specification, eliminating the need for external data wrangling:

- **Aggregation**: `bin`, `hexbin`, `group`
- **Statistical**: `normalize`, `window` (moving averages)
- **Positional**: `stack`, `dodge`, `shift`
- **Filtering**: `filter`, `select`
- **Ordering**: `sort`

### 4. Layering

Compose complex visualizations by layering multiple marks. Each mark can have its own data, transforms, and encodings while sharing the same coordinate system.

### 5. Tidy Data

Plot works best with tidy data: arrays of objects where each object represents one observation with consistent properties.

```javascript
// Tidy data format
const data = [
  {name: "Alice", age: 25, score: 85},
  {name: "Bob", age: 30, score: 92},
  {name: "Carol", age: 28, score: 78}
];
```

## Quick Start

```javascript
import * as Plot from "@observablehq/plot";

// Simple scatterplot
const data = [
  {x: 1, y: 2, category: "A"},
  {x: 2, y: 5, category: "B"},
  {x: 3, y: 3, category: "A"},
  {x: 4, y: 7, category: "B"}
];

const plot = Plot.plot({
  marks: [
    Plot.dot(data, {
      x: "x",
      y: "y",
      fill: "category",
      r: 5
    })
  ]
});

document.body.appendChild(plot);
```

## Interactive Viewer

The Observable Plot skill includes an interactive live editor and viewer for developing visualizations:

### Starting the Viewer

**Launch from your working directory** (where you want plots to be created):

```bash
# From your project directory
uv run --directory ~/.claude/skills/observable-plot/scripts plot-viewer --plots-dir $(pwd)/plots
```

Or if you're already in the skills directory structure:

```bash
# Shorter version from within skills directory
uv run --directory observable-plot/scripts plot-viewer --plots-dir $(pwd)/plots
```

This launches a three-pane interface with history sidebar, live preview, and code editor on http://localhost:8765

**The viewer automatically detects if it's already running and just opens a new browser tab.**

**Options:**
- `--plots-dir PATH` - Specify plots directory (default: ./plots)
- `--port 8080` - Use a different port
- `--no-browser` - Don't auto-open browser
- `--create-example` - Create example plot file on startup

### Using with Claude

Claude can write visualization code to JSON files that automatically load in the viewer:

#### Writing Plot Files

**IMPORTANT**: Claude should check its current working directory and write plot files to `$(pwd)/plots/`.

**Workflow:**
1. User launches viewer from their working directory with `--plots-dir $(pwd)/plots`
2. Viewer displays the plots directory it's watching on startup
3. Claude checks its current directory and creates `plots/` subdirectory
4. Claude writes plot JSON files to `plots/filename.json`
5. Viewer automatically detects and displays new plots in the history sidebar

**For Claude:**
1. Check the current directory with `pwd`
2. Ensure the `plots` subdirectory exists with `mkdir -p plots`
3. Write plot files to `plots/filename.json`

The viewer will show which directory it's watching on startup, so you can verify Claude is writing to the correct location.

#### JSON File Format

Claude writes plot files to `$(pwd)/plots/` with this structure:

```json
{
  "name": "Sales Analysis",
  "description": "Monthly revenue by product category",
  "code": "const data = [...]; return Plot.plot({...})",
  "timestamp": "2025-10-31T12:34:56.789Z"
}
```

**Fields:**
- `name` - Descriptive name shown in history (required)
- `description` - Brief description shown in history sidebar (optional)
- `code` - JavaScript code that returns a Plot.plot() result (required)
- `timestamp` - ISO timestamp for tracking creation time (required)

#### File Naming Convention

Use descriptive filenames that make sense:
- `sales-by-category-2025.json`
- `temperature-trends-seattle.json`
- `penguins-body-mass-analysis.json`

Avoid generic names like `plot1.json` or `temp.json`.

#### Example Workflow

**Step 0: Launch the viewer from your working directory**

```bash
cd /Users/mberg/projects/myapp
uv run --directory ~/.claude/skills/observable-plot/scripts plot-viewer --plots-dir $(pwd)/plots
```

The viewer will print: `Watching plots directory: /Users/mberg/projects/myapp/plots`

**Step 1: Check current directory and ensure plots folder exists**

```bash
pwd
# Output: /Users/mberg/projects/myapp

mkdir -p plots
```

**Step 2: Write the plot file**

```bash
cat > plots/sales-analysis-2025.json << 'EOF'
{
  "name": "Sales Analysis",
  "description": "Monthly revenue by product category",
  "code": "const data = [\n  {month: 'Jan', revenue: 1000},\n  {month: 'Feb', revenue: 1200}\n];\n\nreturn Plot.plot({\n  marks: [\n    Plot.barY(data, {x: 'month', y: 'revenue'})\n  ]\n})",
  "timestamp": "2025-10-31T12:34:56.789Z"
}
EOF
```

**Step 3: Viewer automatically detects and loads the new plot**

The viewer polls every 5 seconds for new plots and will automatically:
- Add the plot to the history sidebar
- Load it as the current plot
- Display the visualization

**Step 4: User interaction**

Users can then:
- Switch between plots using the history sidebar
- Edit code in the editor and see live updates
- Save modified plots to new files

### Viewer Features

- **History Sidebar**: Browse all saved plots with names, descriptions, and timestamps
- **Live Preview**: Chart updates as you type (500ms debounce)
- **Monaco Editor**: Full-featured code editor with syntax highlighting
- **File Switching**: Click any plot in history to load it instantly
- **Auto-reload**: Detects new plots and file changes automatically (polls every 2 seconds)
- **Resizable Panes**: Drag divider to adjust layout
- **Error Display**: See error messages clearly when code fails
- **Keyboard Shortcut**: ⌘+Enter to manually run code
- **Persistent Storage**: All plots saved in `plots/` directory for future use
- **Error Tracking**: Errors are automatically sent to server for debugging

### Debugging with Claude

When running the viewer in the background, Claude can check for errors:

```bash
curl -s http://localhost:8765/viewer-status | jq
```

This returns:
```json
{
  "last_error": "Plot evaluation error: data is not defined",
  "last_error_time": "2025-10-31T14:23:45.123Z",
  "error_count": 3,
  "recent_errors": [
    {
      "message": "Plot evaluation error: data is not defined",
      "s
Files: 35
Size: 286.3 KB
Complexity: 84/100
Category: General

Related in General