#はじめに
ヒストグラムを作る方法を記載します。
Math.Netを使ってデータからヒストグラムを作成し、
Chartコントロールで棒グラフ表示します。
#Math.Net
Math.Netは.NET開発者向け数学ライブラリです。
VisualStudioの参照設定で”Math.Net Numerics”を追加してください。
##ヒストグラムの作り方
MathNet.Numerics.Statistics.Histogramクラスを使います。
コンストラクタにデータ、Bucket数、上限値、下限値を指定します。
Bucketとはヒストグラムを棒グラフにしたときの1つの棒に対応するものです。
int nBuckets = 10;
Histogram hist = new Histogram(data, nBuckets, -50 /* lower */, 50 /* upper */);
Bucket数、上限値、下限値からヒストグラムの度数をカウントする区間が決まります。
区間幅は (upper - lower) / Bucket数 となります。
例えば、upper = 50, lower = -50, Bucket数 = 10とすると、 区間幅は (50 - (-50) / 10) = 10となります。
各Bucketは (-50,-40], (-40,-30], .... , (40, 50]となります。
なお、"("は端を含まない区間記号、"]"は端を含む区間記号です。
各Bucketはindexで参照できます。indexの範囲は0~Bucket数-1です。
for (int i = 0; i < nBuckets; i++)
{
double mid = Math.Round((hist[i].UpperBound+hist[i].LowerBound)/2, 1);
seriesColumn.Points.Add(new DataPoint(mid, hist[i].Count));
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;
using MathNet.Numerics.Statistics;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
private Random mRand;
public Form1()
{
InitializeComponent();
// clear
chart1.Series.Clear();
chart1.ChartAreas.Clear();
chart1.Titles.Clear();
Title title1 = new Title("Histgram");
// series
Series seriesColumn = new Series();
seriesColumn.LegendText = "Histgram";
seriesColumn.ChartType = SeriesChartType.Column;
// 正規乱数を作る
mRand = new Random(DateTime.Now.Millisecond);
int nData = 10000;
double[] data = new double[nData];
for (int i = 0; i < nData; i++)
{
// Box-Muller法で一様乱数から正規乱数を作る
data[i] = boxmuller(mRand, 0 /* average */ , 10 /* sigma */);
}
// ヒストグラムを作る
int nBuckets = 10;
Histogram hist = new Histogram(data, nBuckets, -50 /* lower */, 50 /* upper */);
for (int i = 0; i < nBuckets; i++)
{
double mid = Math.Round((hist[i].UpperBound+hist[i].LowerBound)/2, 1);
seriesColumn.Points.Add(new DataPoint(mid, hist[i].Count));
}
// chartarea
ChartArea area1 = new ChartArea();
area1.AxisX.Title = "Value";
area1.AxisY.Title = "Frequency";
chart1.Titles.Add(title1);
chart1.ChartAreas.Add(area1);
chart1.Series.Add(seriesColumn);
}
private double boxmuller(Random rdm, double ave, double sigma)
{
double r1 = rdm.NextDouble();
double r2 = rdm.NextDouble();
double std = Math.Sqrt(-2.0 * Math.Log(r1)) * Math.Sin(2.0 * Math.PI * r2);
return ave + std * sigma;
}
}
}