ScottPlot.NET
GitHub Repo stars

Heatmap

Heatmap Quickstart

Heatmaps can be created from 2D arrays

ScottPlot.Plot myPlot = new();

double[,] data = SampleData.MonaLisa();
myPlot.Add.Heatmap(data);

myPlot.SavePng("demo.png", 400, 300);

Inverted Heatmap

Heatmaps can be inverted by reversing the order of colors in the colormap

ScottPlot.Plot myPlot = new();

double[,] data = SampleData.MonaLisa();

var hm1 = myPlot.Add.Heatmap(data);
hm1.Colormap = new ScottPlot.Colormaps.Viridis();
hm1.Position = new(0, 65, 0, 100);

var hm2 = myPlot.Add.Heatmap(data);
hm2.Colormap = new ScottPlot.Colormaps.Viridis().Reversed();
hm2.Position = new(100, 165, 0, 100);

myPlot.SavePng("demo.png", 400, 300);

Heatmap with Custom Colormap

A heatmap’s Colormap is the logic used to convert from cell value to cell color and they can set by the user. ScottPlot comes with many common colormaps, but users may implement IColormap and apply their own. A colorbar can be added to indicate which colors map to which values.

ScottPlot.Plot myPlot = new();

double[,] data = SampleData.MonaLisa();

var hm1 = myPlot.Add.Heatmap(data);
hm1.Colormap = new ScottPlot.Colormaps.Turbo();

myPlot.Add.ColorBar(hm1);

myPlot.SavePng("demo.png", 400, 300);

Heatmap with Transparent Colormap

Custom colormaps may include transparency.

ScottPlot.Plot myPlot = new();

double[,] data = SampleData.MonaLisa();
var hm1 = myPlot.Add.Heatmap(data);

Color[] colors = [Colors.Navy, Colors.Transparent, Colors.Orange];
hm1.Colormap = new ScottPlot.Colormaps.CustomInterpolated(colors);

myPlot.Add.ColorBar(hm1);

myPlot.SavePng("demo.png", 400, 300);

Multiple Colorbars

Multiple colorbars may be added to plots.

ScottPlot.Plot myPlot = new();

double[,] data = SampleData.MonaLisa();

var hm1 = myPlot.Add.Heatmap(data);
hm1.Rectangle = new(0, 1, 0, 1);
hm1.Colormap = new ScottPlot.Colormaps.Turbo();
myPlot.Add.ColorBar(hm1);

var hm2 = myPlot.Add.Heatmap(data);
hm2.Rectangle = new(1.5, 2.5, 0, 1);
hm2.Colormap = new ScottPlot.Colormaps.Viridis();
myPlot.Add.ColorBar(hm2);

myPlot.SavePng("demo.png", 400, 300);

Colorbar Title

A colorbar displays a colormap on an edge of the plot, and it has an optional label which can be customized to display a title.

ScottPlot.Plot myPlot = new();

double[,] data = SampleData.MonaLisa();

var hm = myPlot.Add.Heatmap(data);
hm.Colormap = new ScottPlot.Colormaps.Turbo();

var cb = myPlot.Add.ColorBar(hm);
cb.Label = "Intensity";
cb.LabelStyle.FontSize = 24;

myPlot.SavePng("demo.png", 400, 300);

Colorbar Tick Formatter

Colorbars have an optional custom tick formatter that allows users to control the string format of tick labels.

ScottPlot.Plot myPlot = new();

double[,] data = SampleData.MonaLisa();

var hm = myPlot.Add.Heatmap(data);
var cb = myPlot.Add.ColorBar(hm);
cb.MinimumSize = 80; // reserve space for the colorbar and tick labels

// create a static function containing the string formatting logic
static string CustomFormatter(double position)
{
    return $"{Math.Round(position / 2.55)} %";
}

// create a custom tick generator using your custom label formatter
ScottPlot.TickGenerators.NumericAutomatic myTickGenerator = new()
{
    LabelFormatter = CustomFormatter
};

// tell the colorbar to use the custom tick generator
cb.Axis.TickGenerator = myTickGenerator;

myPlot.SavePng("demo.png", 400, 300);

Flipped Heatmap

Heatmaps can be flipped horizontally and/or vertically

ScottPlot.Plot myPlot = new();

double[,] data = SampleData.MonaLisa();

myPlot.Add.Text("default", 0, 1.5);
var hm1 = myPlot.Add.Heatmap(data);
hm1.Position = new CoordinateRect(0, 1, 0, 1);

