LoginSignup
5
5

C# Chartで散布図を描く

Posted at

はじめに

C#でグラフを描けるChartコントロールを利用して、散布図を描く方法です。ここでいう散布図は時系列データの折れ線グラフなども含みます。

Chartコントロールについて

  • .NET Frameworkに標準搭載されているため、追加のライブラリを導入せず利用可能。但し.NET系では使えないようです。

  • 使用する場合はSystem.Windows.Forms.DataVisualizationを参照に追加します。[プロジェクト]→[参照の追加]を選択し、アセンブリの中にあるSystem.Windows.Forms.DataVisualizationにチェックを入れて[OK]を押します。

  • Chartコントロールは[ツールボックス]の[データ]の中にあります。
    chart100.png

  • Chartコントロール関連の主要リンク

項目 説明
System.Windows.Forms.DataVisualization.Charting 名前空間 名前空間
Chart クラス グラフ
ChartArea クラス グラフエリア
Legend クラス 凡例
Axis クラス
Series クラス データ系列
DataPoint クラス データ点
AxisScaleView クラス グラフの拡大/縮小されたビュー

グラフを描く

本記事に記載のソースコードは、Form上にChartコントロールを1つ配置している(Name=chart1)前提です。またプロジェクト名(名前空間)はWindowsFormsApp1としています。

とりあえず描いてみる

chart101.png

.NETでは使用できないので、プロジェクトとして「Windows フォーム アプリケーション(.NET Framewrok)」を使用します。System.Windows.Forms.DataVisualizationを参照に追加し、Chartコントロールを1つForm上に配置したら、以下のソースを記述します。

using System.Windows.Forms;

//Chartコントロールを使用するために必要。
//System.Windows.Forms.DataVisualizationを参照に追加必要。
using System.Windows.Forms.DataVisualization.Charting;

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            //ChartコントロールをForm上に配置すると、
            //自動で仮のグラフデータが設定されるのでクリアしておく。
            chart1.ChartAreas.Clear();
            chart1.Series.Clear();
            chart1.Legends.Clear();
            chart1.Dock = DockStyle.Fill;//フォームいっぱいに表示

            //グラフエリアと凡例を作成
            chart1.ChartAreas.Add(new ChartArea());//グラフエリア
            chart1.Legends.Add(new Legend());//凡例

            //データ系列を作成
            Series series = new Series();

            //データ系列のグラフの種類を散布図(点のみ)とする
            series.ChartType = SeriesChartType.Point;

            //データ系列にプロットデータ(y=x^2 x範囲-10~10)を追加
            for (int i = -10; i <= 10; i++)
            {
                series.Points.AddXY(i, i * i);
            }

            //データ系列をChartコントロールに追加
            chart1.Series.Add(series);
        }
    }
}

データ系列を追加する

ChartコントロールのSeriesにデータ系列を追加することで、グラフに表示するデータ系列を追加することができます。
chart102.png

using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;//グラフ用

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            //初期化
            chart1.ChartAreas.Clear();
            chart1.Series.Clear();
            chart1.Legends.Clear();
            chart1.Dock = DockStyle.Fill;

            //グラフエリアと凡例を作成
            chart1.ChartAreas.Add(new ChartArea());//グラフエリア
            chart1.Legends.Add(new Legend());//凡例

            //データ系列を作成
            Series series = new Series();

            //データ系列のグラフの種類を散布図(点のみ)とする
            series.ChartType = SeriesChartType.Point;

            //データ系列にプロットデータ(y=x^2 x範囲-10~10)を追加
            for (int i = -10; i <= 10; i++)
            {
                series.Points.AddXY(i, i * i);
            }

            //データ系列をChartコントロールに追加
            chart1.Series.Add(series);

            //データ系列2個目
            Series series2 = new Series();
            series2.ChartType = SeriesChartType.Point;

            //プロットデータ(y=x x範囲-20~20)を追加
            for (int i = -20; i <= 20; i += 2)
            {
                series2.Points.AddXY(i, i);
            }

            //データ系列をChartコントロールに追加
            chart1.Series.Add(series2);
        }
    }
}

