C#

【C# グラフライブラリ】ScottPlotの紹介 まとめ

はじめに

無料で使えて、高機能・高速・良デザインのグラフを作成できる「ScottPlot」の紹介まとめです。

以前も紹介記事を書いてますが、新バージョンのリリースや、細かい機能も紹介してきたので、まとめもかねてて再度ScottPlotをなるべくわかりやすく紹介します。

ScottPlotのサンプルコードの実行結果
ScatterPlotのサンプルコードの実行結果
~ この記事の内容 ~
  • はじめに
  • ScottPlotの概要
  • 散布図の作り方
  • カスタマイズ・便利機能 コードも貼る
  • その他グラフ
  • まとめ

ScottPlotで出来ること
  • さくさく動くグラフを作れる。
  • グラフの拡大・縮小・移動がコードなしで作れる
  • 軸・凡例・目盛のカスタマイズできる
  • 大量のデータを読み込んでも描画が遅くない
  • 簡易的なリアルタイム描画もできる

ScottPlotの概要

ScottPlotは、無料で高機能・高速・良デザインのグラフを作成できるグラフライブラリです。NuGet対応なのでインストールも簡単です。MITライセンスなので商用でも利用することができます。

開発も活発で、2021年5月に大規模アップデートの「Ver.4.1」がリリースされました。本家HPにサンプルコードや画像が「CookBook」として体系化されて公開されています。

Ver.4.1のアップデートの概要や注目点などの詳細は以下の記事をご覧ください。

公式HP・紹介サイトなど

CookBookが掲載されている公式サイトや、GitHubのプロジェクトページは以下です。

また、以前は皆無でしたが、最近では日本語のサイトやQiitaの記事も見かけるようになってきました。日本での知名度が上がってきた証拠だと思うので、個人的にもうれしいです。

公式HP

https://swharden.com/scottplot/

GitHubプロジェクトページ

https://github.com/ScottPlot/ScottPlot

【WPF】いちばんやさしいScottPlot の使い方(WindowsForm共通)

https://resanaplaza.com/%E3%80%90wpf%E3%80%91%E3%81%84%E3%81%A1%E3%81%B0%E3%82%93%E3%82%84%E3%81%95%E3%81%97%E3%81%84scottplot-%E3%81%AE%E4%BD%BF%E3%81%84%E6%96%B9%EF%BC%88windowsform%E5%85%B1%E9%80%9A%EF%BC%89/

C# グラフライブラリ ScottPlotのTips

https://qiita.com/ohru131/items/8cc5d3d539a74d05423d

※ Qiita記事での本サイトへのリンクの掲載ありがとうございます。

ライセンス・人気度・プラットフォーム

ScottPlotのライセンスや、DL数などは以下の通りです。

ライセンス MIT
.NETバージョン.NET 4.6.1~
.NET Core 2.0 ~
   
※.NET 5.0にも対応 
NuGet ダウンロード数   104K
GitHub Star数930 

プラットフォーム

  • Windows Forms
  • WPF
  • Avalonia
  • Console Application

※最新のVer.4.1系の内容を掲載しています
※ 2021年8月時点の情報です

散布図の作り方

以下のシンプルなグラフであれば、5行の実装で作ることができます。

下のGIF動画は、最新のScottPlot Ver.4.1で、線付きの散布図(折れ線グラフ)を作成したものです。
拡大・縮小や、デザインはデフォルトなので実装や設定はする必要ありません。

ScottPlot4.1での散布図の実行結果

全体コード

上記のグラフを作成するコードは以下の通りです。usingも含めて実装コードは5行のみです。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

using ScottPlot; // DataGenに使います

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

            // サンプル用のポイントデータです
            double[] xs = DataGen.Consecutive(51);
            double[] sin = DataGen.Sin(51);

            // データをプロットします
            formsPlot1.Plot.AddScatter(xs, sin);

        }
    }
}

より細かい作り方は・・・

NuGetでのインストール方法や、コントロールの貼り付け方など、さらに細かい内容は以下の記事をご覧ください。Ver.4.0の記事ですが最新版でも同じ方法で作ることができます。

カスタマイズ・便利機能

表示やグラフの設定についても、いろいろな機能が充実しています。長くなってしまうので詳細は過去の記事をご覧ください。Ver.4.0の記事もありますが、実装方法や実行時のイメージは確認できると思います。

グラフ操作・表示関連

  • 拡大・縮小範囲の制限
  • データに合わせた表示範囲の自動設定(オートスケール)
  • 目盛間隔や表示の設定

グラフのカスタマイズ関連

  • Y軸を日付にする
  • 第二軸を表示させる

リアルタイム描画

ScottPlotは静的(固定された)データの描画を得意とするため、あくまで「おまけ」程度ですが、簡易的にグラフをリアルタイムに描画することもできます。

まとめ

長くなってしまいましたが、ScottPlotの使い方や、細かい機能などについてまとめてみました。参考になればうれしいです。

ScottPlotについては他にも記事があります。興味のある方はトップページ右上のメニューから「ScottPlot」を選んで記事をご覧ください。

【おすすめ】UdemyでC#のスキルを上げる

C#のスキルを上げるには、Udemyの動画講座がおすすめです。「C#で読みやすいコードを書く50の方法」「保守性の高いコードの書き方」など、脱初心者/スキルアップのための講座が多数公開されています。

