SciChart iOS v2.x API > 2D Chart Types > The Heatmap Series Type
The Heatmap Series Type

Heatmaps are provided by the SCIFastUniformHeatmapRenderableSeries, which consumes data from a SCIUniformHeatmapDataSeries. This is designed to display 2D arrays of data with real values. Every item in the 2D array is represented as a colored rectangle (“cell”); the color depends on corresponding item’s value.

Examples for the Heatmap Series can be found in the SciChart iOS Examples Suite

 

 

Example: Declaring a SCIHeatMapRenderableSeries

To declare a SCIFastUniformHeatmapRenderableSeries use the following code:

 

// Create a SCIChartSurface instance
SCIChartSurface * _sciChartSurface = [[SCIChartSurface alloc]initWithFrame:frame];
// NOTE: You will need to add the SCIChartSurface as a SubView to your View
//
// Declare a Heatmap DataSeries with X,Y,Z datatype, Size in X,Y (array size)
// and StartX, StepX, StartY, StepY values
int WIDTH = 100;
int HEIGHT = 100;
SCIUniformHeatmapDataSeries * heatmapDataSeries = [[SCIUniformHeatmapDataSeries alloc] initWithTypeX:SCIDataType_Double
        Y:SCIDataType_Double
        Z:SCIDataType_Double
        SizeX:WIDTH Y:HEIGHT
        StartX:SCIGeneric(0.0)
        StepX:SCIGeneric(1.0)
        StartY:SCIGeneric(0.0)
        StepY:SCIGeneric(1.0)];
// Access the 2D array of Z-values that the heatmap holds
SCIArrayController2D* zValues = heatmapDataSeries.zValues;
// Populate the heatmap Z-values
for (int i=0; i<WIDTH; i++) {
    for (int j=0; j<HEIGHT; j++) {
        [zValues setValue:SCIGeneric((double)i*j/10) AtX:i Y:j];
    }
}
// Declare a Heatmap Data Series and set style
SCIFastUniformHeatmapRenderableSeries * heatmapRenderableSeries = [[SCIFastUniformHeatmapRenderableSeries alloc] init];
[heatmapRenderableSeries setMinimum:0];
[heatmapRenderableSeries setMaximum:1000];
[heatmapRenderableSeries setDataSeries:heatmapDataSeries];
// Note Surface must have an XAxis/YAxis of type SCINumericAxis to match the Double,float data
id<SCIAxis2DProtocol> axis = [[SCINumericAxis alloc] init];
[axis setGrowBy: [[SCIDoubleRange alloc]initWithMin:SCIGeneric(0.1) Max:SCIGeneric(0.1)]];
[_sciChartSurface.yAxes add:axis];
axis = [[SCINumericAxis alloc] init];
[axis setGrowBy: [[SCIDoubleRange alloc]initWithMin:SCIGeneric(0.1) Max:SCIGeneric(0.1)]];
[_sciChartSurface.xAxes add:axis];
// Add the Render Series to an existing SciChartSurface
[_sciChartSurface.renderableSeries add:heatmapRenderableSeries];
// Create a SCIChartSurface instance
//var sciChartSurface = SCIChartSurface(frame: frame)
// NOTE: You will need to add the SCIChartSurface as a SubView to your View
//
// Declare a Heatmap DataSeries with X,Y,Z datatype, Size in X,Y (array size)
// and StartX, StepX, StartY, StepY values
let WIDTH = Int32(100);
let HEIGHT = Int32(100);
var heatmapDataSeries = SCIUniformHeatmapDataSeries(typeX: .double, y: .double, z: .double,
                                                    sizeX: WIDTH, y: HEIGHT,
                                                    startX: SCIGeneric(0.0), stepX: SCIGeneric(1.0),
                                                    startY: SCIGeneric(0.0), stepY: SCIGeneric(1.0))
// Access the 2D array of Z-values that the heatmap holds
let zValues = heatmapDataSeries.zValues();
// Populate the heatmap Z-values
for i in 0..<WIDTH {
    for j in 0..<HEIGHT {
        zValues.setValue(SCIGeneric(Double(i*j/10)), atX: i, y: j)
    }
}
// Declare a Heatmap Render Series and set style
var heatmapRenderableSeries = SCIFastUniformHeatmapRenderableSeries()
heatmapRenderableSeries.minimum = 0
heatmapRenderableSeries.maximum = 1000
heatmapRenderableSeries.dataSeries = heatmapDataSeries
// Note Surface must have an XAxis/YAxis of type SCINumericAxis to match the Double,Double data
let xAxis = SCINumericAxis()
xAxis.growBy = SCIDoubleRange(min: SCIGeneric(0.1), max: SCIGeneric(0.1))
sciChartSurface.xAxes.add(xAxis)
let yAxis = SCINumericAxis()
yAxis.growBy = SCIDoubleRange(min: SCIGeneric(0.1), max: SCIGeneric(0.1))
sciChartSurface.yAxes.add(yAxis)
// Add the Render Series to an existing SciChartSurface
sciChartSurface.renderableSeries.add(heatmapRenderableSeries)
// Create a SCIChartSurface instance
var sciChartSurface = new SCIChartSurface();