グラフの種類を変更する

設定を変えることでデータ系列のグラフの種類を変更することができます。下記では上から順番に設定を追加していっています。

設定 結果
//グラフの種類を線に変更
series.ChartType = SeriesChartType.Line;
chart103a.png
//線の太さ
series.BorderWidth = 3;
chart103b.png
//線の色
series.Color = Color.Blue;
chart103c.png
//線の種類
series.BorderDashStyle = ChartDashStyle.Dash;
chart103d.png
//マーカー追加
series.MarkerStyle = MarkerStyle.Circle;
series.MarkerSize = 8;//マーカーサイズ
chart103e.png
//マーカーのプロパティ変更
series.MarkerColor = Color.White;//色
series.MarkerBorderColor = Color.Green;//外枠色
series.MarkerBorderWidth = 2;//外枠の太さ
chart103f.png
//凡例文字列の変更
series.LegendText = "y = x^2";
chart103g.png
//グラフ上に値ラベルを表示
series.IsValueShownAsLabel = true;
chart103h.png

以下は設定変更のサンプルです。「凡例の非表示」や「カスタムラベルの表示」なども併せて実施しています。

chart103i.png

using System.Drawing;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;//グラフ用

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            //初期化
            chart1.ChartAreas.Clear();
            chart1.Series.Clear();
            chart1.Legends.Clear();
            chart1.Dock = DockStyle.Fill;

            //グラフエリアと凡例を作成
            chart1.ChartAreas.Add(new ChartArea());//グラフエリア
            chart1.Legends.Add(new Legend());//凡例

            //データ系列を作成
            Series series = new Series();

            //データ系列のグラフの種類を設定
            series.ChartType = SeriesChartType.Line;//線
            series.BorderWidth = 2;//線の太さ
            series.Color = Color.Blue;//線の色
            series.BorderDashStyle = ChartDashStyle.Solid;//線の種類
            series.MarkerStyle = MarkerStyle.Circle;//丸マーカー
            series.MarkerSize = 6;//マーカーサイズ
            series.MarkerColor = Color.White;//マーカーの色
            series.MarkerBorderColor = Color.Blue;//マーカー外枠の色
            series.MarkerBorderWidth = 1;//マーカー外枠の太さ
            series.LegendText = "y = x^2";//凡例文字列の変更

            //データ系列にプロットデータ(y=x^2 x範囲-10~10)を追加
            for (int i = -10; i <= 10; i++)
            {
                series.Points.AddXY(i, i * i);
            }

            //データ系列をChartコントロールに追加
            chart1.Series.Add(series);

            //データ系列2個目
            Series series2 = new Series();

            //データ系列のグラフの種類を設定
            series2.ChartType = SeriesChartType.Line;//線の種類
            series2.BorderWidth = 2;//線の太さ
            series2.Color = Color.Red;//線の色
            series2.MarkerStyle = MarkerStyle.Triangle;//マーカー種類
            series2.MarkerSize = 8;//マーカーサイズ
            series2.IsVisibleInLegend = false;//凡例を非表示

            //プロットデータ(y=x*2 x範囲-20~20)を追加
            for (int i = -20; i <= 20; i += 5)
            {
                //プロットデータの値を設定
                DataPoint dataPoint = new DataPoint(i, i * 2);

                //プロットデータのラベルを設定
                dataPoint.Label = "(" + i.ToString() + "," + (i * 2).ToString() + ")";

                //系列にプロットデータを追加
                series2.Points.Add(dataPoint);
            }

            //データ系列をChartコントロールに追加
            chart1.Series.Add(series2);
        }
    }
}

第2軸を使用する

SeriesXAxisType YAxisTypeを変更することで、データ系列ごとに主軸を使用するか、第2軸を使用するかを設定できます。以下の例では2個目のデータ系列をX,Y軸とも第2軸に設定しています。
chart104.png

