もっと詳しく

ScottPlotが Ver4.1 になって、グラフの左右にY軸(つまりY軸が2個)が表示できるようになりました。

今回は、以前公開した「【WPF】C#+ScottPlotで複合グラフのユーザーコントロールを作る!」のソースコードを ScottPlot 4.1 に対応させ、ついでにY2軸が使えるように修正しましたので、紹介したいと思います。

複合グラフの表示例

このユーザーコントロールを使うと、次のようなY2軸の複合グラフが表示できます。

赤い線がY2軸のスケール(0~2250)で表示され、それ以外はY1軸のスケール(0~200)で表示されています。

ユーザーコントロールの使い方

では、ユーザーコントロールの使い方は、各グラフ(折線、棒)ごとに左右どちらのY軸を使うかが指定できるようになった以外は前回の記事と全く同じです。

メソッド

メソッドは下記の2つのみです。

メソッド名 引数の説明 内容
void Clear() グラフの消去
void Draw(string title) title:グラフのタイトル グラフの描画

プロパティ一覧

プロパティは以下の通りです。

前回との違いは、Yの1,2軸を指定するための YAxisNo と、Y2軸のタイトルを設定する YAxis2Title が追加されています。

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軸のタイトル
int[] YAxisNo null Y軸の指定
YValuesの登録順に0か1を配列で指定(0:左のY軸、1:右のY軸)
例えば、3個のグラフを描画する際、1つ目のY2軸に表示するには
new int[]{1,0,0} 

使い方とサンプルソース

呼び出し手順は次の通りです。

  1. LabelsにX軸に表示したいラベルを登録、YValuesにはY軸に表示したいデータを指定します。
  2. Y軸に表示したいデータの中で、棒グラフとして描画したいものについて、その番号をBarStyleDataNoプロパティに指定します。
  3. Y軸に表示したいデータの中で、Y1軸(左)に表示したいものは、0を、Y2軸(右)に表示したいものは1 を YAxisNo に指定します。
  4. 最後に、Draw プロパティを呼び出せば、複合グラフが表示されます。

Drawプロパティにはグラフのタイトルを指定します。

尚、YValues に折れ線の値を Add メソッドで追加していく仕様なので、最初にClear メソッドを呼んで Listの中身をクリアしていて下さい。

クリアを忘れると、同じ処理を実行する度に前回にAddしたYValuse の内容も合わせて表示されるため、グラフが線だらけになります。

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[] { 2000, 1000,1600, 2200, 1800 });
uxLineBarChart.YAxisNo = new int[] { 0,0,0,1 };
//uxLineBarChart.Colors = new string[] { "orange","red","gray","pink","magenta"};
uxLineBarChart.BarStyleDataNo = 0;
uxLineBarChart.XAxisTitle = "年度";
uxLineBarChart.YAxisTitle = "台数";
uxLineBarChart.YAxis2Title = "在庫数";

uxLineBarChart.Draw("折れ線と棒グラフ");

ユーザーコントロールの解説

事前準備

あらかじめ NuGet を使って、 ScottPlot.WPF をインストールしておいてください。

ScottPlotのインストールについて分からない方は、 こちら の記事を参照ください。

ユーザーコントロールの作り方については、こちらの記事をご参照ださい。

レイアウトの作成

【WPF】C#+ScottPlotで複合グラフのユーザーコントロールを作る」と全く同じです。

というか、前回のソースを修正しただけなので、プロジェクト名は WpfLineBarChartTest ユーザーコントロール名は ScottLineBarChartControl になっています。

ちなみに、ユーザーコントロールにScottPlotを張り付けると、下記の様になります。

XAMLのソースコード

以下がXAMLのソースコードです。

単に最新版のScottPlot を張り付け直しただけなので手を加えていません。

前回と全く同じです。

<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#側のソースコードになります。

using ScottPlot;
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;

namespace WpfPiChartTest
{
    /// <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 string YAxis2Title { get; set; }                             //Y2軸のタイトル
        public int[] YAxisNo { get; set; }                                  //Y軸の指定


        //コンストラクタ
        public ScottLineBarChartControl()
        {
            InitializeComponent();
        }

        /// <summary>
        /// 描画処理
        /// </summary>
        /// <param name="title"></param>
        public void Draw(string title)
        {
            //描画エリアのクリア
            uxScottPlot.Plot.Clear();
            //グラフタイトルの表示
            uxScottPlot.Plot.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();

            //描画データを取り出してグラフを作成
            for (int no = 0; no < YValues.Count; no++)
            {
                //棒又は線の色を取得
                System.Drawing.Color? color = null;
                if (Colors != null) color = colors[no];

                //凡例を取得
                var legend = (Legends == null) ? null : Legends[no];

                //棒グラフ対象のデータであれば棒グラフを、そうでなければ折れ線グラフを作成
                if (BarStyleDataNo == no)
                {
                    //棒グラフの作成
                    var bar = uxScottPlot.Plot.AddBar(YValues[no], xvalue);
                    bar.Label = legend;
                    bar.ShowValuesAboveBars = ShowValues;
                    if (color != null) bar.FillColor = color ?? System.Drawing.Color.Empty;
                    if (YAxisNo != null) bar.YAxisIndex = YAxisNo[no];
                }
                else
                {
                    //折れ線グラフの作成
                    var scat = uxScottPlot.Plot.AddScatter(xvalue, YValues[no], lineWidth: 2, markerSize: 10, lineStyle: LineStyle.Solid, color: color, label: legend);
                    if (YAxisNo != null)  scat.YAxisIndex = YAxisNo[no];
                }
            }

            //X軸に表示するラベルを設定
            uxScottPlot.Plot.XTicks(labels);
            //グリッド線の表示
            uxScottPlot.Plot.Grid(true);
            //フレーム(外枠)の表示
            //uxScottPlot.Plot.Frameless(false);
            //凡例の表示
            if (ShowLegend) uxScottPlot.Plot.Legend(true);
            //X軸のタイトルを設定
            uxScottPlot.Plot.XLabel(XAxisTitle);
            //Y軸のタイトルを設定
            uxScottPlot.Plot.YLabel(YAxisTitle);
            //軸の指定があれば、Y2軸番号を表示
            uxScottPlot.Plot.YAxis2.Ticks(YAxisNo != null ? true : false);
            //Y2軸のタイトルを表示
            uxScottPlot.Plot.YAxis2.Label(YAxis2Title);

            //グラフを描画
            uxScottPlot.Render();
        }

        /// <summary>
        /// グラフ表示エリアとデータのクリア
        /// </summary>
        public void Clear()
        {
            uxScottPlot.Plot.Clear();
            YValues.Clear();
        }
    }
}

今回は「【WPF】C#+ScottPlotで複合グラフのユーザーコントロールを作る!」のソースコード をScottPlot 4.1で動くように修正しているだけなので、詳細については上記の記事をご覧ください。

また、旧バージョンから移行を考えている方は、下記の記事に詳細を載せていますのでご一読ください。

まとめ

フリーのチャートライブラリ ScottPlot が 2021年7月に 大幅なバージョンアップが行われ、Y2軸対応になりました。

今回は、以前公開した「複合グラフのユーザーコントロール」をScottPlotに対応させ、更にY2軸が使えるように修正致しました。

とはいえ、このユーザーコントロールはシンプルな構成であり、皆さんが実際に使うには機能が不足していると思います。

あくまでも参考情報としての位置づけですが、皆様のプログラミングの一助になれば幸いです。