今回はScottPlotを使って、WPFで使える複合グラフ描画用のユーザーコントロールを作ってみました。
複合グラフと言っても、折れ線グラフと棒グラフの組み合わせになりますが、ユーザーコントロールを画面に張り付けて、データをセットするだけで簡単に複合グラフが作成できます。
複合グラフの表示例
このユーザーコントロールを使うと、次のような複合グラフが表示できます。

ユーザーコントロールの使い方
では、ユーザーコントロールの使い方について解説していきます。
メソッド
メソッドはシンプルで、次の2つが用意されています。
メソッド名 | 引数の説明 | 内容 |
---|---|---|
void Clear() | グラフの消去 | |
void Draw(string title) | title:グラフのタイトル | グラフの描画 |
プロパティ一覧
次のプロパティが用意されています。
string[] Labels | null | X軸に表示するラベル |
List<string[]> YValues | null | Y軸のデータ |
string[] Colors | null | 棒グラフ、折れ線グラフの色 |
int BarStyleDataNo | null | Listに登録されたYValuesにおいて、棒グラフとして表示させたいList上の番号 |
bool ShowValues | false | true にすると棒グラフに値を表示 |
bool ShowLegend | true | trueにすると凡例を表示 |
string[] Legends | false | 凡例として表示する各データのタイトル(YValuesに登録した数だけ用意) |
string XAxisTitle | null | X軸のタイトル |
string YAxisTitle | null | Y軸のタイトル |
使い方とサンプルソース
LabelsにX軸に表示したいラベルを、YValuesにはY軸に表示したいデータを指定し、更に棒グラフとして表示したいデータをBarStyleDataNoプロパティで指定します。

最後に、Draw プロパティを呼び出すことで複合グラフが表示されます。
Drawプロパティにはグラフのタイトルを指定してください。
注意点としては、YValues に折れ線の値を Add メソッドで追加していく仕様なので、最初にClear メソッドを呼んで Listの中身をクリアしておく点です。
でないと、同じ処理を実行する度に前回にAddしたYValuse の内容も合わせて表示され、グラフが線だらけになってしまいます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
uxLineBarChart.Clear(); uxLineBarChart.ShowValues = true; uxLineBarChart.Labels = new string[] { "2019年", "2020年", "2021年", "2022年", "2023年" }; uxLineBarChart.Legends = new string[] { "予測台数", "実績台数", "顧客数", "在庫数" }; uxLineBarChart.YValues.Add(new double[] { 100, 100, 200, 50, 50 }); uxLineBarChart.YValues.Add(new double[] { 110, 150, 120, 150, 130 }); uxLineBarChart.YValues.Add(new double[] { 120, 140, 160, 120, 140 }); uxLineBarChart.YValues.Add(new double[] { 200, 100, 160, 220, 180 }); //uxLineBarChart.Colors = new string[] { "orange","red","gray","pink","magenta"}; uxLineBarChart.BarStyleDataNo = 0; uxLineBarChart.XAxisTitle = "年度"; uxLineBarChart.YAxisTitle = "台数"; uxLineBarChart.Draw("折れ線と棒グラフ"); |
ユーザーコントロールの解説
事前準備
今回はフリーのチャートライブラリである ScottPlot を使いますので、NuGetによるインストールが必要です。
NuGetから 「scott」で検索し、 ScottPlot.WPF を選んでインストールして下さい。

ScottPlotのインストールについて詳しい情報を知りたい方は、 こちら の記事をご覧ください。
また、ユーザーコントロールの作り方が知りたい方は、こちらの記事をご覧ください。
レイアウトの作成
今回は、プロジェクト名を WpfLineBarChartTest ユーザーコントロール名を ScottLineBarChartControl で作成しています。
まず、レイアウトエディタでツールボックスに表示されている WpfPlot を張り付けておいて下さい。

