CSV to Treemap

Drop a CSV, name the column that groups it and the column that sizes it, and you get a treemap: nested rectangles whose area is the aggregate, one level deep, each tile labelled with its name and its formatted value. Groups totalling zero or less are dropped rather than faked. The file is parsed and drawn in your own browser.

No file open? Borrow the sample sales data · group by product, subgroup by region, size by revenue.

Need to filter or join first? Open the app

Area is the whole argument

A treemap makes one claim and makes it with geometry. The rectangle for a category occupies a share of the canvas equal to that category's share of the total, so the picture answers a question a bar chart answers slowly: what is this file mostly made of. Nine near-identical bars and one long one is a shape you have to scan. Nine small tiles crowded around one big one is a shape you take in at a glance, before you have read a single label.

That strength is also the limit, and it is worth saying out loud on the page rather than in a footnote. Human beings compare lengths well and areas badly. Ask someone whether one tile is 30 percent or 40 percent larger than another and you will get a shrug. So the treemap here is built for proportion, not for precision: it tells you which handful of things dominate and roughly how badly, and then the exact numbers are written on the tiles and available as a CSV for anyone who needs to do arithmetic. If your reader has to rank items three through seven, send them a bar chart instead. I would rather this page recommend the right shape than pretend it is the only one.

The nesting is what earns the treemap its keep over a donut. Each outer rectangle can be split once by a second column, so revenue by product becomes revenue by product, split by region without leaving the panel or drawing a second chart. You see the size of each product and the internal makeup of each product in the same picture. That is genuinely two questions answered at once, which is a rare thing in a chart and the reason treemaps survived the decades of criticism aimed at pie charts.

Five controls, and what each one moves

Everything redraws from rows that are already parsed, so changing a control is instant and the file is never read twice.

  • Group. The column that makes the outer rectangles. This is the only control the treemap cannot do without. Leave it empty and the page stops with a message naming the control by its label, so you are never hunting for which of five dropdowns it meant.
  • Subgroup. Optional, and set to (none) until you choose otherwise. Give it a second column and every outer rectangle is divided into children. The caption then gains the phrase split by and the column name, so nobody has to guess what the internal boundaries mean.
  • Size. The number whose aggregate becomes the area. Set it to Count rows and the tiles size by how many records fall in each group, which is the right answer for a file of events with no quantity attached to them.
  • Aggregate. Sum, average, count, count distinct, minimum, maximum, median. Sum is the honest default for a treemap because sums are the thing that legitimately add up to a whole. An average-sized treemap is a stranger object: the parts no longer sum to the total, so the areas are comparable to each other but not to the canvas. Use it deliberately.
  • Show. Top 5, 10, 20, 50 or everything. The treemap takes three times this number of groups, with a floor of four, because rectangles degrade more gracefully than bars do. Top 10 therefore keeps thirty groups, which fills a panel without turning it to confetti.

Worked example: one year of orders

The sample file is 180 orders across 2024, seven columns wide. Here is the head of it:

date,region,product,channel,units,unit_price,revenue
2024-01-02,West,Doohickey,Direct,58,211.64,12275.12
2024-01-04,West,Sprocket,Partner,13,40.73,529.49
2024-01-06,North,Sprocket,Retail,31,147.97,4587.07
2024-01-08,South,Gizmo,Direct,33,13.81,455.73
2024-01-10,North,Gizmo,Direct,20,55.49,1109.80

Set Group to product, Subgroup to region and Size to revenue. The panel titles itself revenue by product, puts TREEMAP in the corner as the kicker, and captions the picture 5 groups · area is sum of revenue · split by region. Five outer rectangles appear, one per product, each carved into four children for West, North, South and East.

Read the caption slowly, because every clause in it is load bearing. 5 groups tells you nothing was folded away. area is sum of revenue names both the encoding and the aggregate, so a reader six months from now cannot mistake the picture for a count of orders. split by region explains the internal lines. A caption that states these three things cannot quietly lie about them later, which is the entire reason it is generated from the same object that produces the tiles rather than typed by hand.

Each tile carries two lines: the name, then the value formatted the way the column deserves. Because revenue was read as money, the biggest tile reads Doohickey over $182.4k rather than 182412.87, and the same formatting shows up in the tooltip and in the exported CSV header. The child tiles inside it are shaded from the same categorical palette, so West and North sit next to each other without their boundary vanishing.

Now switch Group to channel and Subgroup back to (none). Four flat tiles for Direct, Partner, Retail and Online, and the caption drops its last clause to read 4 groups · area is sum of revenue. Switch Size to units and the ranking shifts, because the product that sells the most pieces is not the product that earns the most money. That disagreement between two treemaps of the same file is usually the most interesting thing on the page.

Negative numbers, and why a tile vanishes

This is the one rule worth understanding before you trust a treemap you did not build yourself. A rectangle cannot have negative area. There is no drawing that honestly represents minus four thousand dollars as a share of a canvas, so any tool showing you a treemap of a column containing negatives has made a decision on your behalf, and it usually made it silently.

Here the decision is explicit. Groups whose aggregate comes out at zero or below are dropped before layout begins, and the count of surviving groups is stated in the caption so a shrinking number is visible rather than hidden. If nothing at all survives, the page refuses to draw and says exactly why: Every group totals zero or less, so there is no area to draw. That message is not a generic failure. It is a diagnosis, and nine times out of ten the diagnosis is that Size is pointing at a change column rather than a level column.

