FlexChart for WinForms
WinForms 箱ひげ図
WinForms のチャートタイプ > 統計チャート > WinForms 箱ひげ図

箱ひげ図は、四分位数、平均、および異常値によって数値データの分布を表示する統計グラフです。その名のとおり、これらの値は箱とひげを使用して表現されます。箱は四分位数の範囲(下位四分位点、上位四分位点、および中央値)を示し、ひげは上下の四分位数の外側にあるばらつきを示します。ひげの外側にある点のことを異常値と言います。これらのチャートは、多数のグループやデータセット間で分布を比較するために便利です。たとえば、2 つの都市の気温の月較差を簡単に表示できます。

WinForms 箱ひげ図

WinForms 箱ひげ図の作成

FlexChart で箱ひげ図を実装するには、箱ひげ図系列を表す BoxWhisker クラスを使用します。他の系列関連のプロパティとは別に、このクラスは箱ひげ図系列に固有のプロパティを提供し(QuartileCalculation プロパティなど)、それを使用して四分位数計算に中央値を含めるかどうかを指定できます。このプロパティは、QuartileCalculation 列挙に含まれる値を受け取ります。FlexChart には、ShowOutliers、ShowInnerPoints、ShowMeanLine、および ShowMeanMarks プロパティを介して異常値、内側ポイント、平均線、および平均マークを表示するかどうかを指定するオプションもあります。

WinForms 箱ひげ図をコードで作成するには、コントロールを初期化した後に、最初にデフォルトの系列をクリアし、Add メソッドを使用して新しい系列を追加します。DataSource プロパティを使用してデータソースを設定し、BindingX および Binding プロパティを設定して X 軸と Y 軸を構成します。また、ChartType などの必要なプロパティを使用して、チャートを設定する必要があります。

// 系列をクリアします
flexChart1.Series.Clear();

// BoxWhiskerを設定し、系列に追加します
var data = GetTemperatureData(new string[] { "New York", "Chicago" }, false, 365, true);
foreach (CityDataItem item in data)
{
    var ds = item.Data.GroupBy(x => x.Date.Month).SelectMany(grp => grp).OrderBy(x => x.Date.Day).Select(x => new PointD { X = x.Date.Month - 1, Y = x.HighTemp }).ToList();
    C1.Win.Chart.BoxWhisker boxWhisker = new C1.Win.Chart.BoxWhisker()
    {
        Name = item.Name,
        DataSource = ds,
        BindingX = "X",
        Binding = "Y",
        QuartileCalculation = QuartileCalculation.InclusiveMedian,
    };
    this.flexChart1.Series.Add(boxWhisker);
}
// データソースを指定します
flexChart1.DataSource = GetMonthAxisDataSource();           

// X軸の値を含むプロパティを設定します
flexChart1.BindingX = "Value,Name";
' 系列をクリアします
flexChart1.Series.Clear()

' BoxWhiskerを設定し、系列に追加します
Dim data As List(Of CityDataItem) = GetTemperatureData(New String() {"New York", "Chicago"}, False, 365, True)
For Each item As CityDataItem In data
    Dim ds As List(Of PointD) = item.Data.GroupBy(Function(x) x.[Date].Month).SelectMany(Function(grp) grp).OrderBy(Function(x) x.[Date].Day).[Select](Function(x) New PointD() With {
         .X = x.[Date].Month - 1,
         .Y = x.HighTemp
    }).ToList()
    Dim boxWhisker As New C1.Win.Chart.BoxWhisker() With {
         .Name = item.Name,
         .DataSource = ds,
         .BindingX = "X",
         .Binding = "Y",
         .QuartileCalculation = QuartileCalculation.InclusiveMedian
    }
    Me.flexChart1.Series.Add(boxWhisker)
Next
' データソースを指定します
flexChart1.DataSource = GetMonthAxisDataSource()

' X軸の値を含むプロパティを設定します
flexChart1.BindingX = "Value,Name"

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

/// <summary>
/// StatisticalChartのデータを作成するメソッド
/// </summary>
private DataSource _dataHelper = new DataSource().Instance;
private Random rnd = new Random();
public List<CategoricalPoint> GetMonthAxisDataSource()
{
    List<CategoricalPoint> data = new List<CategoricalPoint>();
    int i = 0;
    foreach (string month in _dataHelper.Months.Take(12))
    {
        data.Add(new CategoricalPoint { Name = month, Value = i });
        i++;
    }
    return data;
}
public List<CityDataItem> GetTemperatureData(string[] cities, bool monthly = false, int count = 30, bool isFahrenheit = false)
{
    var data = new List<CityDataItem>();
    var startDate = new DateTime(2017, 1, 1);
    foreach (string city in cities)
    {
        var dataItem = new CityDataItem() { Name = city };
        for (int i = 0; i < count; i++)
        {
            var temp = new Temperature();
            DateTime date;
            if (monthly)
                date = startDate.AddMonths(i);
            else
                date = startDate.AddDays(i);
            temp.Date = date;
            if (date.Month <= 8)
                temp.HighTemp = rnd.Next(3 * date.Month, 8 * date.Month);
            else
                temp.HighTemp = rnd.Next((13 - date.Month - 2) * date.Month, (13 - date.Month) * date.Month);
            temp.LowTemp = temp.HighTemp - rnd.Next(6, 8);
            temp.Precipitation = (date.Month < 4 || date.Month > 8) ? rnd.Next(100, 150) : rnd.Next(150, 200);
            if (isFahrenheit) temp.HighTemp = temp.HighTemp * 1.8 + 32;
            dataItem.Data.Add(temp);
        }
        data.Add(dataItem);
    }
    return data;
}
''' <summary>
''' StatisticalChartのデータを作成するメソッド
''' </summary>
Private _dataHelper As DataSource = New DataSource().Instance
Private rnd As New Random()
Public Function GetMonthAxisDataSource() As List(Of CategoricalPoint)
    Dim data As New List(Of CategoricalPoint)()
    Dim i As Integer = 0
    For Each month As String In _dataHelper.Months.Take(12)
        data.Add(New CategoricalPoint() With {
             .Name = month,
             .Value = i
        })
        i += 1
    Next
    Return data
End Function
Public Function GetTemperatureData(cities As String(), Optional monthly As Boolean = False, Optional count As Integer = 30, Optional isFahrenheit As Boolean = False) As List(Of CityDataItem)
    Dim data As List(Of CityDataItem) = New List(Of CityDataItem)()
    Dim startDate As DateTime = New DateTime(2017, 1, 1)
    For Each city As String In cities
        Dim dataItem As CityDataItem = New CityDataItem() With {
             .Name = city
        }
        For i As Integer = 0 To count - 1
            Dim temp As Temperature = New Temperature()
            Dim [date] As DateTime
            If monthly Then
                [date] = startDate.AddMonths(i)
            Else
                [date] = startDate.AddDays(i)
            End If
            temp.[Date] = [date]
            If [date].Month <= 8 Then
                temp.HighTemp = rnd.[Next](3 * [date].Month, 8 * [date].Month)
            Else
                temp.HighTemp = rnd.[Next]((13 - [date].Month - 2) * [date].Month, (13 - [date].Month) * [date].Month)
            End If
            temp.LowTemp = temp.HighTemp - rnd.[Next](6, 8)
            temp.Precipitation = If(([date].Month < 4 OrElse [date].Month > 8), rnd.[Next](100, 150), rnd.[Next](150, 200))
            If isFahrenheit Then
                temp.HighTemp = temp.HighTemp * 1.8 + 32
            End If
            dataItem.Data.Add(temp)
        Next
        data.Add(dataItem)
    Next
    Return data
End Function