// NOTE: You will need to add the SCIChartSurface as a SubView to your View
//
// Declare a new Heatmap DataSeries with XType Double, and YType Double
int width = 100;
int height = 100;
int xStart = 0;
int xStep = 1;
int yStart = 0;
int yStep = 1;
double[,] zValues = new double[width, height];
var heatmapDataSeries = new UniformHeatmapDataSeries<double,double,double>(zValues,
                                                                           xStart,
                                                                           xStep,
                                                                           yStart,
                                                                           yStep);
// Append some data.
for (int i = 0; i < width; i++)
{
    for (int j = 0; j < height; j++)
    {
        zValues[i, j] = i * j / 10;
    }
}
// Create a RenderableSeries and apply DataSeries
var heatmapRenderableSeries = new SCIFastUniformHeatmapRenderableSeries();
heatmapRenderableSeries.Minimum = 0;
heatmapRenderableSeries.Maximum = 1000;
heatmapRenderableSeries.DataSeries = heatmapDataSeries;
// Note Surface must have an XAxis/YAxis of type SCINumericAxis to match the float,float data
var xAxis = new SCINumericAxis { GrowBy = new SCIDoubleRange(0.1, 0.1) };
sciChartSurface.XAxes.Add(xAxis);
var yAxis = new SCINumericAxis { GrowBy = new SCIDoubleRange(0.1, 0.1) };
sciChartSurface.YAxes.Add(yAxis);
// Add the Render Series to an existing SciChartSurface
sciChartSurface.RenderableSeries.Add(heatmapRenderableSeries);

 

Updating Data in the Heatmap

You can update the data and force a refresh by simply updating the array passed in. To do this, use the following code:

Objective C:

Updating Heatmap data series
Copy Code
[heatmapDataSeries updateZValues:data[increment] Size:WIDTH*HEIGHT];

Swift:

Declaring a SCIFastMountainRenderableSeries Instance
Copy Code
heatmapDataSeries.updateZValues(data[increment], size: Int32(height*width))

 

How X,Y Values are Defined for the Chart X/Y Axes

Converting DataValues to Colors (Defining a Color Map)

Conversion of data value into color is defined by three properties: FastHeatMapRenderableSeries.Style.palette, FastHeatMapRenderableSeries.Style.min and FastHeatMapRenderableSeries.Style.max. There is a default Palette for FastHeatMapRenderableSeries, however you can define a custom as follows:

offset = 0 corresponds to FastHeatMapRenderableSeries.Style.min data value, offset=1 corresponds to FastHeatMapRenderableSeries.Style.max data value. By default Minimum = 0, Maximum = 1. You can set custom Minimum, Maximum and palette:

Objective C:

Defining ColorMap
Copy Code
    float *gradientCoord = malloc(sizeof(float)*6);
    gradientCoord[0] = 0.f;
    gradientCoord[1] = 0.2f;
    gradientCoord[2] = 0.4f;
    gradientCoord[3] = 0.6f;
    gradientCoord[4] = 0.8f;
    gradientCoord[5] = 1.f;
   
    uint *gradientColor = malloc(sizeof(uint)*6);
    gradientColor[0] = 0xFF00008B;
    gradientColor[1] = 0xFF6495ED;
    gradientColor[2] = 0xFF006400;
    gradientColor[3] = 0xFF7FFF00;
    gradientColor[4] = 0xFFFFFF00;
    gradientColor[5] = 0xFFFF0000;
   
    SCITextureOpenGL *_colorMap = [[SCITextureOpenGL alloc] initWithGradientCoords:gradientCoord Colors:gradientColor Count:6];
   
    [heatmapRenderableSeries setColorMap:_colorMap];

Swift:

Defining ColorMap
Copy Code
        let countColors = 6
       
        let stops = UnsafeMutablePointer<Float>.allocate(capacity: countColors)
        stops[0] = 0.0
        stops[1] = 0.2
        stops[2] = 0.4
        stops[3] = 0.6
        stops[4] = 0.8
        stops[5] = 1.0
       
        let gradientColor = UnsafeMutablePointer<uint>.allocate(capacity: countColors)
        gradientColor[0] = 0xFF00008B;
        gradientColor[1] = 0xFF6495ED;
        gradientColor[2] = 0xFF006400;
        gradientColor[3] = 0xFF7FFF00;
        gradientColor[4] = 0xFFFFFF00;
        gradientColor[5] = 0xFFFF0000;
       
        let colorMap = SCITextureOpenGL.init(gradientCoords: stops,
                                             colors: gradientColor,
                                             count: Int32(countColors))
        
        heatRenderableSeries.colorMap = colorMap

 

The X,Y value Mapping Functions

In a SCIUniformHeatmapDataSeries there are no X and Y values, only Z-values provided by the 2D array. The X and Y values are determined from the heatmap size and the X and Y mapping functions passed in to the SCIUniformHeatmapDataSeries init method.

 

Still stuck?

You can check the Online iOS Heatmap Chart Example about using this kind of renderable series.

Also our series of Swift and Xamarin Tutorials here.

Finally, you can check our iOS Charts and Xamarin Charts GitHub Repositories where you can find the Examples Suite. It contatns 20+ examples and demostrates the use of different renderable series.