using System.Drawing;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;//グラフ用

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            //初期化
            chart1.ChartAreas.Clear();
            chart1.Series.Clear();
            chart1.Legends.Clear();
            chart1.Dock = DockStyle.Fill;

            //グラフエリアと凡例を作成
            chart1.ChartAreas.Add(new ChartArea());//グラフエリア
            chart1.Legends.Add(new Legend());//凡例

            //データ系列を作成
            Series series1 = new Series { ChartType = SeriesChartType.Line, Color = Color.Blue };
            Series series2 = new Series { ChartType = SeriesChartType.Line, Color = Color.Red };

            //データ系列にプロットデータを追加
            for (int i = -10; i <= 10; i++)
            {
                series1.Points.AddXY(i, i * i);//y=x^2 x範囲-10~10
                series2.Points.AddXY(i * 2, i * 2);//y=x x範囲-20~20
            }

            //データ系列をChartコントロールに追加
            chart1.Series.Add(series1);
            chart1.Series.Add(series2);

            //データ系列series2の軸を第2軸に設定
            series2.XAxisType = AxisType.Secondary;//X軸として第2軸を使用
            series2.YAxisType = AxisType.Secondary;//Y軸として第2軸を使用
        }
    }
}

軸の目盛や範囲などを変更する

X軸であるAxisXを対象として説明をしていますが、他の軸も同様です。
Y軸の場合はAxisY、第2軸の場合はAxisX2 AxisY2となります。

Minimum、Maximum、Interval、IntervalOffset、MinorGrid

例えば以下のコードを実行すると、目盛が中途半端な値となります。

chart105.png

using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;//グラフ用

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            //初期化
            chart1.ChartAreas.Clear();
            chart1.Series.Clear();
            chart1.Legends.Clear();
            chart1.Dock = DockStyle.Fill;

            //グラフエリアを作成
            chart1.ChartAreas.Add(new ChartArea());//グラフエリア

            //データ系列を作成
            Series series = new Series { ChartType = SeriesChartType.Line, BorderWidth = 2 };

            //データ系列にプロットデータを追加
            for (double i = -13.15; i <= 20; i++)
            {
                series.Points.AddXY(i, i * i);
            }

            //データ系列をChartコントロールに追加
            chart1.Series.Add(series);
        }
    }
}

軸設定を変えることで、グラフの見た目を変更してみます。

設定 結果
//最小値、最大値を変更
chart1.ChartAreas[0].AxisX.Minimum = -15.0;
chart1.ChartAreas[0].AxisX.Maximum = 20.0;
chart105a.png
//目盛間隔を10に設定
chart1.ChartAreas[0].AxisX.Interval = 10;
chart105b.png
//目盛のオフセットを設定。-15に対して5を足して-10から目盛を表示
chart1.ChartAreas[0].AxisX.IntervalOffset = 5;
chart105c.png
//補助目盛を追加
chart1.ChartAreas[0].AxisX.MinorGrid.Enabled = true;
chart1.ChartAreas[0].AxisX.MinorGrid.Interval = 2;
chart1.ChartAreas[0].AxisX.MinorGrid.IntervalOffset = 1;
chart105d.png
//X軸の値0の点でY軸と交差する
chart1.ChartAreas[0].AxisX.Crossing = 0;
chart105e.png

以下は設定変更のサンプルです。上記以外の設定も変更しています。

chart106.png

