# Heatmap maker with hierarchical clustering

> Paste a matrix to make a clustered heatmap: row z-scores, average-linkage clustering (Euclidean or Pearson) with dendrograms, viridis or blue–white–red.

URL: https://www.labcanvas.com/tools/heatmap-maker

Paste a matrix with row and column labels, such as genes by samples, and the tool draws a heatmap. It can scale each row to z-scores, cluster rows and columns by average-linkage hierarchical clustering with Euclidean or 1 − Pearson correlation distance and draw the dendrograms, colour the cells with a colour-blind-safe scale (viridis, cividis, blue–white–red or purple–white–orange) and show the values in the cells. Download the heatmap as SVG or 300 dpi PNG and the reordered matrix as CSV.

## Quick answer

- **What it does:** Draws a heatmap from a pasted labelled matrix, with optional row z-scores and average-linkage clustering of rows and columns shown as dendrograms, in colour-blind-safe scales.
- **Formula:** z = (x − row mean) / row SD (n − 1); distance = √Σ(xᵢ − yᵢ)² or 1 − Pearson r; average linkage d(A∪B, C) = (|A|·d(A, C) + |B|·d(B, C)) / (|A| + |B|).
- **Example:** VEGFA at 6.1, 6.3, 5.9, 6.2 (control) and 8.4, 8.9, 8.6, 8.2 (hypoxia) has mean 7.325 and SD 1.302, so its first control sample has z = (6.1 − 7.325) / 1.302 = −0.94.

Free, in the browser, no account needed. Updated 2026-10-19.

## Features

- Paste a matrix from Excel: column labels in the first row, row labels in the first column; missing cells allowed
- Optional row z-score scaling (as pheatmap’s scale = "row")
- Hierarchical clustering of rows and/or columns: average linkage (UPGMA) with Euclidean or \(1 - \text{Pearson } r\) distance, matching SciPy and R’s hclust
- Dendrograms drawn beside and above the heatmap
- Colour-blind-safe scales: viridis, cividis, blue–white–red (RdBu) and purple–white–orange (PuOr), diverging scales centred on 0 or a value you choose
- Values in the cells on request, in black or white for contrast
- SVG and 300 dpi PNG export; reordered matrix as CSV
- Runs in your browser; nothing is uploaded

## How to use it

1. **Paste the matrix**: Copy a table with sample names across the top and gene (or feature) names down the first column.
2. **Scale and cluster**: Scale rows to z-scores to compare patterns across genes with different expression levels, and cluster rows and columns with Euclidean or correlation distance.
3. **Choose colours and export**: Pick viridis for values or blue–white–red for z-scores and fold changes, then download SVG or PNG.

## At a glance

| | |
| --- | --- |
| Input | Matrix with column labels in the first row and row labels in the first column |
| Scaling | Optional row z-scores (sample SD) |
| Clustering | Average linkage (UPGMA); Euclidean or \(1 - \text{Pearson } r\); rows and/or columns; matches SciPy |
| Colours | Viridis, cividis, RdBu, PuOr (colour-blind safe) |
| Limit | 60,000 cells |
| Export | SVG and 300 dpi PNG; reordered matrix as CSV |

## How it works

**Row z-scores.** Each value becomes \(z = (x - \bar{x}) / s\), where \(\bar{x}\) and \(s\) are the mean and sample standard deviation (\(n - 1\)) of its row, the same as R’s `scale()` and pheatmap’s `scale = "row"`. Every row then has mean 0 and SD 1, so the colours show whether a gene is high or low in a sample relative to its own average, not its absolute level. Rows with no variation get \(z = 0\).

**Distances.** Euclidean distance \(d = \sqrt{\textstyle\sum (x_i - y_i)^2}\) groups rows with similar values; \(1 - \text{Pearson } r\) (0 for identical patterns, 1 for unrelated, 2 for opposite) groups rows with the same shape of profile regardless of level, the measure used by Eisen et al. (1998). On z-scored rows the two are closely related: the squared Euclidean distance between z-scored rows is \(2(n - 1)(1 - r)\), so they rank pairs of rows in the same order and usually give very similar trees. With missing cells, distances use the positions both rows have, and Euclidean distance is scaled by \(\sqrt{p / m}\) as in R’s `dist()`.

**Average linkage (UPGMA).** Start with every row as its own cluster; merge the two closest; set the distance from the merged cluster to every other as the size-weighted mean of the two old distances, \(d(A \cup B, C)\) \(= (\lvert A\rvert\, d(A, C) + \lvert B\rvert\, d(B, C))\) \(/\, (\lvert A\rvert + \lvert B\rvert)\); repeat until one cluster is left. The dendrogram joins clusters at the height of their merge, and the heatmap rows follow its leaf order. Merge heights and leaf order match SciPy’s `linkage(method="average")` and `dendrogram` on the example.

**Colours.** Sequential data (expression, intensity) use viridis or cividis, which are perceptually uniform and readable with colour-vision deficiency and in greyscale; data around a centre (z-scores, log fold changes) use the ColorBrewer RdBu or PuOr diverging scales, centred so 0 is white. Rainbow and red–green scales distort the data and exclude colour-blind readers (Crameri et al. 2020). Sequential scales run from the smallest to the largest value; diverging scales are symmetric around the centre.

