ハードエンジニアの方向けです。
評価で取ったcsvデータをグラフ表示したいことありますよね。
C#で、csvデータをグラフにしてGUI上にchart表示させてみたいと思います。
やること
・csvデータを読み込む
・グラフ用のデータにする(series)
・chartに表示する
・表示範囲を工夫する
・(おまけ)グラフを画像出力する
それでは順番に見ていきましょう!
目次
順番に見ていく
csvデータを読み込む
実行ファイルと同じ階層にある「sample.csv」を読んで、Listの入れ子に取り込みます。
csvファイルはカンマ区切りを想定しています。
チャート表示用に数値を扱いたいのですが、テキストリード使っているのでいったん文字列として認識されてしまいます。
数値に型変換してリストに取り込みます。
string filename = "sample.csv";
List<List<double>> datas = new List<List<double>>();
System.Text.Encoding enc = System.Text.Encoding.GetEncoding("shift_jis");
string[] lines = System.IO.File.ReadAllLines(filename, enc);
foreach (string s in lines)
{
List<double> tmp_d = new List<double>();
List<string> tmp_str = s.Split(',').ToList();
foreach (string ss in tmp_str)
{
if (ss != "")//例外処理, 空白データは無視
{
tmp_d.Add(Convert.ToDouble(ss));
}
}
datas.Add(tmp_d);
}
グラフ用のデータにする(series)
取り込んだリストを、グラフ用のデータにします。
Series series = new Series();
series.ChartType = SeriesChartType.Line;
series.LegendText = "データ";
int cnt = 0;
foreach (List<double> list_d in datas)
{
foreach (double d in list_d)
{
series.Points.AddXY(cnt, d);
cnt += 1;
}
}
グラフに表示する
シンプルですね。扱いやすくするため、Chartオブジェクトを設定しています。
再表示したときにグラフが重なっていかないようにクリアしています。
Chart chr = chart1;
chr.ChartAreas.Clear();
chr.Series.Clear();
ChartArea chartAria1 = new ChartArea("chartArea1");
chr.ChartAreas.Add(chartAria1);
chr.Series.Add(series);
表示範囲を工夫する
ちょっと応用編です。
そのまま出力すると、何が何だか分からないグラフになることがあります。
一工夫して、データのmax値の1.2倍をグラフ表示のmaxにして、8分割して線を引いてみます。
また、Y軸にタイトルをつけます。
double max = 0;
double min = 65535;
foreach (List<double> list_d in datas)
{
foreach (double d in list_d)
{
if(d > max)
{
max = d;
}
if (d < min)
{
min = d;
}
}
}
//表示範囲をmax*1.2にします
double msb = max * 1.2;
chartAria1.AxisX.Minimum = 0;
chartAria1.AxisY.Maximum = msb;
chartAria1.AxisY.Interval = (msb - 0) / 8;
chartAria1.AxisY.Minimum = 0;
chartAria1.AxisY.Title = "データ";
(おまけ)グラフを画像出力する
おまけです。グラフを画像出力します。
string pic_chart = $"chart.png";
chr.SaveImage(pic_chart, ChartImageFormat.Png);
サンプルコード
//csvデータをリストに取り込む
string filename = "sample.csv";
List<List<double>> datas = new List<List<double>>();
System.Text.Encoding enc = System.Text.Encoding.GetEncoding("shift_jis");
string[] lines = System.IO.File.ReadAllLines(filename, enc);
foreach (string s in lines)
{
List<double> tmp_d = new List<double>();
List<string> tmp_str = s.Split(',').ToList();
foreach (string ss in tmp_str)
{
if (ss != "")//例外処理, 空白データは無視
{
tmp_d.Add(Convert.ToDouble(ss));
}
}
datas.Add(tmp_d);
}
//chart描画
//max
double max = 0;
double min = 65535;
foreach (List<double> list_d in datas)
{
foreach (double d in list_d)
{
if(d > max)
{
max = d;
}
if (d < min)
{
min = d;
}
}
}
//表示範囲をmax*1.2にします
double msb = max * 1.2;
Chart chr = chart1;
chr.ChartAreas.Clear();
chr.Series.Clear();
ChartArea chartAria1 = new ChartArea("chartArea1");
chr.ChartAreas.Add(chartAria1);
chartAria1.AxisX.Minimum = 0;
chartAria1.AxisY.Maximum = msb;
chartAria1.AxisY.Interval = (msb - 0) / 8;
chartAria1.AxisY.Minimum = 0;
chartAria1.AxisY.Title = "データ";
Series series = new Series();
series.ChartType = SeriesChartType.Line;
series.LegendText = "データ";
int cnt = 0;
foreach (List<double> list_d in datas)
{
foreach (double d in list_d)
{
series.Points.AddXY(cnt, d);
cnt += 1;
}
}
chr.Series.Add(series);
//グラフを画像出力
string pic_chart = $"chart.png";
chr.SaveImage(pic_chart, ChartImageFormat.Png);
以上です。
誰かの助けになることができたら幸いです。