using System.Drawing;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;//グラフ用

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            //初期化
            chart1.ChartAreas.Clear();
            chart1.Series.Clear();
            chart1.Legends.Clear();
            chart1.Dock = DockStyle.Fill;

            //グラフエリアを作成
            chart1.ChartAreas.Add(new ChartArea());//グラフエリア

            //データ系列を作成
            Series series = new Series { ChartType = SeriesChartType.Line, BorderWidth = 2 };

            //データ系列にプロットデータを追加
            for (double i = -13.15; i <= 20; i++)
            {
                series.Points.AddXY(i, i * i);
            }

            //データ系列をChartコントロールに追加
            chart1.Series.Add(series);

            //コードが長くなるので軸を変数に代入
            Axis AxisX = chart1.ChartAreas[0].AxisX;
            Axis AxisY = chart1.ChartAreas[0].AxisY;

            //X軸の設定を変更
            AxisX.Minimum = -15.0;//最小値
            AxisX.Maximum = 20.0;//最大値
            AxisX.Interval = 10;//間隔
            AxisX.IntervalOffset = 5;//間隔のオフセット
            AxisX.LineWidth = 2;//軸の太さ

            //X軸の補助目盛を設定
            AxisX.MinorGrid.Enabled = true;//補助目盛を使用
            AxisX.MinorGrid.Interval = 2;//間隔
            AxisX.MinorGrid.IntervalOffset = 1;//間隔のオフセット
            AxisX.MinorGrid.LineColor = Color.FromArgb(200, 200, 200);//色
            AxisX.MinorGrid.LineDashStyle = ChartDashStyle.Dash;//線の種類

            //X軸のTickMarkを設定
            AxisX.MinorTickMark.Enabled = true;
            AxisX.MinorTickMark.TickMarkStyle = TickMarkStyle.InsideArea;
            AxisX.MinorTickMark.LineWidth = 1;
            AxisX.MinorTickMark.Size = 3;
            AxisX.MinorTickMark.Interval = AxisX.MinorGrid.Interval;
            AxisX.MinorTickMark.IntervalOffset = AxisX.MinorGrid.IntervalOffset;

            //目盛の書式設定
            AxisX.LabelStyle.Format = "0.0";

            //Y軸との交差位置を変更
            AxisX.Crossing = 0;

            //軸のタイトルを設定
            AxisX.Title = "X軸タイトル";
            AxisY.Title = "Y軸タイトル";
        }
    }
}

IsMarginVisible

IsMarginVisibleにより軸の目盛範囲にマージン(余白)を持たせるかどうかを設定できます。

  • true(既定値)
    データ範囲-5~5に対し、左端、右端にマージンが追加され表示範囲が-6~6となっています。
    chart107a.png
  • false
    データ範囲がそのまま表示範囲となっています。
    chart107b.png

以下はfalseの場合のソースコードです。

using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;//グラフ用

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            //初期化
            chart1.ChartAreas.Clear();
            chart1.Series.Clear();
            chart1.Legends.Clear();
            chart1.Dock = DockStyle.Fill;

            //グラフエリアを作成
            chart1.ChartAreas.Add(new ChartArea());//グラフエリア

            //データ系列を作成
            Series series = new Series { ChartType = SeriesChartType.Line, BorderWidth = 2 };

            //データ系列にプロットデータを追加
            for (int i = -5; i <= 5; i++)
            {
                series.Points.AddXY(i, i * i);
            }

            //データ系列をChartコントロールに追加
            chart1.Series.Add(series);

            //軸のマージンを設定
            chart1.ChartAreas[0].AxisX.IsMarginVisible = false;//マージンなしで設定

            //グラフタイトル
            chart1.Titles.Add("IsMarginVisible=" + chart1.ChartAreas[0].AxisX.IsMarginVisible.ToString());
        }
    }
}

IntervalAutoMode

IntervalAutoModeにより軸の目盛間隔を固定とするか、軸の長さに応じて可変とするかを設定します。

  • FixedCount(既定値)
    サイズを大きくしても目盛間隔は変わりません。
    chart108a.png
  • VariableCount
    サイズの大小に応じて目盛間隔が変わります。
    chart108b.png

以下はVariableCountの場合のソースコードです。

using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;//グラフ用

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            //初期化
            chart1.ChartAreas.Clear();
            chart1.Series.Clear();
            chart1.Legends.Clear();
            chart1.Dock = DockStyle.Fill;

            //グラフエリアを作成
            chart1.ChartAreas.Add(new ChartArea());//グラフエリア

            //データ系列を作成
            Series series = new Series { ChartType = SeriesChartType.Line, BorderWidth = 2 };

            //データ系列にプロットデータを追加
            for (int i = -100; i <= 100; i += 10)
            {
                series.Points.AddXY(i, i * i);
            }

            //データ系列をChartコントロールに追加
            chart1.Series.Add(series);

            //軸のマージンをなしに設定
            chart1.ChartAreas[0].AxisX.IsMarginVisible = false;

            //目盛の数を固定にするか可変にするか
            chart1.ChartAreas[0].AxisX.IntervalAutoMode = IntervalAutoMode.VariableCount;//可変

            //グラフタイトル
            chart1.Titles.Add("IntervalAutoMode=" + chart1.ChartAreas[0].AxisX.IntervalAutoMode.ToString());
        }
    }
}

