With so much buzz around Claude dashboards , I had to give it a spin with a well known example: the NYC taxi dataset.
This is a 5-minute guide shows that demonstrates the power of dashboards from just a single prompt:
Build a new dashboard (https://support.claude.com/en/articles/17454700-get-started-with-claude-dashboards) with the data that is in the .parquet in this folder.
how a single Claude Code session turned a raw NYC TLC yellow taxi trip Parquet file (January 2026, 3,724,889 rows, 64 MB) into:
- An interactive Claude Dashboard hosted on claude.ai, where every number is traceable to its source.
- A self-contained HTML embed (24 KB) that you can paste into a WordPress page with the Elementor HTML widget.
The whole build took about 10 minutes of wall-clock time, from the first prompt to the exported file.
NYC yellow taxi trips, January 2026
— trips took in — in fares, fees and tips. — were paid by card and — started at an airport. The busiest day was —, with — trips.
Trips per day
Pickups by calendar day. Weekends are grey.
When people ride
Trips by pickup weekday and hour, summed over the month. Darker cells have more trips.
Trip length
Trips per distance band, with the average total charged.
How riders pay
Average total and tip per trip. Tips paid in cash aren't recorded.
| Payment | Trips | Avg total | Avg tip |
|---|
Source: the NYC TLC yellow taxi trip records for January 2026. Only trips picked up in January are counted. Records are left out when the total is zero or negative, the distance is zero or 100 miles or more, or the drop-off time is before the pickup. "Total charged" is the sum of total_amount and includes fares, surcharges, tolls and recorded tips. Card tip rate is tips divided by fares on card trips.
Contents
What the dashboard shows
| Section | Chart type | Key insight |
|---|---|---|
| Takeaway sentence | Text with live-filled figures | 3.5M trips, $104.4M charged, 62.3% paid by card, 6.3% from airports; busiest day Fri Jan 30 (140,853 trips) |
| Headline KPIs | Six number tiles | Avg fare $21.08 · avg distance 3.49 mi · median trip 13.5 min · card tip rate 21.2% |
| Trips per day | Bar chart, weekends muted, hover tooltips | Weekly rhythm and one sharp late-January dip |
| When people ride | Weekday × hour heatmap | Evening peaks Thu–Sat; late-night demand on weekends |
| Trip length | Horizontal bars by distance band | Most trips are 1–5 miles; 20+ mi trips average $112.19 |
| How riders pay | Table | Card riders tip $4.11 on average; cash tips aren’t recorded |
Data cleaning rules: the dashboard keeps only pickups in January 2026 and drops records with a zero or negative total, a distance of zero or 100+ miles, or a drop-off before the pickup. That left 3,517,748 trips.
End-to-end workflow
1. Profile the Parquet file with DuckDB
DuckDB read the Parquet schema (20 columns: pickup/drop-off timestamps, distance, fare, tip, payment type, airport fee, the new cbd_congestion_fee) and the date range. A few pickups fell outside January (from 2025-12-31 to 2026-02-01) and were filtered out.
Where does the data come from?
The NYC Taxi & Limousine Commission (TLC) yellow taxi trip records, file yellow_tripdata_2026-01.parquet.
2. Aggregate 3.7M rows into five small CSVs
A dashboard can’t attach a 64 MB file, so DuckDB SQL reduced the data to five small summary tables (216 rows in total):
| File | Rows | Contents |
|---|---|---|
summary.csv | 1 | Month totals and rates |
daily.csv | 31 | Trips, revenue, avg fare, avg miles per day |
hourly.csv | 168 | Trips per ISO weekday × hour |
payment.csv | 5 | Trips, avg total, avg tip per payment type |
distance.csv | 6 | Trips and avg total per distance band |
3. Create the Claude Dashboard
- Created a new artifact from the Dashboard artifact type on claude.ai.
- Uploaded each CSV to the artifact’s asset store.
- Wrote the dashboard’s documents in one atomic batch: the
dash/metatitle, fivedatasets/*source definitions, and the pagefiles/index.html. - Built the page in plain HTML with d3 v7. Each figure is tagged with
data-source/data-field/data-where, so readers can click any number and see which CSV row it came from.
4. Visual check and fixes
A headless Chrome screenshot found two layout bugs, and both were fixed in the embed and in the live dashboard:
- The trip-length bars weren’t on one scale because the value column changed width from row to row. The value column now has a fixed width.
- The bottom card row left an empty third grid column. The grid is now an explicit two-column layout that drops to one column below 760px.
Commands used
Inspect the Parquet file
duckdb -c "DESCRIBE SELECT * FROM 'yellow_tripdata_2026-01.parquet';
SELECT count(*), min(tpep_pickup_datetime), max(tpep_pickup_datetime)
FROM 'yellow_tripdata_2026-01.parquet';"
Clean and aggregate to CSV (DuckDB SQL)
CREATE VIEW t AS SELECT * FROM 'yellow_tripdata_2026-01.parquet'
WHERE tpep_pickup_datetime >= '2026-01-01' AND tpep_pickup_datetime < '2026-02-01'
AND total_amount > 0 AND trip_distance > 0 AND trip_distance < 100
AND tpep_dropoff_datetime > tpep_pickup_datetime;
COPY (SELECT count(*) trips, round(sum(total_amount),2) revenue, round(avg(fare_amount),2) avg_fare,
round(avg(trip_distance),2) avg_miles,
round(median(date_diff('second',tpep_pickup_datetime,tpep_dropoff_datetime))/60.0,1) median_minutes,
round(sum(tip_amount) FILTER (WHERE payment_type=1)/sum(fare_amount) FILTER (WHERE payment_type=1),4) card_tip_rate,
round(count(*) FILTER (WHERE payment_type=1)::double/count(*),4) card_share,
round(count(*) FILTER (WHERE Airport_fee>0)::double/count(*),4) airport_share
FROM t) TO 'summary.csv';
COPY (SELECT strftime(tpep_pickup_datetime,'%Y-%m-%d') AS "day", count(*) trips,
round(sum(total_amount),2) revenue, round(avg(fare_amount),2) avg_fare,
round(avg(trip_distance),2) avg_miles FROM t GROUP BY 1 ORDER BY 1) TO 'daily.csv';
COPY (SELECT isodow(tpep_pickup_datetime) dow, hour(tpep_pickup_datetime) AS "hour", count(*) trips
FROM t GROUP BY 1,2 ORDER BY 1,2) TO 'hourly.csv';
COPY (SELECT CASE payment_type WHEN 0 THEN 'Flex fare' WHEN 1 THEN 'Credit card' WHEN 2 THEN 'Cash'
WHEN 3 THEN 'No charge' WHEN 4 THEN 'Dispute' ELSE 'Other' END payment,
count(*) trips, round(avg(total_amount),2) avg_total, round(avg(tip_amount),2) avg_tip
FROM t GROUP BY 1 ORDER BY trips DESC) TO 'payment.csv';
COPY (SELECT CASE WHEN trip_distance<1 THEN 'Under 1 mi' WHEN trip_distance<2 THEN '1–2 mi'
WHEN trip_distance<5 THEN '2–5 mi' WHEN trip_distance<10 THEN '5–10 mi'
WHEN trip_distance<20 THEN '10–20 mi' ELSE '20+ mi' END band,
min(trip_distance) lo, count(*) trips, round(avg(total_amount),2) avg_total
FROM t GROUP BY 1 ORDER BY lo) TO 'distance.csv';
Claude Code tool calls (Artifact / ArtifactData)
| Step | Tool call |
|---|---|
| Pick the artifact type | Artifact action: quickstart, intent: other |
| Create the dashboard | Artifact publish with the Dashboard type_url, title, auto_open: after_first_write |
| Read the type’s docs | Artifact action: read, path: artifact-type/reference/design-defaults.md (later exporting.md) |
| Upload data | Artifact publish with asset: true, one call per CSV, which returns /_blob/<id> URLs |
| Write the dashboard | ArtifactData action: batch (7 writes: dash/meta, 5 × datasets/*, files/index.html) |
| Fix the layout | ArtifactData action: update on files/index.html with if_version: 1 |
Claude API usage metrics
Usage summary (/usage equivalent)
| Metric | Value |
|---|---|
| Model | claude-opus-5-5 (Opus 5.5), every request |
| Wall-clock time | 16:14:43 → 16:25:12 UTC (≈ 10.5 min) |
| API requests | 22 |
| Input tokens (uncached) | 44 |
| Cache-write tokens | 88,966 |
| Cache-read tokens | 1,786,426 |
| Output tokens (incl. thinking) | 29,567 |
| Cache hit rate on input | ≈ 95% (1.79M read vs 89K written) |
Tool calls
| Tool | Calls |
|---|---|
| Bash | 10 |
| Artifact | 9 |
| AskUserQuestion | 4 |
| ArtifactData | 2 |
| ToolSearch | 1 |
| Write | 1 |
| Read | 1 |
Context window
| Metric | Value |
|---|---|
| Context in use at the last request | ≈ 112.9K tokens (112,095 cached + 825 new + 2 uncached) |
| Largest contributors | System prompt and tool schemas, the Dashboard type’s instructions and design references, the page HTML (~17 KB), and one rendered screenshot |
| Compaction | None needed |
Conclusions
Claude dashboards can turn into a very powerful tool for fast creation of dashboards and data analysis.
However, it should not be unattended - the prompter must know what is the general view of the data being analyzed. Claude dashboards can turn into a very powerful tool
It was also very positive to see that there is traceability of what Claude did for analysing the data - useful for reproducibility