1講座 2440円程度で返金保証あり。視聴期間も無制限なので「自分のペースでコスパ良くスキルアップしたい」「失敗したくない」とお悩み方におすすめです。

⇒ C#の講座一覧はこちら
icon

質問・要望 大歓迎です

「こんな解説記事作って」「こんなことがしたいけど、〇〇で困ってる」など、コメント欄で教えてください。 質問・要望に、中の人ができる限り対応します。

使えたよ・設定できたよの一言コメントも大歓迎。気軽に足跡を残してみてください。記事を紹介したい方はブログ、SNSにバシバシ貼ってもらってOKです。

ABOUT ME
えす
現役のソフトウェアエンジニアです。 C++ C# Python を使ってます。10年ちょい設計/開発部門にいましたが、今はQAエンジニアっぽいことをしています。

POSTED COMMENT

  1. れん より:

    ScottPlotの解説、分かりやすくてとても助かります。
    CookBookなどを見てもわからなかったので質問させて頂きたいのですが、グラフは通常だと左から右に描画されますが、右から左に描画してほしいときはどうすればいいでしょうか。

    • えす より:

      れんさん

      こんにちは。えすです。

      一人で書いていると伝わるか不安な事もあるので
      わかりやすいと言っていただけると、本当に嬉しいです。

      右からの描画ですが、ポイントデータの配列にデータを逆から入れる。でどうでしょうか?
      ちょっとイメージがついていないので、データ内容や、軸の表示をどうしたいなどを詳しく教えていただけると、もう少しご協力できるかもしれません。

  2. れん より:

    えす様

    ご回答頂きありがとうございます。
    言葉足らずですみません。

    イメージ的にはX軸の値が日時で、Y軸の値が常に変化する値のリアルタイム描画のグラフと言えば伝わりますでしょうか。

    1秒ごとにその時点での日時とYの値を取得して、
    古いデータが右で新しいデータが左側に描画されていくような感じです。

    ご提案頂いたポイントデータの配列を逆から入れていくという方法を試させていただいたのですが、日時のXの配列の後ろから古い日時の値を格納していき描画すると、

    “X配列 must not descend:X配列[n] = 新しい日時 but X配列[n+1]=古い日時”
    といった理由で例外が発生し、古い日時の方が配列の後ろにあると
    うまくいかないようでした。

    グラフのデータはSignalPlotXYで追加しています。

    • えす より:

      れんさん

      えすです。

      詳細ありがとうございます、イメージをつかむことができました。

      設定などで簡単に実現する方法はありませんでしたが、
      ScatterPlotで以下のようにすれば、右->左にリアルタイムに描画ができました。

      ・Xの値をマイナス方向に増加(?)させる
      ・X軸のラベルに日時を文字列としてセットする

      後ほど記事にさせていただきますが、
      コードは以下です。実行画像は記事内に追記しておきます。

      ※ 環境により画面のちらつき、実行時間等でクラッシュなどはあるかもしれません。
      ※ 例外処理なしの、参考・サンプルと考えてください。


      using System;
      using System.Collections.Generic;
      using System.ComponentModel;
      using System.Data;
      using System.Drawing;
      using System.Linq;
      using System.Text;
      using System.Threading.Tasks;
      using System.Windows.Forms;

      namespace ScottPlot41_Reverse
      {
      public partial class Form1 : Form
      {
      // ScottPlotに動的にデータをセットするためのリストです。
      ScottPlot.Plottable.ScatterPlotList pointList = null;

      // 日時表示のラベルと、ラベルに対応するX軸の位置のリストです。
      List dateLabelList = new List();
      List xPositionList = new List();

      // Y軸のダミー値用の乱数です。
      Random random = new System.Random();

      // X軸に表示する日時に使います
      DateTime dt = new DateTime();

      public Form1()
      {
      InitializeComponent();

      // x軸の位置リストに0をセットします
      xPositionList.Add(0.0);

      // ScottPlotからデータ更新用のリストを取得します。
      pointList = formsPlot1.Plot.AddScatterList();

      formsPlot1.Refresh();

      // タイマーの処理を開始します
      timer1.Start();
      }
      //
      // タイマーの処理です
      //
      private void timer1_Tick(object sender, EventArgs e)
      {
      // 現在時刻を取得してラベルに追加します
      dt = DateTime.Now;
      string timeStr = dt.ToString("mm:ss");
      dateLabelList.Add(timeStr);

      //
      // x軸の位置配列と、対応するラベル配列をScottPlotにセットします。
      //
      formsPlot1.Plot.XAxis.ManualTickPositions(xPositionList.ToArray(), dateLabelList.ToArray());

      // データプロット用にX軸位置を取得します
      double xPosition = xPositionList.Last();

      // Y軸用の乱数を生成します(0~1.0)
      double yPosition = random.NextDouble();

      // データをプロットします
      pointList.Add(xPosition, yPosition);

      // ポイントデータに合わせて表示範囲を自動調整します。
      formsPlot1.Plot.AxisAuto();

      // 4.1.58(?)では、データ等の更新後にRefreshが必要なようです。
      formsPlot1.Refresh();

      // グラフを描画します
      formsPlot1.Render();

      // 次周期用のXの位置をセットします
      // マイナス1することで、右 -> 左にプロットを進めます
      xPositionList.Add(xPosition - 1 );
      }
      }
      }

COMMENT

メールアドレスが公開されることはありません。 が付いている欄は必須項目です