ScaleView

グラフの一部を拡大して見たい場合、軸の最大最小値を変更する方法もありますが、表示範囲外を見ることができないため不便です。そのようなときはScaleViewを使います。下記はデータの範囲が-100~100に対して、-50~50の部分を拡大して表示しています。またスクロールバーにより表示範囲を変更できます。

chart109.png

using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;//グラフ用

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            //初期化
            chart1.ChartAreas.Clear();
            chart1.Series.Clear();
            chart1.Legends.Clear();
            chart1.Dock = DockStyle.Fill;

            //グラフエリアを作成
            chart1.ChartAreas.Add(new ChartArea());//グラフエリア

            //データ系列を作成
            Series series = new Series { ChartType = SeriesChartType.Line, BorderWidth = 2 };

            //データ系列にプロットデータを追加
            for (int i = -100; i <= 100; i += 1)
            {
                series.Points.AddXY(i, i * i);
            }

            //データ系列をChartコントロールに追加
            chart1.Series.Add(series);

            //Zoomしたとき引数の値をそのまま表示範囲にしたいのでマージンをなしにする。
            //マージンありで、Zoom(-50.0, 50.0)とした場合-51~51のように左右にマージンが作られてしまう。
            chart1.ChartAreas[0].AxisX.IsMarginVisible = false;

            //ScaleViewでグラフを拡大
            chart1.ChartAreas[0].AxisX.ScaleView.Zoom(-50.0, 50.0);
        }
    }
}

時系列(日時)データを表示する

X軸データを日時にする

Series.XValueType = ChartValueType.DateTimeとすると、データ系列のX軸データが日時データとして扱われます。また軸目盛の書式をyyyy/MM/ddHH:mm:ssのようなカスタム日時形式文字列で指定することで目盛表記を変更できます。

chart110.png

using System;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;//グラフ用

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            //初期化
            chart1.ChartAreas.Clear();
            chart1.Series.Clear();
            chart1.Legends.Clear();
            chart1.Dock = DockStyle.Fill;

            //グラフエリアを作成
            chart1.ChartAreas.Add(new ChartArea());//グラフエリア

            //データ系列を作成
            Series series = new Series { ChartType = SeriesChartType.Line, BorderWidth = 2 };

            //データ系列のX軸データを日時データとする
            series.XValueType = ChartValueType.DateTime;

            //X軸の目盛の書式設定
            chart1.ChartAreas[0].AxisX.LabelStyle.Format = "yyyy/M/d";

            //データ系列にプロットデータを追加
            for (int i = 1; i <= 180; i++)
            {
                series.Points.AddXY(new DateTime(2015, 5, 1).AddHours(i), Math.Sin((double)(i * 5) / 360 * 2 * Math.PI));
            }

            //データ系列をChartコントロールに追加
            chart1.Series.Add(series);
        }
    }
}

日時をシリアル値に変換する

AddXYにはAddXY(Double, Double)だけでなくAddXY(Object, Object[])といったオーバーロードが存在するためX軸データとしてDateTimeをそのまま指定できます。但し軸の最小値Axis.Minimumや最大値Axis.MaximumはDouble型のため、例えば最小値を2051/5/1のように日時で指定したい場合は、DateTime.ToOADateメソッドを使って日時をDouble型(Excelでいうシリアル値)に変換する必要があります。

chart111.png

