ComponentOne FlexChart for WPF
Heat Map
FlexChart > Understanding FlexChart > FlexChart Types > Heat Map

A heat map is a graphical representation of tabular data values through color coding and shading. Heat map helps in identifying patterns, areas of concentration, and data variance. The heat map data is represented by a two-dimensional matrix. You can use the heat map chart to plot data like event schedule, temperature records, weekly traffic intensity, etc.

A heat map chart can showcase different visual representations depending upon the type of data. Heat map chart can therefore be categorized into two types.

  1. Category based heat map
  2. Value based heat map

Category based heat map

When you want to plot the data against intervals or specific numeric ranges, you can create a category based heat map. To implement category based heat map chart, you need to use the DiscreteColorScale class. It provides Intervals property that allows you to get or set the collection of intervals. Set the MinMaxColor, and Name properties for each interval. So, the data points belonging to a particular interval are represented by the same color. The list of user-defined intervals is shown on the chart legend.

For example, if you use heat map chart to show the weekly traffic intensity of a city, you can use the DiscreteColorScale class and add intervals such as very low, low, normal, and set its corresponding min, max, and color property.

The following image shows a category based heat map.

Use the following code snippet to create a category based heat map.

XAML
Copy Code
<UserControl x:Class="ExtendedFeatures.Samples.Loading"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:c1="http://schemas.componentone.com/winfx/2006/xaml"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <Grid>
        <c1:C1FlexChart x:Name="chart" Loaded="ChartLoaded" 
                        Header="Weekly traffic intensity"
                        ToolTipContent="{}{item:0.0}%" LegendPosition="Bottom">
            <c1:C1FlexChart.HeaderStyle>
                <c1:ChartStyle FontSize="20" />
            </c1:C1FlexChart.HeaderStyle>

            <c1:C1FlexChart.AxisX>
                <c1:Axis AxisLine="False" MajorGrid="False" MajorTickMarks="None" LabelAngle="45" 
                         MinorGrid="True">
                    <c1:Axis.MinorGridStyle>
                        <c1:ChartStyle Stroke="White" StrokeThickness="1" />
                    </c1:Axis.MinorGridStyle>
                </c1:Axis>
            </c1:C1FlexChart.AxisX>
            <c1:C1FlexChart.AxisY>
                <c1:Axis AxisLine="False" MajorGrid="False" MajorTickMarks="None" Reversed="True" 
                         MinorGrid="True">
                    <c1:Axis.MinorGridStyle>
                        <c1:ChartStyle Stroke="White" StrokeThickness="1"/>
                    </c1:Axis.MinorGridStyle>
                </c1:Axis>
            </c1:C1FlexChart.AxisY>
        </c1:C1FlexChart>
    </Grid>
