C# PR

【C#】ScottPlot 4.1 グラフをリアルタイムに描画する方法 【ScatterPlotList】

記事内に商品プロモーションを含む場合があります

はじめに

ScottPlotの新しいバージョン「4.1」を使って、線付の散布図(ScatterPlot)をリアルタイムに描画する方法を紹介します。

ScottPlotはあくまで「大量の固定長のデータ」を高速に描画・操作することを念頭においたライブラリです。リアルタイムでのグラフ描画は現状、「おまけ機能」的な扱いなので、「ScottPlotを使ってちょっと動的なグラフ描画を試してみたい」という方に向けて解説します。

なお、以前ご紹介した4.0系の方法は描画が止まるなどの現象が発生するようです。リアルタイムでの描画を試して見たい方はこちら4.1系の方法を推奨します。

ScottPlotはあくまで「大量の固定長のデータ」を高速に描画・操作することを念頭に開発されています。今回の紹介する方法でリアルタイム描画も可能ですが、現状「おまけ」程度の機能ですので予めご了承ください。

Ver.4.0系のこの記事の方法は、描画を続けていくと描画自体が止まるなどの現象がでるようです。今回のVer.4.1の方法では少なくとも100ポイント程度の描画が止まることは無いのでVer.4.1の方法を推奨します。

参考にした公式のFAQ

今回の記事は公式ページの以下の内容を元に作成しています。

公式FAQ:User Control: Live Data
https://swharden.com/scottplot/faq/live-data/#growing-data-with-scatterplotlist

環境

環境バージョンなど備考
VisualStudio   2019 Community 2017でも使用できます
.NET4.7.2
プロジェクトFormアプリケーション(.NET Framework) 
ScottPlot4.1.16

実行結果

後述する、「のこぎり状の波形をタイマーで動的に表示するコード」の実行結果は以下の通りです。

全体コード

のこぎり状の波形をタイマーで動的に表示するコードです。

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 FormScottPlot41_RealTime
{

    // 以下のコントロールがFormに追加されていることを前提にしています
    // ScottPlotのコントロール(FormsPlot1)
    // タイマーのコントロール (timer1)

    public partial class Form1 : Form
    {
        // 動的にポイントを追加できるScatterPointListを作成します。
        ScottPlot.Plottable.ScatterPlotList pointList = new ScottPlot.Plottable.ScatterPlotList();

        // 波形の生成に使うカウンタです
        int  counter = 0;
        double point = 0.0;

        public Form1()
        {
            InitializeComponent();

            // ScottPlotのコントロールに、ScatterPointListを追加します。
            formsPlot1.Plot.Add(pointList);

            // タイマーの処理を開始します
            timer1.Start();
        }

        //
        // タイマーの処理です
        // インターバルは100msに設定しています
        //
        private void timer1_Tick(object sender, EventArgs e)
        {

            // 3周期ごとにY軸を初期化して、のこぎり型の波形を生成します。
            if ( counter % 3 == 0) { point = 0.0; }

            // pointListにデータを追加します。
            // 既にコントロールにも追加しているので、ここで追加したデータも
            // Render()の際に合わせて表示されます
            pointList.Add( counter, point);

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

            // コントロールを描画します
            // pointList
            formsPlot1.Render();

            // カウンタの更新です。
            point++;
            counter++;

            // 一定数でグラフを初期化します。
            if( counter > 100 )
            {
                pointList.Clear();
                counter = 0;
                point = 0;
            }
        }
    }
}

コードのポイント

ScatterPlotList

通常のScatterPlotではなく、動的にポイント情報が追加可能な「ScatterPlotList」を作成し、手動でScottPlotのコントロールに追加します。

        // 動的にポイントを追加できるScatterPointListを作成します。
        ScottPlot.Plottable.ScatterPlotList pointList = new ScottPlot.Plottable.ScatterPlotList();

       // ScottPlotのコントロールに、ScatterPointListを追加します。
        formsPlot1.Plot.Add(pointList);

ScatterPlotListへのデータ追加

ScatterPlotListのAdd関数を使って、ポイント情報を追加しています。
前述したコードでScottPlotのコントロールと、ScatterPlotListはリンクしている状態になるので、Add関数でポイント情報を追加して、Render()を呼び出すだけで、動的なグラフを描画することが出来ます。

            // pointListにデータを追加します。
            // 既にコントロールにも追加しているので、ここで追加したデータも
            // Render()の際に合わせて表示されます
            pointList.Add( counter, point);

まとめ

ScottPlotの新しいバージョン「4.1」を使って、線付の散布図(ScatterPlot)をリアルタイムに描画する方法を紹介しました。おまけ程度の機能ですが、「ScottPlotでリアルタイムにグラフを描画したい!」という方の参考になればうれしいです。

お知らせ

今月号の『Software Design』はドメイン駆動設計(DDD)。実例を交えたDDDの手法の解説が特集されています。

編集:Software Design 編集部
¥1,562 (2024/03/13 12:59時点 | Amazon調べ)

質問・要望 大歓迎です

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

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

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

POSTED COMMENT

  1. より:

    リアルタイムで描画する際に凡例を表示するにはどうしたらいいのでしょうか

    • えす より:

      暁さん、こんにちは。

      コメントの承認が遅れてすみません。
      ちょっと調べてみるので、もう少々お待ちください。

      • えす より:

        暁さん、こんにちは

        えすです。

        凡例の件ですが、
        formsPlot1.Plot.Legend()や、引数の設定など、いろいろと試してみましたが、
        凡例は有効化されないようです。

        試行錯誤してみましたが、有効化の方法までたどり着けませんでした。
        お力になれず申し訳ないです。

  2. りゅーいち より:

    凡例の件について、今更ながら(4.1.58ですが)

    pointList.Label = “なにか”;
    などととしてラベルを付けた後に
    formsPlot1.Plot.Legend();
    とするとちゃんと描画されながら凡例が表示されました。

    私は
    var legend = formsPlot1.Plot.Legend();
    legend.FontSize = 24;
    legend.FontBold = true;
    みたいな感じで若干カスタマイズしてます。

    あと4.1.58だと
    ScottPlot.Plottable.ScatterPlotList pointList = new ScottPlot.Plottable.ScatterPlotList();
    ではエラーが出ましたが、ScottPlot.Plottable.ScatterPlotListDraggable pointList = new ScottPlot.Plottable.ScatterPlotListDraggable();
    ではエラーが出ず、正常に生成されました。

    • えす より:

      りゅーいちさん

      えすです。コメントありがとうございます。

      リアルタイムの凡例は、動的なリストにラベルを付けなんですね。
      あとで私も試して記事化検討してみます。

      情報ありがとうございます!

えす へ返信する コメントをキャンセル

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