Observable Plot
Create data visualizations using Observable Plot's declarative grammar of graphics
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",
"sRelated in General
modeling-omnistudio-epc-catalog
IncludedSalesforce Industries CME EPC product-modeling skill for Product2-based catalog creation. Use when creating EPC products, configuring product attributes, building offer bundles with Product Child Items, or reviewing EPC DataPack JSON metadata for product catalog changes. TRIGGER when: user creates or updates Product2 EPC records, AttributeAssignment payloads, AttributeMetadata/AttributeDefaultValues, Offer bundles, or ProductChildItem relationships. DO NOT TRIGGER when: designing OmniScripts/FlexCards/Integration Procedures (use building-omnistudio-omniscript, building-omnistudio-flexcard, or building-omnistudio-integration-procedure), implementing Apex business logic (use generating-apex), or troubleshooting deployment pipelines (use deploying-metadata).
relationship-science-coach
IncludedUse this skill for direct, practical adult relationship coaching: couples conflict, repair, trust, marriage, dating, flirting, attachment patterns, emotional connection, sex, desire differences, eroticism, kink negotiation, affection, love languages, breakups, and long-term passion. Draw on Gottman, EFT and Hold Me Tight, attachment science, modern sex research, Perel, Nagoski, Kerner, Schnarch, Love and Stosny, and flexible love-language tools. Be concrete and low-hedge. Redirect only for imminent danger, abuse, coercive control, minors, non-consent, self-harm, stalking, or medical/legal/psychiatric decisions.
building-sf-integrations
IncludedSalesforce integration architecture and runtime plumbing with 120-point scoring. Use this skill to set up Named Credentials, External Credentials, External Services, REST/SOAP callout patterns, Platform Events, and Change Data Capture. TRIGGER when: user sets up Named Credentials, External Services, REST/SOAP callouts, Platform Events, CDC, or touches .namedCredential-meta.xml files. DO NOT TRIGGER when: Connected App/OAuth config (use configuring-connected-apps), Apex-only logic (use generating-apex), or data import/export (use handling-sf-data).
venue-templates
IncludedAccess comprehensive LaTeX templates, formatting requirements, and submission guidelines for major scientific publication venues (Nature, Science, PLOS, IEEE, ACM), academic conferences (NeurIPS, ICML, CVPR, CHI), research posters, and grant proposals (NSF, NIH, DOE, DARPA). This skill should be used when preparing manuscripts for journal submission, conference papers, research posters, or grant proposals and need venue-specific formatting requirements and templates.
let-fate-decide
IncludedDraws the 12 Houses of the Zodiac Tarot spread to inject entropy into planning when prompts are vague, ambiguous, or casually delegated. Interprets the spread to guide next steps. Use when the user says 'let fate decide', 'YOLO', 'whatever', 'idk', or other nonchalant phrases, makes Yu-Gi-Oh references, or when you are about to arbitrarily pick between multiple reasonable approaches. Prefer over ask-questions-if-underspecified when the user's tone is casual or playful rather than precision-seeking.
net-ops
IncludedCross-platform network troubleshooting (Windows, macOS, Linux) via local or remote shell. Use for: DNS broken, can't resolve hostnames, nslookup/dig works but apps fail, NRPT, WFP, scutil, /etc/resolver, systemd-resolved, /etc/resolv.conf, NetworkManager, VPN DNS leak residue (ProtonVPN/Mullvad/WireGuard/AnyConnect), AV/firewall blocking DNS or DoH, Tailscale DNS interaction, intermittent connectivity, remote diagnostics over SSH.