(2018.4.22 作成)
このサイトでは電子工作に関する内容を紹介していますが、マイコンで取得したデータをPCで処理する場面は多々あると思います。その中でもデータをリアルタイムにグラフで可視化できると何かと便利です。
こういった用途でグラフを書く方法はいくつか考えられますが、管理人の場合はC#で受信側ソフトを作ることが多いです。
C#でグラフを描こうとする場合、もともとChartコントロールというグラフ描画機能があるのでこれを使うことが最もお手軽です。しかし残念ながらこのChartコントロールはイマイチ使い勝手が悪いです。
そこでほかに良いグラフ描画コントロールがないか探してみました。選定基準は
です。この基準に照らして探してみたところいくつか見つかったので紹介してみようと思います。
まず最初に比較対象となる標準のChartコントロールでグラフを描いてみた例を示します。
左図のように、まるで少し前のエクセルで書いたようなグラフを描くことができます。
多くの場合これでも問題ないと思うのですが、いろいろと不満もあるので何とかしたいです。
ちなみに以下にこのグラフを作成したソースコードを示します。
using System; using System.Windows.Forms; namespace WindowsChart { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { // Prepare data double[] x = new double[] { 0.0, 1.0, 5.0 }; double[] y = new double[] { 0.0, 3.0, 10.0 }; System.Windows.Forms.DataVisualization.Charting.Series ser = new System.Windows.Forms.DataVisualization.Charting.Series(); ser.Name = "Data1"; ser.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line; for (int i = 0; i < x.Length; i++) ser.Points.AddXY(x[i], y[i]); chart1.Series.Clear(); chart1.Series.Add(ser); chart1.ChartAreas[0].AxisX.Title= "label x"; chart1.Titles.Add("Windows Chart"); chart1.Legends[0].DockedToChartArea = chart1.ChartAreas[0].Name; chart1.Legends[0].Docking = System.Windows.Forms.DataVisualization.Charting.Docking.Left; } } }
検索すると比較的容易に見つかるOxyPlotです。そこそこ有名らしく日本語のサイトもいくつかあります。
なかなかシンプルで使いやすく、1時間もせずに左のグラフまで作れるようになりました。
NuGetを使用してインストールできるのはVer1.0までで2016年にこの開発は終了したようですが、その後も継続しておりVer2.0のpre版まで作成されているようです。
Chart Controlと同様にソースコードを下に示します。(FormLoad部分以外は上記コードと同じなので割愛)
private void Form1_Load(object sender, EventArgs e) { OxyPlot.PlotModel model = new OxyPlot.PlotModel(); // Prepare data double[] x = new double[] { 0.0, 1.0, 5.0 }; double[] y = new double[] { 0.0, 3.0, 10.0 }; OxyPlot.Series.LineSeries ls = new OxyPlot.Series.LineSeries(); ls.Title = "Data1"; for (int i = 0; i < x.Length; i++) ls.Points.Add(new DataPoint(x[i], y[i])); model.Series.Add(ls); // xaxis OxyPlot.Axes.LinearAxis axisx = new OxyPlot.Axes.LinearAxis(); axisx.Title = "label x"; axisx.Position = OxyPlot.Axes.AxisPosition.Bottom; model.Axes.Add(axisx); // Visuarization model.Title = "Oxy Plot"; model.Background = OxyPlot.OxyColors.White; model.LegendPosition = OxyPlot.LegendPosition.TopLeft; plotView1.Model = model; }
カッコいいグラフが描けるLive Chartsです。作者の方が書かれているようにOxyPlotをカッコよくすることを目的に作ったもののようで、ずいぶん素敵です。
今回作った左のテストプログラムもプロット線が下から上がってくるようなアニメーションがかかっておりカッコいいです。
問題はカッコいいけど遅い、サンプルプログラムが読みにくいのでやりたいことになかなかたどり着かない。ぐらいでしょうか。
電子工作のデータを表示させるという男前仕様のプログラムには少し過ぎたプロットライブラリです。
同じようにFormLoad部分のコードを下に示します。
private void Form1_Load(object sender, EventArgs e) { // Prepare data double[] x = new double[] { 0.0, 1.0, 5.0 }; double[] y = new double[] { 0.0, 3.0, 10.0 }; List data = new List(); for (int i = 0; i < x.Length; i++) data.Add(new LiveCharts.Defaults.ObservablePoint(x[i], y[i])); // line data LiveCharts.Wpf.LineSeries ss = new LiveCharts.Wpf.LineSeries(); ss.Values = new LiveCharts.ChartValues(); ss.Values.AddRange(data); ss.Title = "Data1"; ss.PointGeometry = null; ss.Fill =System.Windows.Media.Brushes.Transparent; cartesianChart1.Series.Add(ss); // xaxis LiveCharts.Wpf.Axis axisx = new LiveCharts.Wpf.Axis(); axisx.Title = "label x"; cartesianChart1.AxisX.Add(axisx); // Visuarization cartesianChart1.Zoom = LiveCharts.ZoomingOptions.Xy; cartesianChart1.Pan = LiveCharts.PanningOptions.Xy; cartesianChart1.BackColor = Color.White; cartesianChart1.LegendLocation = LiveCharts.LegendLocation.Right; }
個人的には通常使用は.NetのChartコントロール。ズームなどしたい時はOxyPlotがよさそうな気がします。それ以上にカッコよく見せたい時はLive Chartsを使用し、詳細に解析を行いたい時はpythonのmatplotlibが良いように思います。