C#でグラフ表示する方法|Chartコントロールの使い方とサンプルコードを初心者向けに解説
はじめに
C#でデータの推移や比較結果を分かりやすく伝えたい場合は、数値を表に並べるだけでなく、グラフとして表示する方法が効果的です。特にWindowsフォームアプリでは、Chartコントロールを利用すると、折れ線グラフや棒グラフ、円グラフなどを比較的少ないコードで作成できます。
この記事では、C#でグラフ表示を行う初心者に向けて、Chartコントロールの準備方法から基本的な使い方、見た目のカスタマイズ、CSVデータの読み込み、リアルタイム更新まで順番に解説します。
なお、この記事のサンプルコードは、主に「Windows Forms App(.NET Framework)」を対象としています。Chartコントロールは.NET Framework 4.8.1向けのWindows Formsコントロールとして公式APIが提供されており、表示データを管理するSeriesと、描画領域を管理するChartAreasが中心的な要素です。Microsoft Learn+1
1. C#でグラフ表示する方法の全体像
1-1. 「c# グラフ表示」で検索する人が知りたいこと
「c# グラフ表示」と検索する人の多くは、次のような疑問を持っています。
C#で折れ線グラフや棒グラフを作るには何を使えばよいか
Visual Studioの画面上にグラフを配置する方法
配列やCSVの数値をグラフ化する方法
グラフの色、軸、タイトル、凡例を変更する方法
一定間隔でデータを追加するリアルタイムグラフの作り方
WPFや新しい.NETでも利用できるグラフライブラリ
単にグラフを表示するだけでなく、業務アプリや計測ツールで実際に利用できる形まで作りたいというケースも多いでしょう。
1-2. C#でグラフを表示する主な方法
C#でグラフを表示する方法は、大きく分けて次の3つです。
1つ目は、WindowsフォームのChartコントロールを使用する方法です。.NET FrameworkのWindowsフォームアプリで利用しやすく、Visual Studioのデザイナーから配置できます。
2つ目は、OxyPlot、LiveCharts、ScottPlotなどの外部ライブラリを使用する方法です。WPFや新しい.NETを使用する場合、外部ライブラリのほうが導入しやすいことがあります。
3つ目は、Graphicsクラスなどを使ってグラフを自作する方法です。自由度は高いものの、軸、目盛り、凡例、拡大縮小などをすべて自分で実装する必要があるため、初心者にはおすすめできません。
1-3. 初心者にはChartコントロールがおすすめな理由
Chartコントロールには、グラフ表示に必要な機能が最初から用意されています。
折れ線、棒、円、散布図などを表示できる
デザイナー上でサイズや位置を調整できる
タイトル、軸、凡例を設定できる
データを1件ずつ追加できる
複数の系列を同時に表示できる
PNGやJPEGなどの画像として保存できる
基本的には、描画領域となるChartAreaを作成し、データ系列となるSeriesを追加して、そのSeriesにデータを登録します。
1-4. この記事で作成するグラフの完成イメージ
この記事では、月別売上を表す次のような折れ線グラフを作成します。
X軸:1月から6月
Y軸:売上金額
グラフタイトル:月別売上
系列名:売上
各データ位置に丸いマーカーを表示
X軸とY軸にタイトルを表示
最終的には、配列やCSVファイルから読み込んだデータも、同じ考え方でグラフ表示できるようになります。
2. Chartコントロールとは
2-1. Chartコントロールの特徴
Chartコントロールは、Windowsフォーム上にグラフを表示するためのコントロールです。
主に次のオブジェクトを組み合わせて使用します。
| オブジェクト | 役割 |
|---|---|
Chart | グラフ全体を管理する |
ChartArea | 軸や目盛りを含む描画領域を管理する |
Series | 1つのデータ系列を管理する |
DataPoint | 個々のデータを管理する |
Legend | 凡例を管理する |
Title | グラフタイトルを管理する |
Seriesには表示するデータと表示属性が保存され、ChartAreaには軸、目盛り、ラベルを含む描画領域が保存されます。Microsoft Learn+2
Microsoft Learn+2
2-2. 表示できるグラフの種類
Chartコントロールでは、さまざまな形式のグラフを表示できます。
代表的な種類は次のとおりです。
折れ線グラフ
曲線グラフ
棒グラフ
横棒グラフ
積み上げ棒グラフ
円グラフ
ドーナツグラフ
散布図
面グラフ
バブルチャート
レーダーチャート
ローソク足チャート
グラフの種類は、Series.ChartTypeプロパティで指定します。
C#series.ChartType = SeriesChartType.Line;
LineをColumnやPieに変更するだけでも、基本的なグラフ形式を切り替えられます。
2-3. Windowsフォームアプリで使える場面
Chartコントロールは、次のようなアプリケーションで利用できます。
売上管理システム
在庫管理システム
アンケート集計ツール
温度や湿度の監視ツール
製造設備の稼働状況表示
ログ解析ツール
株価や為替データの確認ツール
学習用の統計アプリ
特に、社内向けのWindowsデスクトップアプリで数値を可視化したい場合に適しています。
2-4. Chartコントロールを使う際の注意点
最も注意したいのは、作成するプロジェクトの種類です。
Visual Studioには、名前が似ている次のプロジェクトテンプレートがあります。
Windows Forms App
Windows Forms App(.NET Framework)
標準のChartコントロールを簡単に使用したい場合は、「Windows Forms App(.NET Framework)」を選択するのが確実です。
新しい.NETを対象としたWindows Forms Appでは、Chartコントロールがツールボックスに表示されない場合があります。Microsoftの案内でも、.NETベースのプロジェクトでは標準Chartが利用できず、.NET Frameworkプロジェクトまたは互換パッケージを検討する方法が示されています。Microsoft Learn+1
3. C#でグラフ表示するための準備
3-1. Visual StudioでWindowsフォームアプリを作成する
Visual Studioで次の手順を実行します。
Visual Studioを起動する
「新しいプロジェクトの作成」を選択する
言語に「C#」を指定する
「Windows Forms App(.NET Framework)」を選択する
プロジェクト名を入力する
.NET Framework 4.8または4.8.1を選択する
「作成」をクリックする
「Windows Forms App」と「Windows Forms App(.NET Framework)」を間違えないようにしてください。
3-2. Chartコントロールをフォームに配置する
プロジェクトを作成したら、Visual Studioのツールボックスを開きます。
「データ」カテゴリーにある「Chart」を、Form1へドラッグ&ドロップしてください。
配置後は、プロパティウィンドウで次の設定を行います。
(Name) = chart1
Dock = Fill
DockをFillにすると、フォームの大きさに合わせてChartコントロールが拡大・縮小されます。
ボタンを使用するサンプルも試す場合は、Buttonコントロールを配置し、名前をbutton1、表示文字を「グラフ表示」にします。
3-3. 必要な名前空間を追加する
コードの先頭に、次の名前空間を追加します。
C#using System;
using System.Drawing;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;
CSVファイルや配列を扱うサンプルでは、必要に応じて次の名前空間も追加します。
C#using System.Globalization;
using System.IO;
using System.Linq;
3-4. Chartコントロールが表示されない場合の確認ポイント
ツールボックスにChartが表示されない場合は、次の点を確認します。
まず、プロジェクトが「Windows Forms App(.NET Framework)」として作成されているか確認してください。
次に、ツールボックス内を右クリックし、「アイテムの選択」を開きます。「.NET Framework コンポーネント」からChartを探してチェックします。
参照設定にSystem.Windows.Forms.DataVisualizationがない場合は、次の手順で追加します。
ソリューションエクスプローラーの「参照」を右クリックする
「参照の追加」を選択する
「アセンブリ」の「フレームワーク」を開く
System.Windows.Forms.DataVisualizationにチェックを入れる
それでも表示されない場合は、Visual Studioを再起動し、プロジェクトをリビルドしてください。
4. Chartコントロールで折れ線グラフを表示する基本手順
4-1. ChartAreaを設定する
ChartAreaは、グラフの軸や目盛りを含む描画領域です。
C#chart1.ChartAreas.Clear();
ChartArea chartArea = new ChartArea("MainArea");
chart1.ChartAreas.Add(chartArea);
Clearを実行しているのは、デザイナーが自動作成したChartAreaとの重複を防ぐためです。
4-2. Seriesを追加する
Seriesは、グラフに表示する1つのデータ系列です。
C#chart1.Series.Clear();
Series series = new Series("売上");
series.ChartArea = "MainArea";
chart1.Series.Add(series);
たとえば「売上」と「利益」を同時に表示する場合は、Seriesを2つ作成します。
4-3. グラフにデータを追加する
データはPoints.AddXYメソッドで追加できます。
C#series.Points.AddXY("1月", 120);
series.Points.AddXY("2月", 150);
series.Points.AddXY("3月", 135);
series.Points.AddXY("4月", 180);
series.Points.AddXY("5月", 210);
series.Points.AddXY("6月", 195);
第1引数がX軸の値、第2引数がY軸の値です。
4-4. ChartTypeで折れ線グラフを指定する
折れ線グラフを表示する場合は、ChartTypeにLineを指定します。
C#series.ChartType = SeriesChartType.Line;
線を滑らかな曲線にしたい場合は、Splineを指定します。
C#series.ChartType = SeriesChartType.Spline;
4-5. 実行してグラフ表示を確認する
コードを記述したら、Visual Studioの「開始」ボタンをクリックするか、F5キーを押します。
グラフが表示されない場合は、次の3点を確認してください。
ChartAreaが追加されているか
SeriesがChartに追加されているか
Seriesにデータが1件以上登録されているか
5. 初心者向けサンプルコードでC#のグラフ表示を実装する
5-1. フォーム起動時にグラフを表示するサンプルコード
次のコードでは、フォームが起動した時点で折れ線グラフを表示します。
C#using System;
using System.Drawing;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;
namespace ChartSample
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
DrawLineChart();
}
private void DrawLineChart()
{
chart1.Series.Clear();
chart1.ChartAreas.Clear();
chart1.Legends.Clear();
chart1.Titles.Clear();
ChartArea chartArea = new ChartArea("MainArea");
chartArea.AxisX.Title = "月";
chartArea.AxisY.Title = "売上";
chartArea.AxisX.Interval = 1;
chartArea.AxisY.Minimum = 0;
chartArea.AxisY.Interval = 50;
chart1.ChartAreas.Add(chartArea);
Series series = new Series("売上");
series.ChartArea = "MainArea";
series.ChartType = SeriesChartType.Line;
series.BorderWidth = 3;
series.MarkerStyle = MarkerStyle.Circle;
series.MarkerSize = 8;
series.Points.AddXY("1月", 120);
series.Points.AddXY("2月", 150);
series.Points.AddXY("3月", 135);
series.Points.AddXY("4月", 180);
series.Points.AddXY("5月", 210);
series.Points.AddXY("6月", 195);
chart1.Series.Add(series);
chart1.Legends.Add(new Legend("MainLegend"));
chart1.Titles.Add("月別売上");
}
}
}
5-2. ボタンクリックでグラフを表示するサンプルコード
ボタンをクリックしたときにグラフを表示したい場合は、フォームのコンストラクターからDrawLineChartを呼び出さず、ボタンのクリックイベントから呼び出します。
C#public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
DrawLineChart();
}
Visual Studioのデザイナー上でボタンをダブルクリックすると、クリックイベントが自動作成されます。
同じボタンを何度押しても系列が重複しないように、DrawLineChartの先頭でSeries.ClearやChartAreas.Clearを実行しておくことが重要です。
5-3. 配列データをグラフ化するサンプルコード
実際のアプリでは、固定値ではなく配列やデータベースから取得した値をグラフ化することが多くなります。
C#private void DrawArrayData()
{
string[] months =
{
"1月", "2月", "3月",
"4月", "5月", "6月"
};
double[] sales =
{
120, 150, 135,
180, 210, 195
};
if (months.Length != sales.Length)
{
MessageBox.Show("項目数とデータ数が一致していません。");
return;
}
chart1.Series.Clear();
chart1.ChartAreas.Clear();
ChartArea area = new ChartArea("MainArea");
area.AxisX.Title = "月";
area.AxisY.Title = "売上";
area.AxisX.Interval = 1;
chart1.ChartAreas.Add(area);
Series series = new Series("売上");
series.ChartType = SeriesChartType.Line;
series.BorderWidth = 3;
series.MarkerStyle = MarkerStyle.Circle;
for (int i = 0; i < months.Length; i++)
{
series.Points.AddXY(months[i], sales[i]);
}
chart1.Series.Add(series);
}
X軸の配列とY軸の配列で要素数が異なると、対応関係が崩れます。処理前に要素数を確認しておくと安全です。
5-4. 実行結果の見方
サンプルを実行すると、横軸に月、縦軸に売上が表示されます。
グラフを見ると、1月から2月にかけて売上が増加し、3月に一度減少した後、5月まで増加していることが分かります。
このように、表だけでは見つけにくい増減や傾向を視覚的に確認できることが、グラフ表示の大きな利点です。
6. グラフの見た目をカスタマイズする方法
6-1. グラフタイトルを設定する
グラフタイトルは、Titles.Addで追加できます。
C#chart1.Titles.Clear();
chart1.Titles.Add("月別売上");
文字サイズや太字を設定する場合は、作成したTitleオブジェクトを取得します。
C#Title title = new Title("月別売上");
title.Font = new Font("Meiryo UI", 16, FontStyle.Bold);
chart1.Titles.Add(title);
Chartコントロールでは、Titlesコレクションを通じて複数のタイトルを管理できます。Microsoft Learn
6-2. X軸・Y軸のラベルを設定する
軸タイトルは、ChartAreaのAxisX.TitleとAxisY.Titleで設定します。
C#ChartArea area = chart1.ChartAreas["MainArea"];
area.AxisX.Title = "月";
area.AxisY.Title = "売上金額(万円)";
文字サイズも変更できます。
C#area.AxisX.TitleFont = new Font("Meiryo UI", 11);
area.AxisY.TitleFont = new Font("Meiryo UI", 11);
area.AxisX.LabelStyle.Font = new Font("Meiryo UI", 9);
area.AxisY.LabelStyle.Font = new Font("Meiryo UI", 9);
6-3. 凡例を表示・非表示にする
凡例を表示するには、Legendを追加します。
C#chart1.Legends.Clear();
chart1.Legends.Add(new Legend("MainLegend"));
特定の系列を凡例に表示しない場合は、IsVisibleInLegendをfalseにします。
C#chart1.Series["売上"].IsVisibleInLegend = false;
円グラフなどで凡例が必要な場合はtrueにします。
C#chart1.Series["売上"].IsVisibleInLegend = true;
6-4. 線の色・太さ・マーカーを変更する
折れ線グラフの線やマーカーは、Seriesのプロパティで変更できます。
C#Series series = chart1.Series["売上"];
series.Color = Color.RoyalBlue;
series.BorderWidth = 4;
series.BorderDashStyle = ChartDashStyle.Solid;
series.MarkerStyle = MarkerStyle.Circle;
series.MarkerSize = 9;
series.MarkerColor = Color.White;
series.MarkerBorderColor = Color.RoyalBlue;
series.MarkerBorderWidth = 2;
データの値をグラフ上に表示することもできます。
C#series.IsValueShownAsLabel = true;
series.LabelFormat = "0";
6-5. 軸の最小値・最大値・目盛りを調整する
Y軸を0から300まで、50単位で表示する例です。
C#ChartArea area = chart1.ChartAreas["MainArea"];
area.AxisY.Minimum = 0;
area.AxisY.Maximum = 300;
area.AxisY.Interval = 50;
X軸が数値の場合は、X軸にも範囲を指定できます。
C#area.AxisX.Minimum = 0;
area.AxisX.Maximum = 10;
area.AxisX.Interval = 1;
データの範囲を自動判定させたい場合は、最小値と最大値をDouble.NaNに戻します。
C#area.AxisY.Minimum = double.NaN;
area.AxisY.Maximum = double.NaN;
補助線を表示すると、値を読み取りやすくなります。
C#area.AxisX.MajorGrid.LineDashStyle = ChartDashStyle.Dot;
area.AxisY.MajorGrid.LineDashStyle = ChartDashStyle.Dot;
area.AxisX.MajorGrid.LineColor = Color.LightGray;
area.AxisY.MajorGrid.LineColor = Color.LightGray;
7. 棒グラフ・円グラフ・散布図を表示する方法
7-1. 棒グラフを表示するサンプルコード
縦棒グラフを表示する場合は、ChartTypeにColumnを指定します。
C#private void DrawColumnChart()
{
chart1.Series.Clear();
chart1.ChartAreas.Clear();
chart1.Titles.Clear();
chart1.ChartAreas.Add(new ChartArea("MainArea"));
Series series = new Series("売上");
series.ChartType = SeriesChartType.Column;
series.IsValueShownAsLabel = true;
series.Points.AddXY("商品A", 80);
series.Points.AddXY("商品B", 120);
series.Points.AddXY("商品C", 95);
series.Points.AddXY("商品D", 150);
chart1.Series.Add(series);
chart1.Titles.Add("商品別売上");
}
横棒グラフにしたい場合は、Barを指定します。
C#series.ChartType = SeriesChartType.Bar;
7-2. 円グラフを表示するサンプルコード
円グラフでは、全体に占める割合を表現できます。
C#private void DrawPieChart()
{
chart1.Series.Clear();
chart1.ChartAreas.Clear();
chart1.Legends.Clear();
chart1.Titles.Clear();
chart1.ChartAreas.Add(new ChartArea("MainArea"));
chart1.Legends.Add(new Legend("MainLegend"));
Series series = new Series("構成比");
series.ChartType = SeriesChartType.Pie;
series.IsValueShownAsLabel = true;
series.Label = "#PERCENT{P1}";
series.LegendText = "#VALX";
series["PieLabelStyle"] = "Outside";
series.Points.AddXY("商品A", 40);
series.Points.AddXY("商品B", 30);
series.Points.AddXY("商品C", 20);
series.Points.AddXY("その他", 10);
chart1.Series.Add(series);
chart1.Titles.Add("商品別構成比");
}
#PERCENT{P1}を指定すると、小数点以下1桁の割合を表示できます。
7-3. 散布図を表示するサンプルコード
散布図では、2つの数値に関係があるかを確認できます。
C#private void DrawScatterChart()
{
chart1.Series.Clear();
chart1.ChartAreas.Clear();
chart1.Titles.Clear();
ChartArea area = new ChartArea("MainArea");
area.AxisX.Title = "広告費";
area.AxisY.Title = "売上";
chart1.ChartAreas.Add(area);
Series series = new Series("店舗");
series.ChartType = SeriesChartType.Point;
series.MarkerStyle = MarkerStyle.Circle;
series.MarkerSize = 10;
series.Points.AddXY(10, 80);
series.Points.AddXY(15, 105);
series.Points.AddXY(20, 120);
series.Points.AddXY(25, 145);
series.Points.AddXY(30, 155);
series.Points.AddXY(35, 190);
chart1.Series.Add(series);
chart1.Titles.Add("広告費と売上の関係");
}
7-4. ChartTypeの主な種類一覧
| ChartType | 表示形式 |
|---|---|
Line | 折れ線グラフ |
Spline | 曲線グラフ |
FastLine | 高速描画向け折れ線グラフ |
StepLine | 階段状の折れ線グラフ |
Column | 縦棒グラフ |
Bar | 横棒グラフ |
StackedColumn | 積み上げ縦棒グラフ |
Pie | 円グラフ |
Doughnut | ドーナツグラフ |
Point | 散布図 |
Bubble | バブルチャート |
Area | 面グラフ |
StackedArea | 積み上げ面グラフ |
Radar | レーダーチャート |
Candlestick | ローソク足チャート |
7-5. 用途別におすすめのグラフ種類を選ぶ
時系列データの変化を表す場合は、折れ線グラフが適しています。売上、気温、アクセス数などの推移を確認しやすくなります。
複数の商品や部門を比較する場合は、棒グラフが適しています。
全体に占める構成比を表す場合は、円グラフやドーナツグラフが適しています。ただし、項目数が多いと比較しにくくなるため、5項目程度までに抑えると見やすくなります。
2つの数値の関連性を確認する場合は、散布図が適しています。
8. 実用的なグラフ表示の応用例
8-1. CSVデータを読み込んでグラフ表示する
次のようなCSVファイルを用意します。
csv月,売上
1月,120
2月,150
3月,135
4月,180
5月,210
6月,195
CSVファイルを読み込んでグラフ化するコードは次のとおりです。
C#using System.Globalization;
using System.IO;
using System.Linq;
using System.Windows.Forms.DataVisualization.Charting;
private void DrawCsvChart(string filePath)
{
if (!File.Exists(filePath))
{
MessageBox.Show("CSVファイルが見つかりません。");
return;
}
chart1.Series.Clear();
chart1.ChartAreas.Clear();
chart1.Titles.Clear();
ChartArea area = new ChartArea("MainArea");
area.AxisX.Title = "月";
area.AxisY.Title = "売上";
area.AxisX.Interval = 1;
chart1.ChartAreas.Add(area);
Series series = new Series("売上");
series.ChartType = SeriesChartType.Line;
series.BorderWidth = 3;
series.MarkerStyle = MarkerStyle.Circle;
foreach (string line in File.ReadLines(filePath).Skip(1))
{
string[] columns = line.Split(',');
if (columns.Length < 2)
{
continue;
}
string label = columns[0].Trim();
bool success = double.TryParse(
columns[1].Trim(),
NumberStyles.Float,
CultureInfo.InvariantCulture,
out double value
);
if (success)
{
series.Points.AddXY(label, value);
}
}
chart1.Series.Add(series);
chart1.Titles.Add("CSVから読み込んだ売上データ");
}
呼び出し例は次のとおりです。
C#DrawCsvChart(@"C:\Data\sales.csv");
このサンプルは、値の中にカンマや改行を含まない単純なCSVを対象としています。引用符やカンマを含む本格的なCSVを扱う場合は、CSV解析用ライブラリの利用を検討してください。
8-2. 複数系列のデータを1つのグラフに表示する
売上と利益を同時に表示する例です。
C#private void DrawMultipleSeries()
{
chart1.Series.Clear();
chart1.ChartAreas.Clear();
chart1.Legends.Clear();
ChartArea area = new ChartArea("MainArea");
area.AxisX.Title = "月";
area.AxisY.Title = "金額";
area.AxisX.Interval = 1;
chart1.ChartAreas.Add(area);
chart1.Legends.Add(new Legend("MainLegend"));
Series salesSeries = new Series("売上");
salesSeries.ChartType = SeriesChartType.Line;
salesSeries.BorderWidth = 3;
salesSeries.MarkerStyle = MarkerStyle.Circle;
Series profitSeries = new Series("利益");
profitSeries.ChartType = SeriesChartType.Column;
string[] months =
{
"1月", "2月", "3月",
"4月", "5月", "6月"
};
double[] sales =
{
120, 150, 135, 180, 210, 195
};
double[] profits =
{
20, 35, 25, 45, 60, 50
};
for (int i = 0; i < months.Length; i++)
{
salesSeries.Points.AddXY(months[i], sales[i]);
profitSeries.Points.AddXY(months[i], profits[i]);
}
chart1.Series.Add(profitSeries);
chart1.Series.Add(salesSeries);
}
このように、棒グラフと折れ線グラフを1つのChartAreaに表示することもできます。
売上と利益で数値の桁が大きく異なる場合は、第2Y軸を使用します。
C#profitSeries.YAxisType = AxisType.Secondary;
area.AxisY2.Enabled = AxisEnabled.True;
area.AxisY2.Title = "利益";
8-3. リアルタイムにグラフを更新する
WindowsフォームのTimerを使用すると、一定間隔でデータを追加できます。
C#private readonly Timer graphTimer = new Timer();
private readonly Random random = new Random();
private int currentX = 0;
private void SetupRealtimeChart()
{
chart1.Series.Clear();
chart1.ChartAreas.Clear();
ChartArea area = new ChartArea("MainArea");
area.AxisX.Title = "経過時間";
area.AxisY.Title = "温度";
area.AxisY.Minimum = 15;
area.AxisY.Maximum = 30;
chart1.ChartAreas.Add(area);
Series series = new Series("温度");
series.ChartType = SeriesChartType.Line;
series.BorderWidth = 2;
series.MarkerStyle = MarkerStyle.Circle;
chart1.Series.Add(series);
graphTimer.Interval = 1000;
graphTimer.Tick += GraphTimer_Tick;
graphTimer.Start();
}
private void GraphTimer_Tick(object sender, EventArgs e)
{
Series series = chart1.Series["温度"];
double value = 20 + random.NextDouble() * 5;
series.Points.AddXY(currentX, value);
currentX++;
while (series.Points.Count > 60)
{
series.Points.RemoveAt(0);
}
ChartArea area = chart1.ChartAreas["MainArea"];
if (currentX > 60)
{
area.AxisX.Minimum = currentX - 60;
area.AxisX.Maximum = currentX;
}
chart1.Invalidate();
}
フォームのコンストラクターなどから呼び出します。
C#public Form1()
{
InitializeComponent();
SetupRealtimeChart();
}
System.Windows.Forms.TimerのTickイベントはUIスレッド上で実行されるため、Chartコントロールを直接更新できます。
一方、通信処理や別スレッドから値を受信する場合は、InvokeまたはBeginInvokeを使ってUIスレッドに処理を戻す必要があります。
8-4. グラフ画像を保存する
Chartコントロールは、グラフを画像として保存できます。
C#chart1.SaveImage(
@"C:\Data\chart.png",
ChartImageFormat.Png
);
JPEG形式で保存する場合は、次のように指定します。
C#chart1.SaveImage(
@"C:\Data\chart.jpg",
ChartImageFormat.Jpeg
);
保存先をユーザーに選択してもらう場合は、SaveFileDialogを使用します。
C#private void SaveChartImage()
{
using (SaveFileDialog dialog = new SaveFileDialog())
{
dialog.Filter = "PNG画像|*.png|JPEG画像|*.jpg";
dialog.FileName = "chart.png";
if (dialog.ShowDialog() != DialogResult.OK)
{
return;
}
string extension = Path.GetExtension(dialog.FileName).ToLower();
ChartImageFormat format =
extension == ".jpg" || extension == ".jpeg"
? ChartImageFormat.Jpeg
: ChartImageFormat.Png;
chart1.SaveImage(dialog.FileName, format);
}
}
8-5. データをクリアして再描画する
系列を残したまま、データだけを消す場合はPoints.Clearを使います。
C#chart1.Series["売上"].Points.Clear();
すべての系列を削除する場合は、次のようにします。
C#chart1.Series.Clear();
描画領域も含めて作り直す場合は、次のように各コレクションをクリアします。
C#chart1.Series.Clear();
chart1.ChartAreas.Clear();
chart1.Legends.Clear();
chart1.Titles.Clear();
グラフを再描画する場合は、クリア後にChartArea、Series、データの順番で追加し直します。
9. Chartコントロールでよくあるエラーと対処法
9-1. Chartコントロールがツールボックスに表示されない
最初に、プロジェクトの種類を確認してください。
「Windows Forms App」ではなく、「Windows Forms App(.NET Framework)」を選択している必要があります。
.NET Frameworkプロジェクトで表示されない場合は、ツールボックスを右クリックし、「アイテムの選択」からChartを追加します。
新しい.NETを使用している場合は、標準Chartに固執せず、ScottPlotやLiveChartsなど、対象フレームワークに対応したライブラリを選ぶ方法もあります。
9-2. System.Windows.Forms.DataVisualizationが見つからない
次のエラーが発生することがあります。
型または名前空間の名前
'DataVisualization'が名前空間
'System.Windows.Forms'に存在しません
.NET Frameworkプロジェクトの場合は、参照設定にSystem.Windows.Forms.DataVisualizationを追加します。
参照追加後、コードの先頭に次のusingディレクティブを記述します。
C#using System.Windows.Forms.DataVisualization.Charting;
プロジェクトが新しい.NETを対象としている場合は、参照追加だけでは解決しないことがあります。プロジェクトのターゲットフレームワークを確認してください。
9-3. グラフが表示されない
グラフが空白の場合は、次の項目を順番に確認します。
C#Console.WriteLine(chart1.ChartAreas.Count);
Console.WriteLine(chart1.Series.Count);
Console.WriteLine(chart1.Series[0].Points.Count);
すべて1以上である必要があります。
Seriesが使用するChartArea名も確認してください。
C#series.ChartArea = "MainArea";
指定した名前のChartAreaが存在しないと、正しく表示されません。
Chartコントロール自体のサイズが0になっていないか、Visibleがfalseになっていないかも確認します。
9-4. 軸や凡例が意図した通りに表示されない
円グラフでは通常のX軸やY軸は表示されません。
複数系列を使用している場合は、各系列のChartArea、XAxisType、YAxisTypeを確認してください。
凡例が表示されない場合は、Legendが追加されているか確認します。
C#chart1.Legends.Add(new Legend("MainLegend"));
Series側の設定も確認します。
C#series.IsVisibleInLegend = true;
同じ名前のLegendやSeriesを複数回追加すると例外になるため、再描画前にコレクションをクリアする方法が安全です。
9-5. データ更新時に前回のグラフが残る
ボタンを押すたびに同じデータが追加される場合は、データ追加前にPoints.Clearを実行します。
C#Series series = chart1.Series["売上"];
series.Points.Clear();
グラフの種類や系列構成も変更する場合は、Series全体をクリアします。
C#chart1.Series.Clear();
ChartAreaまで毎回追加するコードでは、ChartAreaもクリアしないと同名エラーが発生します。
C#chart1.ChartAreas.Clear();
10. C#のグラフ表示に使える他のライブラリ
10-1. OxyPlotの特徴
OxyPlotは、主に2次元グラフの描画を目的とした.NET向けライブラリです。
グラフ全体をPlotModelとして構築し、折れ線、散布図、棒グラフ、軸、注釈などをモデルとして管理します。WPFでは、XAMLにPlotViewを配置し、PlotModelをバインドする構成を利用できます。OxyPlot+2
OxyPlot+2
OxyPlotが適しているのは、次のようなケースです。
WPFでグラフを表示したい
シンプルな2次元グラフを作りたい
MVVMに合わせてデータを管理したい
軸や注釈を細かく設定したい
10-2. LiveChartsの特徴
LiveChartsは、アニメーションを含む見た目のよいグラフを作成しやすいライブラリです。
LiveCharts2は、Windows Forms、WPF、WinUI、Avalonia、Blazor、MAUIなど複数のUIフレームワークに対応しています。公式サイトでは、WinForms用のCartesianChartをツールボックスから配置する導入方法が案内されています。livecharts.dev+2
GitHub+2
LiveChartsが適しているのは、次のようなケースです。
アニメーション付きグラフを作りたい
モダンな見た目を重視したい
WPFや新しい.NETを使用したい
データバインディングを活用したい
導入時は、利用するバージョンが安定版かプレリリース版かをNuGet上で確認してください。
10-3. ScottPlotの特徴
ScottPlotは、大量の数値データを対話的に表示する用途に強い.NET向けグラフライブラリです。
公式のWindows Forms向け手順では、ScottPlot.WinFormsをインストールし、FormsPlotをフォームに配置してグラフを描画します。折れ線、棒、円、散布図などに対応し、マウス操作による拡大縮小も利用できます。ScottPlot+1
基本的なコードは次のようになります。
C#double[] xs = { 1, 2, 3, 4, 5 };
double[] ys = { 1, 4, 9, 16, 25 };
formsPlot1.Plot.Add.Scatter(xs, ys);
formsPlot1.Refresh();
ScottPlotが適しているのは、次のようなケースです。
大量のデータを表示したい
計測データや科学技術データを扱いたい
マウスでグラフを操作したい
新しい.NETのWindows FormsやWPFを使用したい
ScottPlot 5は2024年に最初のリリースが行われ、公式サイトではScottPlot 4.1以前を旧バージョンとして扱っています。新規開発では、使用するサンプルコードがScottPlot 5向けか確認することが重要です。ScottPlot
10-4. Chartコントロールと外部ライブラリの違い
| 比較項目 | Chartコントロール | 外部ライブラリ |
|---|---|---|
| 導入 | .NET Frameworkでは簡単 | NuGetで追加する |
| 対応環境 | 主にWindows Formsと.NET Framework | WPFや新しい.NETにも対応しやすい |
| 学習のしやすさ | 初心者向け | ライブラリによって異なる |
| 表現力 | 基本機能が充実 | モダンな表現や高速描画に強い |
| アニメーション | 限定的 | LiveChartsなどが得意 |
| 大量データ | 工夫が必要 | ScottPlotなどが得意 |
| データバインディング | 基本的な機能 | WPF向けライブラリが得意 |
10-5. 初心者が最初に選ぶべき方法
.NET FrameworkのWindowsフォームアプリで、基本的な折れ線グラフや棒グラフを作る場合は、Chartコントロールから始めるとよいでしょう。
一方、新しくプロジェクトを作成し、最新の.NETを使用する場合は、ScottPlotやLiveChartsなども有力な選択肢です。
選び方の目安は次のとおりです。
.NET Frameworkの業務アプリ:Chartコントロール
WPFでシンプルなグラフ:OxyPlot
アニメーションや見た目を重視:LiveCharts
大量データや計測データ:ScottPlot
11. C#のグラフ表示に関するよくある質問
11-1. C#でグラフ表示するには何を使えばいい?
Windows Forms App(.NET Framework)で簡単なグラフを作る場合は、Chartコントロールが使いやすい選択肢です。
新しい.NETやWPFを使用する場合は、OxyPlot、LiveCharts、ScottPlotなどの外部ライブラリを検討してください。
11-2. Chartコントロールは無料で使える?
.NET FrameworkのWindows Formsで提供されるChartコントロールについては、通常、コントロール単体を別途購入する必要はありません。
ただし、Visual Studioや.NET Framework、配布するアプリケーションに関係するライセンス条件は、それぞれ確認してください。
11-3. WPFでもChartコントロールは使える?
Windows Forms用のChartコントロールを、WindowsFormsHostを使ってWPFに埋め込む方法はあります。
ただし、WPFではレイアウト、データバインディング、見た目の統一が複雑になりやすいため、OxyPlot、LiveCharts、ScottPlotなどのWPF対応ライブラリを使用する方法が一般的です。OxyPlotとScottPlotには、それぞれWPF向けの導入手順が用意されています。OxyPlot+1
11-4. 折れ線グラフと棒グラフは同時に表示できる?
同時に表示できます。
同じChartAreaを使用するSeriesを2つ作成し、それぞれ異なるChartTypeを指定します。
C#Series columnSeries = new Series("売上");
columnSeries.ChartType = SeriesChartType.Column;
Series lineSeries = new Series("利益率");
lineSeries.ChartType = SeriesChartType.Line;
lineSeries.YAxisType = AxisType.Secondary;
値の単位が異なる場合は、第2Y軸を使用すると見やすくなります。
11-5. リアルタイムグラフはChartコントロールで作れる?
作成できます。
System.Windows.Forms.Timerを使用して、一定間隔でPoints.AddXYを実行します。
ただし、データを追加し続けるとメモリ使用量と描画時間が増えるため、表示件数を制限することが重要です。
C#while (series.Points.Count > 100)
{
series.Points.RemoveAt(0);
}
大量のデータを高速に更新する必要がある場合は、FastLineを使用するか、ScottPlotなど大量データの表示を得意とするライブラリも検討してください。
まとめ
C#でグラフ表示を行う基本的な流れは、次のとおりです。
WindowsフォームにChartコントロールを配置する
ChartAreaで描画領域と軸を設定するSeriesでデータ系列を作成するPoints.AddXYでデータを追加するChartTypeでグラフの種類を指定する
折れ線グラフを表示する最小構成は、次のコードです。
C#chart1.Series.Clear();
chart1.ChartAreas.Clear();
chart1.ChartAreas.Add(new ChartArea("MainArea"));
Series series = new Series("データ");
series.ChartType = SeriesChartType.Line;
series.Points.AddXY(1, 10);
series.Points.AddXY(2, 20);
series.Points.AddXY(3, 15);
chart1.Series.Add(series);
この基本形を理解すれば、棒グラフ、円グラフ、散布図、複数系列、CSVデータ、リアルタイム更新にも応用できます。
.NET FrameworkのWindowsフォームアプリではChartコントロールが扱いやすい一方、新しい.NETやWPFでは外部ライブラリが適している場合があります。開発環境、表示するデータ量、必要なデザインや操作性を考慮して、最適な方法を選びましょう。