XAMLのソースコード
以下がXAMLのソースコードです。
ScottPlotチャートコントロールに対して、uxScottPlot という名前を付けています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<UserControl x:Class="WpfLineBarChartTest.ScottLineBarChartControl" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:WpfLineBarChartTest" mc:Ignorable="d" d:DesignHeight="400" d:DesignWidth="400"> <Grid> <WpfPlot x:Name="uxScottPlot"/> </Grid> </UserControl> |
C#のソースコード
以下がC#側のソースコードになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using ScottPlot; namespace WpfLineBarChartTest { /// <summary> /// ScottLineBarChartControl.xaml の相互作用ロジック /// </summary> public partial class ScottLineBarChartControl : UserControl { public string[] Labels { get; set; } //X軸のラベル(省略すると0から始まる連番) public List<double[]> YValues { get; set; } = new List<double[]>(); //Y軸のデータ public string[] Colors { get; set; } //棒グラフ、折れ線グラフの色 public int? BarStyleDataNo { get; set; } //縦棒のグラフとして表示したいデータの番号 public bool ShowValues { get; set; } = false; //棒グラフに値を表示 public bool ShowLegend { get; set; } = true; //凡例の表示 public string[] Legends { get; set; } //凡例の表示 public string XAxisTitle { get; set; } //X軸のタイトル public string YAxisTitle { get; set; } //Y軸のタイトル //コンストラクタ public ScottLineBarChartControl() { InitializeComponent(); } /// <summary> /// 描画処理 /// </summary> /// <param name="title"></param> public void Draw(string title) { //描画エリアのクリア uxScottPlot.plt.Clear(); //グラフタイトルの表示 uxScottPlot.plt.Title(title); //線の色が指定されていた場合、配列に格納 var colors = Colors?.Select(i => System.Drawing.Color.FromName(i)).ToArray(); //X軸様に0から始まる連番を作成 double[] xvalue = DataGen.Consecutive(YValues[0].Length); //X軸に表示するラベルを取得 string[] labels = Labels ?? xvalue.Select(i => i.ToString()).ToArray(); //凡例に表示するラベルを取得 string[] legends = Legends ?? xvalue.Select(i => i.ToString()).ToArray(); //描画データを取り出してグラフを作成 for (int no = 0; no < YValues.Count; no++) { //棒又は線の色を取得 System.Drawing.Color? color = null; if (Colors != null) color = colors[no]; //棒グラフ対象のデータであれば棒グラフを、そうでなければ折れ線グラフを作成 if (BarStyleDataNo == no) { //棒グラフの作成 uxScottPlot.plt.PlotBar(xvalue, YValues[no], showValues: ShowValues, fillColor: color,label:legends[no]); } else { //折れ線グラフの作成 uxScottPlot.plt.PlotScatter(xvalue, YValues[no], lineWidth: 2, markerSize: 10, lineStyle: LineStyle.Solid, color: color, label: legends[no]); } } //X軸に表示するラベルを設定 uxScottPlot.plt.XTicks(labels); //グリッド線の表示 uxScottPlot.plt.Grid(true); //フレーム(外枠)の表示 uxScottPlot.plt.Frame(true); //凡例の表示 if (ShowLegend) uxScottPlot.plt.Legend(true); //X軸のタイトルを設定 uxScottPlot.plt.XLabel(XAxisTitle); //Y軸のタイトルを設定 uxScottPlot.plt.YLabel(YAxisTitle); //Y軸を描画エリアに収まるように調整 uxScottPlot.plt.AxisAutoY(); //グラフを描画 uxScottPlot.Render(); } /// <summary> /// グラフ表示エリアとデータのクリア /// </summary> public void Clear() { uxScottPlot.plt.Clear(); YValues.Clear(); } } } |
グラフ描画のポイント
今回は、PlotBar メソッドで棒グラフを、PlotScatterメソッドで折れ線グラフを作成しています。
PlotScatterの引数には、X軸、Y軸のデータや、折れ線の色と太さ、線の種類、凡例に表示するラベル、マーカーの形やサイズなどが指定できますが、今回は一部だけ使いました。
また、マーカーサイズは10、線幅は2、線の種類はLineStyle.Solid に固定しています。
凡例については、ShowLegend プロパティで外部から表示/非表示を設定できるようにしていますが、Legends プロパティに何も設定しなければ、凡例の枠さえ表示されません(ScottPlotの仕様です)。
線の色指定についても、前回の記事「【WPF】ScottPlotで円グラフのユーザーコントロールを作ってみました」と同じ理由(Color.Red などの指定だと、stem.Drawing.Color と System.Window.Media.Color が被るので、いちいち stem.Drawing.Color.Red と記述しないといけなくなる)から、文字列で指定するようになっています。
棒グラフと折れ線グラフを同時に描画する場合、両者における最大値の差が大きいと、棒グラフの最大値がグラフに収まるように自動調整され、結果的に折れ線グラフがはみ出してしまう現象が発生しました。
解決策として、uxScottPlot.plt.AxisAutoY() を使って明示的に縦軸が画面に収まるようにしています。

まとめ
フリーのチャートライブラリ ScottPlot を使って、WPFで使える複合グラフのユーザーコントロールについて、使い方とソースコードを紹介しました。
ScottPlotは様々なグラフを重ねて描画することが可能なようですが、今回は棒グラフと折れ線グラフの2種類を使った複合グラフになっています。
ユーザーコントロールにしておけば、このような複合グラフも張り付けるだけで簡単に使える様になるため、是非ご活用ください。