FlexChart for WinForms
WinForms ヒートマップ
WinForms のチャートタイプ > 特殊チャート > WinForms ヒートマップ

ヒートマップは、色分けを使用して 2 次元データをプロットするグラフィカル表現です。ヒートマップの主要な目的は、パターン、集中領域、データ差異を特定することです。ヒートマップを活用できる実用的な例としては、気温の記録や、1 週間の交通量の表示などがあります。

使用するデータのタイプに応じて、ヒートマップは、カテゴリベースと値ベースの 2 種類の視覚表現で作成できます。

カテゴリベースの WinForms ヒートマップ

カテゴリベースのヒートマップは、区間または特定の数値範囲に対してデータをプロットするために使用されます。FlexChart を使用してカテゴリベースの WinForms ヒートマップを作成するには、DiscreteColorScale クラスのインスタンスを作成する必要があります。このクラスは、区間のコレクションを取得または設定するための Intervals プロパティを提供します。各区間の Min プロパティ、Max プロパティ、Color プロパティ、Name プロパティを設定することで、区間を定義できます。これらのユーザー定義の区間によってヒートマップの凡例が形成されます。次に、Heatmap 系列を作成し、DataSource プロパティを設定することによってその系列にデータを提供し、その ColorScale プロパティに DiscreteColorScale オブジェクトを設定します。

カテゴリベースの WinForms ヒートマップ

// FlexChartのヘッダーを設定します
this.flexChart1.Header.Content = "Weekly Traffic Intensity";

// データを取得します
var data = Get2DTrafficData();
            
// ヒートマップのカテゴリとその範囲を定義します
var discreteScale = new DiscreteColorScale
{
    Intervals = new List<DiscreteColorScale.Interval>
    {
        new DiscreteColorScale.Interval(0, 10, Color.FromArgb(0x05,0x71,0xB0), "Very Low"),
        new DiscreteColorScale.Interval(10, 25, Color.FromArgb(0x92, 0xC5, 0xDE), "Low"),
        new DiscreteColorScale.Interval(25, 75, Color.FromArgb(0xD7, 0xD7, 0xD7), "Normal"),
        new DiscreteColorScale.Interval(75, 90, Color.FromArgb(0xF4, 0xA5, 0x82), "High"),
        new DiscreteColorScale.Interval(90, 100, Color.FromArgb(0xCA, 0x00, 0x20), "Critical"),
    }
};

// ヒートマップを作成し、色のスケールを定義してデータを渡します
var heatmap = new Heatmap
{
    ColorScale = discreteScale,
    DataSource = data.Values,
};

// ヒートマップをFlexChartの系列として追加します
this.flexChart1.Series.Add(heatmap);

#region Axis Style

// データに従ってX軸の最小値と最大値を定義します
this.flexChart1.AxisX.Min = heatmap.StartX;
this.flexChart1.AxisX.Max = data.Values.GetLength(0) + heatmap.StartX;

// X軸のグリッド線を設定します
this.flexChart1.AxisX.MinorGrid = true;
this.flexChart1.AxisX.MinorGridStyle.StrokeColor = Color.White;
this.flexChart1.AxisX.LabelAngle = 45;

// Y軸のグリッド線を設定します
this.flexChart1.AxisY.MajorGrid = false;
this.flexChart1.AxisY.MinorGrid = true;
this.flexChart1.AxisY.MinorGridStyle.StrokeColor = Color.White;