myPlot.Add.Text("flip X", 2, 1.5);
var hm2 = myPlot.Add.Heatmap(data);
hm2.Position = new CoordinateRect(2, 3, 0, 1);
hm2.FlipHorizontally = true;

myPlot.Add.Text("flip Y", 4, 1.5);
var hm3 = myPlot.Add.Heatmap(data);
hm3.Position = new CoordinateRect(4, 5, 0, 1);
hm3.FlipVertically = true;

myPlot.Add.Text("flip X&Y", 6, 1.5);
var hm4 = myPlot.Add.Heatmap(data);
hm4.Position = new CoordinateRect(6, 7, 0, 1);
hm4.FlipHorizontally = true;
hm4.FlipVertically = true;

myPlot.Axes.SetLimits(-.5, 7.5, -1, 2);

myPlot.SavePng("demo.png", 400, 300);

Smooth Heatmap

Enable the Smooth property for anti-aliased rendering

ScottPlot.Plot myPlot = new();

double[,] data = SampleData.MonaLisa();

myPlot.Add.Text("Smooth = false", 0, 1.1);
var hm1 = myPlot.Add.Heatmap(data);
hm1.Position = new CoordinateRect(0, 1, 0, 1);

myPlot.Add.Text("Smooth = true", 1.1, 1.1);
var hm2 = myPlot.Add.Heatmap(data);
hm2.Position = new CoordinateRect(1.1, 2.1, 0, 1);
hm2.Smooth = true;

myPlot.SavePng("demo.png", 400, 300);

Transparent Cells

Assign double.NaN to a heatmap cell to make it transparent.

ScottPlot.Plot myPlot = new();

// start with 2D data and set some cells to NaN
double[,] data = SampleData.MonaLisa();
for (int y = 20; y < 80; y++)
{
    for (int x = 20; x < 60; x++)
    {
        data[y, x] = double.NaN;
    }
}

// create a line chart
myPlot.Add.Signal(Generate.Sin());
myPlot.Add.Signal(Generate.Cos());

// plot the heatmap on top of the line chart
var hm1 = myPlot.Add.Heatmap(data);
hm1.Position = new(10, 35, -1.5, .5);

// the NaN transparency color can be customized
var hm2 = myPlot.Add.Heatmap(data);
hm2.Position = new(40, 55, -.5, .75);
hm2.NaNCellColor = Colors.Magenta.WithAlpha(.4);

myPlot.SavePng("demo.png", 400, 300);

Global Transparency

The transparency of the entire heatmap can be adjusted.

ScottPlot.Plot myPlot = new();

double[,] data = SampleData.MonaLisa();

// create a line chart
myPlot.Add.Signal(Generate.Sin());
myPlot.Add.Signal(Generate.Cos());

// plot the heatmap on top of the line chart
var hm = myPlot.Add.Heatmap(data);
hm.Position = new(10, 35, -1.5, .5);
hm.Opacity = 0.5;

myPlot.SavePng("demo.png", 400, 300);

Alpha Map

An alpha map (a 2d array of byte values) can be used to apply custom transparency to each cell of a heatmap.

ScottPlot.Plot myPlot = new();

// data values are translated to color based on the heatmap's colormap
double[,] data = SampleData.MonaLisa();

// an alpha map controls transparency of each cell
byte[,] alphaMap = new byte[data.GetLength(0), data.GetLength(1)];

// fill the alpha map with values from 0 (transparent) to 255 (opaque)
for (int y = 0; y < alphaMap.GetLength(0); y++)
{
    for (int x = 0; x < alphaMap.GetLength(1); x++)
    {
        double fractionAcross = (double)x / alphaMap.GetLength(1);
        alphaMap[y, x] = (byte)(fractionAcross * 255);
    }
}

// create a line chart
myPlot.Add.Signal(Generate.Sin());
myPlot.Add.Signal(Generate.Cos());

// plot the heatmap on top of the line chart
var hm = myPlot.Add.Heatmap(data);
hm.Position = new(10, 35, -1.5, .5);
hm.AlphaMap = alphaMap;

myPlot.SavePng("demo.png", 400, 300);

Frameless Heatmap

A frameless heatmap can be achieved by disabling axis labels and ticks, then setting the margins to 0 so the data area tightly fits the data.

ScottPlot.Plot myPlot = new();

