ScottPlot

【C#】ScottPlot 新バージョンがリリース 【4.1】

はじめに

無料で使える高速なグラフライブラリ「ScottPlot」のメジャーアップデートがありました。
しばらくβ版として開発が続いていましたが、ようやく正式版となったようです。

4.0 から 4.1 と2桁目のバージョンアップですが、機能が大幅に追加されたのでご紹介したいと思います。

この記事の内容
  • バージョンアップ内容
  • 個人的に注目の3つの新機能
  • ① 高速描画可能な「SignalPlot」の追加
  • ② X・Y軸に第2軸 (複合グラフ)を追加する機能
  • ③ 直角で表示される「StepPlot」の追加

バージョンアップ内容

主な新機能は以下の通りです。(機械翻訳+意訳)
リリース直後だからなのか、本家サイトにリンクエラーなどがあり全ては調べられていません。
⑤⑥のレンダリングやイベント処理などは、前バージョンにはない機能なので今後調べていきたいと思います。

主な新機能
  1. 複数のX軸とY軸のサポート
  2. 軸・目盛り・グリッドの豊富で新しいカスタマイズオプション
  3. パフォーマンスとスレッドセーフを向上させるステートレスレンダリング
  4. ユーザー制御用の簡略化された共通構成モジュール
  5. UIスレッドをブロックしないレンダリングリクエストのサポート
  6. ユーザーコントロールのカスタマイズを可能にするための改善されたイベント処理

本家サイトからの引用です。

新バージョンの詳細は以下の本家サイトをご覧ください。

https://swharden.com/scottplot/cookbook/

個人的に注目の新機能

個人的にいいなと思う機能は以下の3つです。

  1. 高速描画可能な「SignalPlot」の新規追加
  2. X・Y軸に第2軸 (複合グラフ)を追加する機能
  3. 直角で表示される「StepPlot」の新規追加

① 高速描画可能な「SignalPlot」

4.0までの散布図でも十分に高速でしたが、さらに何百万点ものデータポイントをインタラクティブに表示可能「SignalPlot」が新たに追加されました。等間隔でのデータを想定しているため、Y軸は固定になっています。

以前記事を書いたリアルタイムでのグラフ描画も、さらに高速に動かせるかもしれません。
深堀して記事かしていきたいと思います。

本家CockBookから引用しています。

旧Ver.のリアルタイム記事は以下を参照ください。

② X・Y軸の第2軸 (複合グラフ)を追加する機能

以前β版の機能として紹介していた、X・Y軸に第2軸を追加する機能が正式リリースされました。

一見地味ですが、「エクセルでいつも見ている、複数データのグラフが作りたい」という時に活躍してくれる機能なので、個人的に非常にありがたいです。

β版の時に紹介した、第2軸を表示する機能の記事は以下をご覧ください。

③ 直角で表示される「StepPlot」の新規追加

個人的に、複数のI/O信号をタイミングチャートのように表示できないか?と思っていたところの新機能でした。うまく使えた場合は記事かしてご紹介したいと思います。

本家CockBookから引用しています

まとめ

無料で使える高速なグラフライブラリ「ScottPlot」のメジャーアップデートについてご紹介しました。
調べきれていない機能・コードの書き方などは、今後掘り下げて別途記事にしていきます。

応援・要望お待ちしてます

ブログを見ていて「この辺を詳しく知りたい」「このライブラリの使い方を知りたい」「こんなことで困ってる」...etc があれば、コメント・問い合わせ・Twitterで教えてください。質問・ご要望に合わせて解説記事を作ります。

ブログを気に入っていただけたり、「応援してもいいよ」という方がいたら、ブログやSNSでの紹介をお願いします。 あたたかい応援は、中の人の更新の大きな励みになります。

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