// データをFlexChartに渡します 
this.flexChart1.AxisX.DataSource = data.CatXData;
this.flexChart1.AxisY.DataSource = data.CatYData;
        ''' <summary>
        ''' ヒートマップを初期化するメソッド
        ''' </summary
        Protected Sub SetupHeatMap()
            ' 系列をクリアします
            Me.flexChart1.Series.Clear()

            ' FlexChartのヘッダーを設定します
            Me.flexChart1.Header.Content = "Weekly Traffic Intensity"

            ' データを取得します
            Dim data As TwoDDataItem = Get2DTrafficData()

            ' ヒートマップのカテゴリとその範囲を定義します
            Dim discreteScale As DiscreteColorScale = New DiscreteColorScale() With {
                 .Intervals = New List(Of DiscreteColorScale.Interval)() From {
                    New DiscreteColorScale.Interval(0, 10, Color.FromArgb(&H5, &H71, &HB0), "Very Low"),
                    New DiscreteColorScale.Interval(10, 25, Color.FromArgb(&H92, &HC5, &HDE), "Low"),
                    New DiscreteColorScale.Interval(25, 75, Color.FromArgb(&HD7, &HD7, &HD7), "Normal"),
                    New DiscreteColorScale.Interval(75, 90, Color.FromArgb(&HF4, &HA5, &H82), "High"),
                    New DiscreteColorScale.Interval(90, 100, Color.FromArgb(&HCA, &H0, &H20), "Critical")
                }
            }

            ' ヒートマップを作成し、色のスケールを定義してデータを渡します
            Dim heatmap As Heatmap = New Heatmap() With {
                 .ColorScale = discreteScale,
                 .DataSource = data.Values
            }

            ' ヒートマップをFlexChartの系列として追加します
            Me.flexChart1.Series.Add(heatmap)

#Region "Axis Style"

            ' データに従ってX軸の最小値と最大値を定義します
            Me.flexChart1.AxisX.Min = heatmap.StartX
            Me.flexChart1.AxisX.Max = data.Values.GetLength(0) + heatmap.StartX

            ' X軸のグリッド線を設定します
            Me.flexChart1.AxisX.MinorGrid = True
            Me.flexChart1.AxisX.MinorGridStyle.StrokeColor = Color.White
            Me.flexChart1.AxisX.LabelAngle = 45

            ' Y軸のグリッド線を設定します
            Me.flexChart1.AxisY.MajorGrid = False
            Me.flexChart1.AxisY.MinorGrid = True
            Me.flexChart1.AxisY.MinorGridStyle.StrokeColor = Color.White

            ' データをFlexChartに渡します 
            Me.flexChart1.AxisX.DataSource = data.CatXData
            Me.flexChart1.AxisY.DataSource = data.CatYData

上記のサンプルコードは、Get2DTrafficData という名前のカスタムメソッドを使用してチャートにデータを提供しています。要件に基づいてデータソースを設定できます。

/// <summary>
/// ヒートマップのデータを作成するメソッド
/// </summary>
Random rnd = new Random();
public TwoDDataItem Get2DTrafficData()
{
    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 times = new string[24];
    for (var i = 0; i < 24; i++)
        times[i] = new DateTime(2000, 1, 1, i, 0, 0).ToShortTimeString();
    var days = Enum.GetNames(typeof(DayOfWeek));
    return new TwoDDataItem(data, times, days);
}
''' <summary>
''' ヒートマップのデータを作成するメソッド
''' </summary>
Private rnd As New Random()
Public Function Get2DTrafficData() As TwoDDataItem
    Dim data As Double(,) = New Double(23, 6) {}
    For j As Integer = 0 To 6
        For i As Integer = 0 To 23
            data(i, j) = 10 * Math.Exp(-(i - 12) * (i - 12) / (2 * 4.0 * 4.0)) / Math.Sqrt(2 * Math.PI * 4.0 * 4.0) * (If((j = 5 OrElse j = 6), 50, 100)) * rnd.NextDouble()
        Next
    Next
    Dim times As String() = New String(23) {}
    For i As Integer = 0 To 23
        times(i) = New DateTime(2000, 1, 1, i, 0, 0).ToShortTimeString()
    Next
    Dim days As String() = [Enum].GetNames(GetType(DayOfWeek))
    Return New TwoDDataItem(data, times, days)
End Function

値ベースの WinForms ヒートマップ