using System;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;//グラフ用

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            //初期化
            chart1.ChartAreas.Clear();
            chart1.Series.Clear();
            chart1.Legends.Clear();
            chart1.Dock = DockStyle.Fill;

            //グラフエリアを作成
            chart1.ChartAreas.Add(new ChartArea());//グラフエリア

            //データ系列を作成
            Series series = new Series { ChartType = SeriesChartType.Line, BorderWidth = 2 };

            //データ系列のX軸データを日時データとする
            series.XValueType = ChartValueType.DateTime;

            //X軸の目盛の書式設定
            chart1.ChartAreas[0].AxisX.LabelStyle.Format = "M/d HH:mm";

            //データ系列にプロットデータを追加
            for (int i = 1; i <= 180; i++)
            {
                series.Points.AddXY(new DateTime(2015, 5, 1).AddHours(i), Math.Sin((double)(i * 5) / 360 * 2 * Math.PI));
            }

            //データ系列をChartコントロールに追加
            chart1.Series.Add(series);

            //X軸の最小最大値を指定
            chart1.ChartAreas[0].AxisX.Minimum = new DateTime(2015, 5, 2, 0, 0, 0).ToOADate();
            chart1.ChartAreas[0].AxisX.Maximum = new DateTime(2015, 5, 2, 20, 0, 0).ToOADate();
        }
    }
}

日時文字列をDateTimeに変換する

データ系列のX軸データが日時文字列の場合は、DateTime.ParseによってDateTimeに変換してから使用します。ここでは省略していますが通常は例外処理が必要です。

chart112.png

using System;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;//グラフ用

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            //初期化
            chart1.ChartAreas.Clear();
            chart1.Series.Clear();
            chart1.Legends.Clear();
            chart1.Dock = DockStyle.Fill;

            //グラフエリアを作成
            chart1.ChartAreas.Add(new ChartArea());//グラフエリア

            //データ系列を作成
            Series series = new Series
            {
                ChartType = SeriesChartType.Line,
                BorderWidth = 2,
                MarkerStyle = MarkerStyle.Circle,
                MarkerSize = 8
            };

            //データ系列のX軸データを日時データとする
            series.XValueType = ChartValueType.DateTime;

            //X軸の目盛の書式設定
            chart1.ChartAreas[0].AxisX.LabelStyle.Format = "M/d";

            //データ系列のX軸データ(日時文字列)
            string[] dates = {
                "2015/5/1 10:00:00",
                "2015/5/3 14:00:00",
                "2015/5/3 16:00:00",
                "2015/5/4  9:00:00",
                "2015/5/6 10:00:00",
            };

            int i = 0;
            foreach (string date in dates)
            {
                i++;
                series.Points.AddXY(DateTime.Parse(date), i);
            }

            //データ系列をChartコントロールに追加
            chart1.Series.Add(series);
        }
    }
}

ミリ秒データを表示する

ミリ秒データの場合、目盛が表示されない場合があります。その場合は目盛間隔を明示的に設定するかIntervalAutoModeVariableCountにします。
chart113.png

using System;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;//グラフ用

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            //初期化
            chart1.ChartAreas.Clear();
            chart1.Series.Clear();
            chart1.Legends.Clear();
            chart1.Dock = DockStyle.Fill;

            //グラフエリアを作成
            chart1.ChartAreas.Add(new ChartArea());//グラフエリア

            //データ系列を作成
            Series series = new Series
            {
                ChartType = SeriesChartType.Line,
                BorderWidth = 2,
                MarkerStyle = MarkerStyle.Circle,
                MarkerSize = 8
            };

            //データ系列のX軸データを日時データとする
            series.XValueType = ChartValueType.DateTime;

            //X軸の目盛の書式設定
            chart1.ChartAreas[0].AxisX.LabelStyle.Format = "mm:ss.fff";
            chart1.ChartAreas[0].AxisX.LabelStyle.Angle = -90;//目盛の表示角度

            //どちらかを設定しないと目盛が表示されない
            chart1.ChartAreas[0].AxisX.IntervalAutoMode = IntervalAutoMode.VariableCount;
            //chart1.ChartAreas[0].AxisX.Interval = (1.0 / 24.0 / 60.0 / 60.0 / 1000.0) * 100.0;//100msec間隔

            //データ系列のX軸データ(日時文字列)
            string[] dates = {
                "2015/5/1 0:00:00.110",
                "2015/5/1 0:00:00.204",
                "2015/5/1 0:00:00.334",
                "2015/5/1 0:00:00.412",
                "2015/5/1 0:00:00.501",
                "2015/5/1 0:00:00.640",
                "2015/5/1 0:00:00.767",
                "2015/5/1 0:00:00.878"
            };

            int i = 0;
            foreach (string date in dates)
            {
                i++;
                series.Points.AddXY(DateTime.Parse(date), i);
            }

            //データ系列をChartコントロールに追加
            chart1.Series.Add(series);
        }
    }
}

