C#でのグラフ描画 ScottPlot
C#でのグラフ描画を検討したときのメモです。
よく名前があがるのは下記4つ。(多分)
- Chart (Windowsのやつ)
- ScottPlot
- OxyPlot
- LiveChart
今回ScotPlotを利用したのですが、そのときのメモです。
利用した理由は下記2点。
- 高速描画 (リアルタイムでの信号表示が求められたため)
- グラフ領域の拡大・縮小・移動がデフォルトで実装込み
なお、私が使用したのは、C#でWPFです。
ScottPlotのSignal Plotについて
信号表示に使用するのに使うべきなのは、そのまんまの名前のSignal Plot
でした。
使い方自体は本家を見てもらうと記載されているのですが、いくつかつまったポイントだけ紹介します。
問題1 データを更新するとグラフも更新(前のデータと重畳表示できず)
どういうことかというと、
GraphScotPlot.Plot.AddSignalXY(xdata, ydata);
(ydataを更新の処理なんか書く)
GraphScotPlot.Plot.AddSignalXY(xdata, ydata); // 更新したydataも追加したつもり
GraphScotPlot.Render();
グラフ表示は、最新のydataのみが表示されます。リフレッシュしなければ前回のが残っているものだと思ってたのが浅はかでした。普通に考えると、ありがたい機能なんですけどね。Signal Plotの名に適した挙動ですよね。改めて描画を呼ばなくとも勝手に最新の信号に更新してくれるんですから。でも、私には前回分の表示を残しておきたい要望がありました。
というわけで、データ保持用の配列を作成
List<double[]> ydata = new List<double[]>() {new double[maxSize], new double[maxSize] }
これで、あとは素直に
GraphScotPlot.Plot.AddSignalXY(xdata, ydata[0]);
GraphScotPlot.Plot.AddSignalXY(xdata, ydata[1]);
GraphScotPlot.Render();
でひと手間必要ですが、重ねて表示もできました。
問題2 データ更新のタイミングで最適な位置の描画に変更される
せっかくズームを調整したのに、データ更新に合わせて勝手に自動調整される、という事態に。設定はユーザにまかせてほしい。
というわけで、固定するための実装です。ちなみに、GraphScotPlot
は配置したScotPlotの名前です。
// 描画前の設定を取得
var axisLimits = GraphScotPlot.Plot.GetAxisLimits();
(描画用データ準備)
・
・
GraphScotPlot.Plot.AddSignalXY(xdata, ydata);
GraphScotPlot.Plot.SetAxisLimits(axisLimits);
GraphScotPlot.Render();
現在表示されている軸の情報の取得と設定がGetAxisLimits()
とSetAxisLimits()
でできます。きっと関数あるだろうと思ったのですが、見つけるのに時間がかかりました。
これで無事にズームを変えられなくなりました。よかった。
下記は、本日紹介したScotPlotのサイトです。
Discussion