Sources: Eisen MB, Spellman PT, Brown PO, Botstein D. Cluster analysis and display of genome-wide expression patterns. *Proc Natl Acad Sci USA* 1998;95:14863–14868, [doi:10.1073/pnas.95.25.14863](https://doi.org/10.1073/pnas.95.25.14863). Crameri F, Shephard GE, Heron PJ. The misuse of colour in science communication. *Nat Commun* 2020;11:5444, [doi:10.1038/s41467-020-19160-7](https://doi.org/10.1038/s41467-020-19160-7).

## Worked example: 16 genes in control and hypoxic cells

The built-in matrix is illustrative log₂ expression of 16 genes in 4 control and 4 hypoxia samples: hypoxia-induced genes (*VEGFA*, *CA9*, *SLC2A1*, *PGK1*, *BNIP3*, *LDHA*, *NDRG1*), proliferation genes that fall (*MKI67*, *CCNB1*, *TOP2A*, *CDK1*, *PLK1*) and four housekeeping genes.

- **Z-score a row.** *VEGFA*: 6.1, 6.3, 5.9, 6.2, 8.4, 8.9, 8.6, 8.2. Mean 7.325, SD 1.302, so \(z = -0.94, -0.79, -1.09, -0.86,\) \(0.83, 1.21, 0.98, 0.67\). *PGK1* is about 3 log₂ units higher but gets similar z-scores, so the two genes look alike on the heatmap.
- **Cluster the rows.** With z-scores, Euclidean distance and average linkage, the seven hypoxia genes form one tight cluster (all joined by height 0.45) and the five proliferation genes another (by 0.14). The housekeeping genes vary by only 0.1–0.4 log₂ units, but z-scoring stretches that noise to an SD of 1, so each attaches to the group its small trend follows: *GAPDH* (11.5 → 11.9) joins the hypoxia genes at 0.67, *ACTB* and *RPLP0* join the proliferation genes at 3.06, and *TBP* joins the hypoxia side at 3.47; the last merge is at 4.94. This is the usual caveat of row scaling: remove flat genes (low variance) before plotting.
- **Cluster the columns.** The samples split into the four controls and the four hypoxia samples, joined at height 7.09; within groups the first merge is Ctrl_1 with Ctrl_4 at 0.47.
- **Without z-scores**, Euclidean clustering groups genes partly by level instead: the highly expressed *ACTB* and *GAPDH* join at 1.25 and then take in *RPLP0*, *PGK1* and *LDHA*, so the hypoxia genes are split by how strongly they are expressed. That is why expression heatmaps are usually row-scaled.

| Data | Scale rows? | Distance | Colours |
| --- | --- | --- | --- |
| Expression (log₂ counts, intensities) of many genes | Yes (z-score) | Euclidean or 1 − Pearson | Blue–white–red, centred at 0 |
| Log₂ fold changes | No | Euclidean | Blue–white–red, centred at 0 |
| Correlation matrix | No | 1 − Pearson or Euclidean | Blue–white–red, centred at 0 |
| Absolute values (plate reader, concentrations) | No | Euclidean | Viridis or cividis |

## Questions

### How do I make a heatmap from Excel data?

Select the table in Excel including the row and column labels, copy, and paste it into the box. The heatmap appears straight away; turn clustering and z-scores on or off, choose colours, and download SVG or PNG.

### Should I scale the rows to z-scores?

For gene expression across samples, usually yes: it shows each gene’s pattern relative to its own mean, so genes with very different levels can be compared. Do not scale fold changes, correlations or values whose absolute size matters.

### Euclidean or correlation distance: which should I use?

Correlation (\(1 - \text{Pearson } r\)) groups rows by the shape of their profile; Euclidean groups by actual values. On z-scored rows they rank pairs of rows identically and usually give very similar trees. Without scaling, use Euclidean when the level matters and correlation when only the pattern does.

### What is average linkage?

A hierarchical clustering rule (UPGMA) where the distance between two clusters is the average distance between all their members. It is the method of Eisen et al. (1998) for expression data, and a balance between single linkage (chains) and complete linkage (tight, compact clusters).

### How do I read a dendrogram?

Rows joined by a short branch are similar; the height where two branches join is their distance. Cutting the tree at a height gives clusters. Rows that sit next to each other are not necessarily similar unless they join low in the tree.

### Which colours should a heatmap use?

A perceptually uniform scale such as viridis or cividis for values from low to high, and a diverging scale such as blue–white–red for values around 0 (z-scores, log fold changes). Avoid rainbow (jet) and red–green, which distort the data and are unreadable for colour-blind readers.

### How many rows can I plot?

Up to 60,000 cells, for example 2,000 genes × 30 samples. Row labels are hidden when rows get too thin to read. For RNA-seq, plot the differentially expressed or most variable genes rather than all of them.

### Is my data uploaded?

No. Everything runs in your browser.