値ベースのヒートマップは、生データ値を区間に分割せずにプロットするために使用されます。FlexChart を使用して値ベースの WinForms ヒートマップを作成するには、GradientColorScale クラスのインスタンスを作成する必要があります。値ベースのヒートマップの凡例は、最大値と最小値の間の数値に対応するエントリを使用して生成されます。これらの値の間隔は、数式 (|Min| + |Max|)/(n-1) に基づいて計算されます。ここで n は Colors プロパティで指定した色の数です。次に、Heatmap 系列を作成し、DataSource プロパティを設定することによってその系列にデータを提供し、その ColorScale プロパティに GradientColorScale オブジェクトを設定します。

たとえば、赤色、白色、青色から成るシンプルなカスタムパレットで、-30 〜 30 の値を赤、白、青の階調にマップします。ここで、-30 を赤に、30 を青にマップさせます。

値ベースの WinForms ヒートマップ

// FlexChartのヘッダーを設定します
this.flexChart1.Header.Content = "Average Temperature By Month";

// データを取得します
var data = Get2DTempData();

// ヒートマップとその範囲のグラデーションスケールを定義します
var gradientScale = new GradientColorScale
{
    Min = -30,
    Max = 30,
    Colors = new List<Color>
    {
        Color.Blue,
        Color.NavajoWhite,
        Color.Red
    }
};

// 凡例を設定します
this.flexChart1.Legend.Position = Position.Bottom;

// ヒートマップを作成し、色のスケールを定義してデータを渡します
var heatmap = new Heatmap()
{
    ColorScale = gradientScale,
    DataSource = data.Values,
};

// ヒートマップをFlexChartの系列として追加します
this.flexChart1.Series.Add(heatmap);

// データラベルとその位置を設定します
this.flexChart1.DataLabel.Content = "{item:0.0}";
this.flexChart1.DataLabel.Position = LabelPosition.Center;

#region Axis Style

this.flexChart1.AxisX.Position = Position.Top;
this.flexChart1.AxisY.Min = heatmap.StartX;
this.flexChart1.AxisY.Max = data.Values.GetLength(0) + heatmap.StartX;
this.flexChart1.AxisY.MajorGrid = false;
this.flexChart1.AxisY.AxisLine = true;

// データをFlexChartに渡します
this.flexChart1.AxisX.DataSource = data.CatXData;
this.flexChart1.AxisY.DataSource = data.CatYData;