double[,] data = {
    { 1, 2, 3 },
    { 4, 5, 6 },
    { 7, 8, 9 },
};

// add a heatmap to the plot
myPlot.Add.Heatmap(data);

// hide axes on all edges of the figure
myPlot.Layout.Frameless();

// disable padding around the heatmap data
myPlot.Axes.Margins(0, 0);

myPlot.SavePng("demo.png", 400, 300);

HeatmapCellAlignment

Heatmap cells are aligned in their centers by default. This means that the bottom left cell will be centered at (0, 0), and its lower left corner will be to the lower left of the origin. Setting sell alignment to lower left causes the lower left of the heatmap to be exactly at (0, 0).

ScottPlot.Plot myPlot = new();

double[,] data = {
    { 1, 2, 3 },
    { 4, 5, 6 },
    { 7, 8, 9 },
};

var hm = myPlot.Add.Heatmap(data);
hm.CellAlignment = Alignment.LowerLeft;

myPlot.SavePng("demo.png", 400, 300);

Heatmap Cell Size

Dimensions of a heatmap may be set by specifying how large a cell should be in pixel units.

ScottPlot.Plot myPlot = new();

double[,] data = {
    { 1, 2, 3 },
    { 4, 5, 6 },
    { 7, 8, 9 },
};

var hm = myPlot.Add.Heatmap(data);
hm.CellAlignment = Alignment.LowerLeft;
hm.CellWidth = 100;
hm.CellHeight = 10;

myPlot.SavePng("demo.png", 400, 300);

Heatmap Rectangle

Dimensions of a heatmap may be set by defining a rectangle that the heatmap will be rendered inside.

ScottPlot.Plot myPlot = new();

// create a heatmap of any size
double[,] data = {
    { 1, 2, 3 },
    { 4, 5, 6 },
    { 7, 8, 9 },
};

// add the heatmap to the plot
var hm = myPlot.Add.Heatmap(data);

// place the heatmap in a rectangle defined in coordinate space
hm.Rectangle = new CoordinateRect(-5, 5, -5, 5);

myPlot.SavePng("demo.png", 400, 300);

Heatmap with Manual Color Range

The user can define the range of values to represent with colors in the colormap. Values outside that range will be clipped to the nearest color in the colormap.

ScottPlot.Plot myPlot = new();

// sample data values range from 0-255
double[,] data = SampleData.MonaLisa();

// add a heatmap and colorbar to the plot
var hm = myPlot.Add.Heatmap(data);
hm.Colormap = new ScottPlot.Colormaps.Turbo();
myPlot.Add.ColorBar(hm);

// force the colormap to span a manual range of values
hm.ManualRange = new(50, 150);

myPlot.SavePng("demo.png", 400, 300);

Heatmap Cell Labels

Text may be placed over cells to provide cell labels. In interactive applications MouseMove events may be used to remove old labels and only display a label over the cell beneath the mouse. See the ScottPlot Demo page for more information and code samples.

ScottPlot.Plot myPlot = new();

double[,] data = {
    { 1, 2, 3 },
    { 4, 5, 6 },
    { 7, 8, 9 },
};

var hm = myPlot.Add.Heatmap(data);

for (int y = 0; y < data.GetLength(0); y++)
{
    for (int x = 0; x < data.GetLength(1); x++)
    {
        Coordinates coordinates = new(x, y);
        string cellLabel = data[y, x].ToString("0.0");
        var text = myPlot.Add.Text(cellLabel, coordinates);
        text.Alignment = Alignment.MiddleCenter;
        text.LabelFontSize = 30;
        text.LabelFontColor = Colors.White;
    }
}

myPlot.SavePng("demo.png", 400, 300);

Heatmap with DateTime Axis

Heatmaps can be displayed on plots which use dates instead of numbers on the horizontal axis.

ScottPlot.Plot myPlot = new();

// add a heatmap to the plot
double[,] data = SampleData.MonaLisa();
var hm = myPlot.Add.Heatmap(data);

// define its height using numeric units
CoordinateRange yRange = new(0, 10);

// define its width using date units
DateTime start = new(2024, 01, 01);
DateTime end = new(2025, 01, 01);
CoordinateRange xRange = new(start.ToOADate(), end.ToOADate());

// apply width and height to the heatmap
hm.Rectangle = new(xRange, yRange);

// tell the plot to use date formatting for X axis tick labels
myPlot.Axes.DateTimeTicksBottom();

myPlot.SavePng("demo.png", 400, 300);