</UserControl>
C#
Copy Code
public partial class Loading : UserControl
    {
        public Loading()
        {
            InitializeComponent();
        }
        private void ChartLoaded(object sender, RoutedEventArgs e)
        {
            chart.BeginUpdate();
            var scale = new DiscreteColorScale() { Intervals = new List<DiscreteColorScale.Interval>() };
            scale.Intervals.Add(new DiscreteColorScale.Interval(0, 10, Color.FromRgb(0x05,0x71,0xB0), "Very Low"));
            scale.Intervals.Add(new DiscreteColorScale.Interval(10, 25, Color.FromRgb(0x92, 0xC5, 0xDE), "Low"));
            scale.Intervals.Add(new DiscreteColorScale.Interval(25, 75, Color.FromRgb(0xD7, 0xD7, 0xD7), "Normal"));
            scale.Intervals.Add(new DiscreteColorScale.Interval(75, 90, Color.FromRgb(0xF4, 0xA5, 0x82), "High"));
            scale.Intervals.Add(new DiscreteColorScale.Interval(90, 100, Color.FromRgb(0xCA, 0x00, 0x20), "Critical"));

            var rnd = new Random();
            var data = new double[24, 7];
            for (var j = 0; j < 7; j++)
                for (var i = 0; i < 24; i++)
                    data[i, j] = 10 * Math.Exp(-(i - 12) * (i - 12) / (2 * 4.0 * 4.0))
                    / Math.Sqrt(2 * Math.PI * 4.0 * 4.0) * ((j == 5 || j == 6) ? 50 : 100)
                    * rnd.NextDouble();

            var hmap = new Heatmap();
            hmap.ItemsSource = data;
            hmap.ColorScale = scale;
            chart.Series.Add(hmap);

            var times = new string[24];
            for (var i = 0; i < 24; i++)
                times[i] = new DateTime(2000, 1, 1, i, 0, 0).ToShortTimeString();
            chart.AxisX.ItemsSource = times;
            chart.AxisY.ItemsSource = new string[] { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" };
            chart.EndUpdate();
        }
    }

Value based heat map

When you want to plot the raw data values without dividing them into intervals, you can create a value based heat map. To implement the value-based heat map, you need to use the GradientColorScale class. By default, a heat map is rendered with the chart legend. Each legend entry corresponds to a numeric value between the Min and Max values. The interval used to generate the numeric values for the legend entries is calculated by using the formula (|Min| + |Max|)/(n-1) where n refers to the number of colors specified in the Colors property.

For example, a simple custom palette containing red, white and blue color maps the values from -30 to 30 to shades of red, white, blue, where -30 is mapped to red and 30 to blue.

The following image shows a value based heat map.


Use the following code snippet to create a value based heat map.

XAML
Copy Code
<UserControl x:Class="ExtendedFeatures.Samples.Temperature"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:c1="http://schemas.componentone.com/winfx/2006/xaml"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300" >
    <Grid>
        <c1:C1FlexChart x:Name="chart" Loaded="ChartLoaded" Rotated="True"
                        Header="Average temperature by month" ToolTipContent="">
            <c1:C1FlexChart.HeaderStyle>
                <c1:ChartStyle FontSize="20" />
            </c1:C1FlexChart.HeaderStyle>
            <c1:C1FlexChart.DataLabel>
                <c1:DataLabel Content="{}{item}" Position="Center" />
            </c1:C1FlexChart.DataLabel>
            <c1:C1FlexChart.AxisX>
                <c1:Axis AxisLine="False" MajorGrid="False" MajorTickMarks="None" />
            </c1:C1FlexChart.AxisX>
        </c1:C1FlexChart>
    </Grid>
</UserControl>
C#
Copy Code
public partial class Temperature : UserControl
    {
        public Temperature()
        {
            InitializeComponent();
        }
        private void ChartLoaded(object sender, RoutedEventArgs e)
        {
            chart.BeginUpdate();
            chart.AxisY.MajorGrid = false;

            var scale = new GradientColorScale() { Min = -30, Max = 30 };
            scale.Colors = new List<Color> { Colors.Blue, Colors.White, Colors.Red };

            var hmap = new Heatmap();
            hmap.ItemsSource = new double[,] {
                {  3.0, 3.1, 5.7, 8.2, 12.5, 15.0, 17.1, 17.1, 14.3, 10.6, 6.6, 4.3 },
                { -9.3, -7.7, -2.2, 5.8, 13.1, 16.6, 18.2, 16.4, 11.0, 5.1, -1.2, -6.1},
                 { -15.1, -12.5, -5.2, 3.1, 10.1, 15.5, 18.3, 15.0, 9.4, 1.4, -5.6, -11.4},
                };
            hmap.ColorScale = scale;
            chart.Series.Add(hmap);
            chart.AxisX.ItemsSource = new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
            chart.AxisY.ItemsSource = new string[] { "Amsterdam", "Moscow", "Perm" };
            chart.EndUpdate();
        }
    }

The default chart legend can be replaced with a gradient chart legend by using the ColorAxis class. Gradient chart legend is a small bar of integrated colors obtained from the Colors definitions. Each color is for a specific numeric range and it integrates with the next color, creating a gradient legend. Every point on the gradient legend represents a distinctive color and value. Therefore, all the dissimilar values in the chart appear in distinctive colors as per the position on the gradient legend.

To implement heat map with a gradient legend, you need to provide an instance of ColorAxis class to the Axis property provided by the
GradientColorScale class. Moreover, you also need to specify the Min, Max and Colors property of GradientColorScale class to set up a gradient legend.

The following image shows a value based heat map with gradient legends.

Use the following code snippet to create a value based heat map with gradient legends.

XAML
Copy Code
<UserControl x:Class="ExtendedFeatures.Samples.Temperature"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:c1="http://schemas.componentone.com/winfx/2006/xaml"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300" >
    <Grid>
        <c1:C1FlexChart x:Name="chart" Loaded="ChartLoaded" Rotated="True"
                        Header="Average temperature by month" ToolTipContent="">
            <c1:C1FlexChart.HeaderStyle>
                <c1:ChartStyle FontSize="20" />
            </c1:C1FlexChart.HeaderStyle>
            <c1:C1FlexChart.DataLabel>
                <c1:DataLabel Content="{}{item}" Position="Center" />
            </c1:C1FlexChart.DataLabel>
            <c1:C1FlexChart.AxisX>
                <c1:Axis AxisLine="False" MajorGrid="False" MajorTickMarks="None" />
            </c1:C1FlexChart.AxisX>
        </c1:C1FlexChart>
    </Grid>
</UserControl>
C#
Copy Code
public partial class Temperature : UserControl
    {
        public Temperature()
        {
            InitializeComponent();
        }
        private void ChartLoaded(object sender, RoutedEventArgs e)
        {
            chart.BeginUpdate();
            chart.AxisY.MajorGrid = false;

            var scale = new GradientColorScale() { Min = -30, Max = 30 };
            scale.Axis = scale.Axis = new C1.WPF.Chart.Extended.ColorAxis()
            { Position = Position.Right, Title = "temprature, celcius" };
            scale.Colors = new List<Color> { Colors.Blue, Colors.White, Colors.Red };

            var hmap = new Heatmap();
            hmap.ItemsSource = new double[,] {
                {  3.0, 3.1, 5.7, 8.2, 12.5, 15.0, 17.1, 17.1, 14.3, 10.6, 6.6, 4.3 },
                { -9.3, -7.7, -2.2, 5.8, 13.1, 16.6, 18.2, 16.4, 11.0, 5.1, -1.2, -6.1},
                 { -15.1, -12.5, -5.2, 3.1, 10.1, 15.5, 18.3, 15.0, 9.4, 1.4, -5.6, -11.4},
                };
            hmap.ColorScale = scale;
            chart.Series.Add(hmap);
            chart.AxisX.ItemsSource = new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
            chart.AxisY.ItemsSource = new string[] { "Amsterdam", "Moscow", "Perm" };
            chart.EndUpdate();
        }
    }
See Also

Reference