this.flexChart1.Rotated = true;
        ''' <summary>
        ''' ヒートマップを初期化するメソッド
        ''' </summary
        Protected Sub SetupHeatMap()
            ' 系列をクリアします
            Me.flexChart1.Series.Clear()

            ' FlexChartのヘッダーを設定します
            Me.flexChart1.Header.Content = "Average Temperature By Month"

            ' データを取得します
            Dim data As TwoDDataItem = Get2DTempData()

            ' ヒートマップとその範囲のグラデーションスケールを定義します
            Dim gradientScale As GradientColorScale = New GradientColorScale() With {
                 .Min = -30,
                 .Max = 30,
                 .Colors = New List(Of Color)() From {
                    Color.Blue,
                    Color.NavajoWhite,
                    Color.Red
                }
            }

            ' 凡例を設定します
            Me.flexChart1.Legend.Position = Position.Bottom


            ' ヒートマップを作成し、色のスケールを定義してデータを渡します
            Dim heatmap As Heatmap = New Heatmap() With {
                 .ColorScale = gradientScale,
                 .DataSource = data.Values
            }

            ' ヒートマップをFlexChartの系列として追加します
            Me.flexChart1.Series.Add(heatmap)

            ' データラベルとその位置を設定します
            Me.flexChart1.DataLabel.Content = "{item:0.0}"
            Me.flexChart1.DataLabel.Position = LabelPosition.Center

#Region "Axis Style"

            Me.flexChart1.AxisX.Position = Position.Top
            Me.flexChart1.AxisY.Min = heatmap.StartX
            Me.flexChart1.AxisY.Max = data.Values.GetLength(0) + heatmap.StartX
            Me.flexChart1.AxisY.MajorGrid = False
            Me.flexChart1.AxisY.AxisLine = True

            ' データをFlexChartに渡します
            Me.flexChart1.AxisX.DataSource = data.CatXData
            Me.flexChart1.AxisY.DataSource = data.CatYData

            Me.flexChart1.Rotated = True

上記のサンプルコードは、Get2DTempData という名前のカスタムメソッドを使用してチャートにデータを提供しています。要件に基づいてデータソースを設定できます。

/// <summary>
/// ヒートマップのデータを作成するするメソッド
/// </summary>
public static TwoDDataItem Get2DTempData()
{
    var data = 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},
    };
    var months = new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
    var areas = new string[] { "Amsterdam", "Moscow", "Perm" };
    return new TwoDDataItem(data, months, areas);
}
''' <summary>
''' ヒートマップのデータを作成するするメソッド
''' </summary>
Public Shared Function Get2DTempData() As TwoDDataItem
    Dim data As Double(,) = 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}}
    Dim months As String() = New String() {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
        "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}
    Dim areas As String() = New String() {"Amsterdam", "Moscow", "Perm"}
    Return New TwoDDataItem(data, months, areas)
End Function

グラデーション付き凡例の使用

他のチャートと同様に、ヒートマップにも生成時にデフォルトで凡例が付きます。ただし、ColorAxis クラスを使用して、ヒートマップのデフォルトのチャート凡例をグラデーション付きチャート凡例に置き換えることができます。グラデーション付きチャート凡例は、Colors 定義から得られる色の組み合わせで構成される小さなバーです。各色は特定の数値範囲に対応し、隣の色とブレンドされてグラデーション付き凡例になります。グラデーション付き凡例の各ポイントは、それぞれ異なる色と値を表します。したがって、チャート内の異なる値はすべて、グラデーション付き凡例での位置に応じてそれぞれ異なる色で表示されます。

グラデーション付き凡例を持つヒートマップを実装するには、GradientColorScale クラスにある Axis プロパティに ColorAxis クラスのインスタンスを提供する必要があります。さらに、Min、Max、および Colors プロパティを指定してグラデーション付き凡例を設定する必要があります。また、色軸にデータソースを提供することで、グラデーション付き凡例に値の代わりに定義済みカテゴリをラベル付けするように選択することもできます。

値を使用したグラデーション付き凡例

カテゴリを使用したグラデーション付き凡例

値を使用した凡例 カテゴリを使用した凡例
 //HeatMap のグラデーションスケールと範囲を定義します
    var gradientScale = new GradientColorScale
    {
        Min = -30,
        Max = 30,
        Colors = new List<Color>
        {
           Color.Blue,
           Color.NavajoWhite,
           Color.Red,
        }, 
        Axis = new ColorAxis
       {
           Position = Position.Right,
     // 色軸のデータソースを設定します 
     // 凡例と共にカテゴリをレンダリングする場合にのみ必要です                     
        //   DataSource = new List<object>()
        //   {
        //      new { Value = -30, Text = "Freezing" },
        //      new { Value = 0, Text = "Warm" },
        //      new { Value = 30, Text = "Hot" }
        //  }
       }
   };

 //グラデーション軸に沿って値が徐々に変化するため、凡例を非表示にします
   this.flexChart1.Legend.Position = Position.None;       
       'Define gradient scale for HeatMap and its range

        Dim gradientScale As GradientColorScale = New GradientColorScale() With {
               .Min = -30,
               .Max = 30,
               .Colors = New List(Of Color)() From {
                Color.Blue,
                Color.NavajoWhite,
                Color.Red
             },
               .Axis = New ColorAxis() With {
                     .Position = Position.Right
         '           .DataSource = New List(Of Object)() From {
         '   New With {.Value = -30, .Text = "Freezing"},
         '   New With {.Value = 0, .Text = "Warm"},
         '   New With {.Value = 30, .Text = "Hot"}
         '}
      }
   }

       'Hiding legends as the values change gradually in along the gradient axis
        Me.flexChart1.Legend.Position = Position.None