CSVファイルのデータを表示する

CSVファイルの内容を読み込むにあたってTextFieldParserを使用しています。TextFieldParserを使用するとa,"b,b",ca,"b\n(改行)b",cなどようなデータも問題なくパースできます。使用するためにはMicrosoft.VisualBasicを参照に追加する必要があります。

chart114.png

CSVファイル

C:\work\sample.csv
日時,データ1,データ2
2015/5/1 0:00,1,1
2015/5/1 12:00,5,2
2015/5/2 0:00,4,3
2015/5/2 12:00,3,4
2015/5/3 0:00,7,
2015/5/3 12:00,6,6
2015/5/4 0:00,2,7
2015/5/4 12:00,4,8

ソースコード

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;//グラフ用
using Microsoft.VisualBasic.FileIO;//TextFieldParserを使用するために必要。Microsoft.VisualBasicを参照に追加必要

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            //初期化
            chart1.ChartAreas.Clear();
            chart1.Series.Clear();
            chart1.Legends.Clear();
            chart1.Dock = DockStyle.Fill;

            //グラフエリアと凡例を作成
            chart1.ChartAreas.Add(new ChartArea());//グラフエリア
            chart1.Legends.Add(new Legend());//凡例

            //X軸の目盛の書式設定
            chart1.ChartAreas[0].AxisX.LabelStyle.Format = "M/d H:mm";

            //読み込むファイル
            string filepath = @"C:\work\sample.csv";

            //ファイルの全データ
            List<List<string>> allDatas = new List<List<string>>();

            //ファイルの内容を読み込んで配列に格納
            using (TextFieldParser textFieldParser = new TextFieldParser(filepath, Encoding.GetEncoding(932)))
            {
                //区切り文字としてカンマを設定
                textFieldParser.TextFieldType = FieldType.Delimited;
                textFieldParser.SetDelimiters(",");

                while (!textFieldParser.EndOfData)
                {
                    try
                    {
                        string[] cells = textFieldParser.ReadFields();
                        allDatas.Add(new List<string>(cells));
                    }
                    catch (Exception)
                    {
                        ;
                    }
                }
            }

            //データ系列の作成
            List<Series> series = new List<Series>();

            bool firstline = true;//1行目かどうか
            foreach (var cells in allDatas)
            {
                if (firstline)//1行目はデータ系列の項目名とする
                {
                    firstline = false;

                    //データ系列の作成
                    for (int i = 1; i < cells.Count; i++)
                    {
                        //X軸データを日時データとして、データ系列を作成
                        Series s = new Series
                        {
                            ChartType = SeriesChartType.Line,
                            BorderWidth = 2,
                            XValueType = ChartValueType.DateTime
                        };

                        //項目名を凡例とする
                        s.LegendText = cells[i];

                        //配列に追加
                        series.Add(s);
                    }
                }
                else//2行目以降はデータ系列のデータ値とする
                {
                    if (series.Count + 1 == cells.Count)//データはX軸データも含むので系列の数+1
                    {
                        DateTime dt;
                        if (DateTime.TryParse(cells[0], out dt))//1列目が日時変換できる場合
                        {
                            for (int i = 0; i < series.Count; i++)
                            {
                                //プロットデータ
                                DataPoint dataPoint = new DataPoint();

                                //プロットデータに値を設定。数値変換できない場合は空データとする
                                double value;
                                dataPoint.IsEmpty = !double.TryParse(cells[i + 1], out value);
                                dataPoint.SetValueXY(dt, value);

                                //データ系列に追加
                                series[i].Points.Add(dataPoint);
                            }
                        }
                    }
                }
            }

            //データ系列をChartコントロールに追加
            foreach (Series s in series)
            {
                chart1.Series.Add(s);
            }
        }
    }
}

参考URL

5
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5