POSTED COMMENT

  1. yana より:

    [ScottPlot]を使ってテキストファイルデータからDataSetにセットしグラフ表示しようとしていますが
    y軸は数値なのでList lst6 = dt0.AsEnumerable().Select(row => (double)row[6]).ToList();で変換出来ました。
    問題はX軸でDatasetにはds0.Tables[0].Rows[i][0].ToString()←ここに年月日”2021/06/15”
    ds0.Tables[0].Rows[i][1].ToString()←ここに時間(時分)”15:47”
    double指定出来ず
    List lst0 = dt0.AsEnumerable().Select(row => row[0].ToString()).ToList();
    List lst1 = dt0.AsEnumerable().Select(row => row[1].ToString()).ToList();
    で、しかも年月日と時間を連結してX軸に表示させたいです。
    また、対数スケールでしかも複数値(グラフ1、グラフ2、
    フラフ3、…)

    • えす より:

      yanaさん
      質問ありがとうございます。記事化を進めていますが、さっと調べてみましたのでお答えします。
       ・CSVから読み取った文字列型の年月日と時間を結合(「日時の文字列」とします)
       ・「日時の文字列」を、C#のDateTime型に変換
       ・DateTimeのToOADate()でDateTime型 -> Double型に変換
       ・変換したDouble型をScottPlotのX軸のデータ配列にセット。
       ・ScottPlot.Plot.XAxis.DateTimeFormat(true); でX軸を日付として設定

      とすることで、X軸に日時の文字列が表示できるようです(Ver.4.1.16で確認)
      ※ デフォルトだと、X軸の日付の期間が広いと時間が省略されてしまうようです。
      ※ 本家サイトCookBook 「Plotting DateTime Data」も参考にしてみてください。

      • えす より:

        yanaさんへの続き
        また、対数スケールで・・(グラフ1、グラフ2、フラフ3、…)以降は文字数制限(?) で見えないようです。
        お手数ですが、再度投稿いただけると助かります。

  2. yana より:

    先のX軸「日時の型」変換の回答有難う御座いました。トライしてみます。対数スケール表示での後半の質問です。
    double[] dataYsLog = ScottPlot.Tools.Log10(dataYs);
    plt.AddScatter(dataXs, dataYsLog, lineWidth: 0);
    ここで複数グラフ線(グラフ1,グラフ2,グラフ3,…)と増えた場合のコード記述はどうなりますか?

  3. yana より:

    先程の複数グラフ表示質問は解決しました。
    formsPlot1.plt.PlotScatter(x, Y1);
    formsPlot1.plt.PlotScatter(x, Y2);と増やせば表示されました。有難うございました。
    ただ、以下のようにDouble変換過程でdoubel → double[]を1行でシンプルに記述出来ないかとも思いました。

    List lst0 = new List();
    for (int i = 0; i < ds0.Tables[0].Rows.Count; i++)//ToOADate → ToDouble
    {
    string strTime1 = ds0.Tables[0].Rows[i][0] + " " + ds0.Tables[0].Rows[i][1];
    DateTime dTime1 = DateTime.Parse(strTime1);
    var oadate1 = dTime1.ToOADate();
    lst0.Add(Convert.ToDouble(oadate1));
    }
    List lst6 = dt0.AsEnumerable().Select(row => (double)row[6]).ToList();
    List lst7 = dt0.AsEnumerable().Select(row => (double)row[7]).ToList();
    List lst8 = dt0.AsEnumerable().Select(row => (double)row[8]).ToList();
    List lst9 = dt0.AsEnumerable().Select(row => (double)row[9]).ToList();

    double[] myDataY0 = lst0.Select(x => (double)x).ToArray();
    double[] myDataY6 = lst6.Select(x => (double)x).ToArray();
    double[] myDataY7 = lst7.Select(x => (double)x).ToArray();
    double[] myDataY8 = lst8.Select(x => (double)x).ToArray();
    double[] myDataY9 = lst9.Select(x => (double)x).ToArray();

    formsPlot1.plt.PlotScatter(myDataY0, myDataY6);
    formsPlot1.plt.PlotScatter(myDataY0, myDataY7);
    formsPlot1.plt.PlotScatter(myDataY0, myDataY8);
    formsPlot1.plt.PlotScatter(myDataY0, myDataY9);
    formsPlot1.plt.XAxis.DateTimeFormat(true);

  4. yana より:

    logスケールでのy軸のスタート値を0からスタートではなく
    1 10 100 1000 10000
    と表示したいがスケール変更は可能でしょうか?

  5. yana より:

    1)Y軸のLogスケールはScottPlot.Tools.Log10()にて出来ましたがlog10yのY値目盛表示を0 10 100 1000と表現可能でしょうか?
    2)X軸をformsPlot1.plt.XAxis.DateTimeFormat(true);日付時間型とすると
    X軸値={①7月1日,②7月7日,③7月19日,④8月4日}でのX軸表示は7月1日、7月2日、7月3日 …8月4日と表示されるが
    目的のx軸は①、②、③,④と表示されるようにしたい
    3)Y軸データで0データをオミット(線形を途切れるようにしたい)は可能ですか?
    double[] originalYs = { 3, double.NaN, 5, double.PositiveInfinity, double.NegativeInfinity, 4, 6 };
    double[] originalXs = { 1, 2, 3, 4, 5, 6, 7 };
    ではうまく行きません。
    以下のように個別化すれば可能ですが1万件のデータとなった場合、分別化は難しいです

    // first segment
    double[] xs1 = { 1, 2, 3 };
    double[] ys1 = { 5, 4, 8 };
    plt.AddScatter(xs1, ys1, Color.Blue);

    // second segment
    double[] xs2 = { 5, 6, 7, 8 };
    double[] ys2 = { 6, 9, 4, 7 };
    plt.AddScatter(xs2, ys2, Color.Blue);

    // third segment
    double[] xs3 = { 10, 11, 12 };
    double[] ys3 = { 8, 3, 7 };
    plt.AddScatter(xs3, ys3, Color.Blue);

    • えす より:

      yanaさん

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

      1) 値目盛表示を0 10 100 1000と表現

      Logスケールではなく、そのまま 10 100 1000 “だけ” を表示して、中間の値は表示させたくないということかと思います。
      動作確認までは見れていないのですが、 2) の質問と同様に Y軸のTickのManual指定でどうでしょうか?

      https://swharden.com/scottplot/cookbooks/4.1.16/category/advanced-axis-features/#manual-tick-labels

      3)Y軸データで0データをオミット(線形を途切れるようにしたい)は可能ですか?

      ScatterPlotでは線を途切れるようにする機能はないようですね。透明化での回避なども試してみましたが、
      系列(線)全体での指定しかないため、特定の点のみを無効化する(途切れさせる)のは難しいようです。
      Githubで要望をあげてみるのも良いかもしれません。

  6. yana より:

    2)X軸 日付時間型は以下にうまく行きました。すみませんでした。
    formsPlot1.plt.XAxis.ManualTickPositions

COMMENT

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