When that happens, the chart you wanted was probably a waterfall, which is built for movement and draws increases and decreases in different colors on a running total. Deltas belong in a bridge. Levels belong in a treemap. Keeping those two straight fixes more confusing charts than any amount of palette tuning.

Taking the treemap somewhere else

  • Download the areas. A three-column CSV: group, subgroup, value. One row per drawn tile. Groups with no subgroup keep an empty middle field instead of being omitted, so the file always accounts for the whole picture and a spreadsheet can pivot it straight away.
  • Download PNG. Two-times pixel density on the panel's own background rather than a transparent one, so the tiles do not turn into a dark smear when the image lands on a dark slide.
  • Download SVG. The layout is rendered a second time through a vector renderer, so the rectangles and their labels come out as real paths and real text. Useful when a house style demands its own colors and someone is going to open the file in Figma or Illustrator to apply them.
  • Copy image. The same PNG onto the clipboard, for pasting into a document, a ticket or a chat without a file ever landing on disk.

To publish the treemap on a page instead of inside a document, the embed builder compresses the data and the configuration into the URL of an iframe. The chart renders from the link alone, with no server holding your numbers and nothing stored anywhere.

What this page will not do

The honest edges, because these are the ones people run into:

  • No third level. Group and Subgroup, and that is it. A third tier of rectangles at panel size is a row of slivers too narrow to label. Combine two columns into a composite key beforehand if you truly need the depth.
  • No drill-down. Clicking a tile does not zoom into it and redraw the children as a full canvas. The picture you see is the picture that exports, which keeps the PNG and the screen honest with each other.
  • No negative area. Covered above, and worth repeating: a group summing to zero or less is dropped, not shrunk to a sliver and not flipped to its absolute value.
  • No filtering. Every row in the file goes into the layout. Filter first in the app, or cut the file down with the CSV splitter.
  • No custom palette here. The validated categorical set applies on this page. Color choice lives in the embed builder, where a chart has to live inside someone else's design.
  • A header row is required. A file whose first line is already data ends up with values as column names. Add a header, or promote a row in the app.

Comma, semicolon, tab and pipe delimited files all parse without configuration, so pasting a block of spreadsheet cells into the paste tab works. Excel workbooks and JSON go through excel-to-chart and json-to-chart, which flatten to the same rectangle and then behave exactly like this page.

Frequently Asked Questions

What do the rectangles actually represent?

Area is the aggregate. If Size is revenue and Aggregate is Sum, a tile twice the area of its neighbour holds twice the revenue. Nothing else in the picture carries a number: the color is categorical and only exists so adjacent tiles can be told apart, and the position inside the rectangle is a packing decision made by the layout, not a ranking you should read into. When you want a ranking you can read precisely, a bar chart is the better shape and the value labels sit right on the bars.

Why did a group disappear from my treemap?

Groups totalling zero or less are dropped before layout, because a rectangle cannot have negative area. A refunds column that sums to minus 4,000 for one region has no honest tile: half the size of a positive one would be a lie, and zero width is invisible anyway. If every group in the file totals zero or less the page stops with the message Every group totals zero or less, so there is no area to draw. That usually means Size is pointing at a delta column, and a waterfall is the chart you actually want.

How deep does the nesting go?

One level. Group makes the outer rectangles, Subgroup splits each one into children, and that is the end of it. Three and four level treemaps look impressive in a screenshot and are close to unreadable at the size a browser panel gives you, since the third level ends up as slivers a few pixels across with no room for a label. If you need a deeper hierarchy, collapse two of your columns into one composite key before dropping the file, or use the pivot tool where depth costs nothing because the rows are text.

What do the labels on the tiles say?

The name and the formatted value, on two lines, in the same monospace face the rest of the chart uses for numbers. Formatted means the column's role is respected: a money column reads 182.4k with its currency symbol rather than 182412.87, and a plain count reads 1,204. Small tiles drop the value line first and then the name, because a label wider than its own rectangle is worse than no label. Hover any tile for the full name and the exact number.

Why is the color palette categorical rather than a gradient?

Because size is already carrying the magnitude, so shading by magnitude too would spend a second channel saying the same thing. What the tiles genuinely need is to be told apart from their neighbours, and that is what a categorical palette is for. The palette is machine-validated: every adjacent pair clears a color-vision-deficiency separation floor in both light and dark mode, so the boundaries survive being printed, projected, and read by someone with deuteranopia.

How many groups will it draw?

The Show setting sets the ceiling, and the treemap is allowed three times that number of groups, with a floor of four. So Top 10, which is the default, keeps the thirty largest groups. A treemap tolerates more categories than a bar chart because the small ones become small rectangles rather than a queue of hairlines, but past a few dozen the labels stop fitting and you are looking at confetti. Set Show to Everything if you want no ceiling at all.

Does my file get uploaded?

No. The CSV is parsed, grouped and laid out in your own browser tab. There is no upload endpoint behind this page and no request that carries your rows anywhere. You can disconnect the network after the page has loaded and everything still works, which is the easiest way to verify the claim without taking my word for it.

Can I get the numbers behind the picture?

Yes. Download the areas writes a CSV with one row per tile: the group name, the subgroup name, and the aggregated value. Groups with no subgroup get an empty middle column rather than being left out. That file holds exactly the numbers the layout used, so an appendix table built from it cannot disagree with the treemap in the slide. PNG and SVG exports of the picture itself sit next to it.

See what your file is mostly made of

Drop the CSV, pick a group and a size, take the picture. No sign-up, no upload, no row cap.

Back to the treemap maker