はじめに
ScottPlotで、マウスで選んだポイント座標を表示する方法を紹介します。
ScottPlotにはOxyPlotのように、クリックしたポイントの座標を表示する機能はついていません。しかし、そのような機能への要望は多いようで、本サイトでも質問をいただいていました。
そんな中で本家のサイトを覗いていたところ、同様の質問へのFAQとして面白い方法が掲載されていたのでご紹介します。
マウスカーソルでポイントを選ぶ方法ですが、ストレスなく確認することができ、20行程度で実装することができます。(詳細は後述するGIF動画等をご覧ください)。
環境
環境 | バージョンなど | 備考 |
VisualStudio | 2019 Community | 2017でも使用できます |
.NET | 4.7.2 | |
プロジェクト | Formアプリケーション(.NET Framework) | |
ScottPlot | 4.1.16 |
マウスカーソルでのポイント情報の表示
以下のGIF動画が、FAQに掲載されていた方法です。
カーソルの近傍のポイントに赤丸をつけて強調表示(ハイライト)し、そのポイントの座標・インデックスをForm左上のタイトルに表示しています。
選択しているポイントもハイライトのおかげで分かりやすく、かなりいい方法だと思います。
ポイントを選ぶ際も意図したポイントがきちんとハイライトされ、拡大・縮小にも対応します。
また、動作も軽いのでストレスなく使うことができます。
- カーソル近傍のポイントを、赤丸でハイライト
- 座標とインデックスを、左上のタイトルに表示
- 拡大・縮小に対応。動作も軽い。
全体コード
全体コードは以下の通りです。本家のFAQは線なしの散布図がベースですが、線付きの散布図に変更しています。
コントロールとイベント設定
実装と合わせて以下の設定を行ってください
- ScottPlotのグラフコントロール「formsPLot1」を貼り付け
- formsPlot1のイベントに関数「formsPlot1_MouseMove()」を設定
全体コード
全体コードは以下の通りです。
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_ToolTips
{
public partial class Form1 : Form
{
private readonly ScottPlot.Plottable.ScatterPlot MyScatterPlot;
private readonly ScottPlot.Plottable.ScatterPlot HighlightedPoint;
private int LastHighlightedIndex = -1;
public Form1()
{
InitializeComponent();
// サンプル用のデータです。
double[] pointX = { 1.0, 2.0, 3.0, 4.0, 5.0 };
double[] pointY = { 1.0, 2.0, 3.0, 4.0, 5.0 };
// 線付きの散布図(折れ線グラフ)としてデータをセットします。
// 併せてポイントデータへの参照も取得しておきます。
MyScatterPlot = formsPlot1.Plot.AddScatter(pointX, pointY);
// ポイントを強調表させるための、線なしの散布図を準備しておきます
HighlightedPoint = formsPlot1.Plot.AddPoint(0, 0);
HighlightedPoint.Color = Color.Red;
HighlightedPoint.MarkerSize = 10;
HighlightedPoint.MarkerShape = ScottPlot.MarkerShape.openCircle;
HighlightedPoint.IsVisible = false;
}
//
// マウスカーソルがScottPlotのコントロールの上にきた際に呼び出される関数です
//
private void formsPlot1_MouseMove(object sender, MouseEventArgs e)
{
// マウスカーソル近傍のポイント座標を取得します。
// マウスの座標を取得します
(double mouseCoordX, double mouseCoordY) = formsPlot1.GetMouseCoordinates();
// グラフのX軸/Y軸の単位から比率を計算します
double xyRatio = formsPlot1.Plot.XAxis.Dims.PxPerUnit / formsPlot1.Plot.YAxis.Dims.PxPerUnit;
// マウスの座標・グラフの縦横比から、カーソル近傍のポイント座標を取得します
(double pointX, double pointY, int pointIndex) = MyScatterPlot.GetPointNearest(mouseCoordX, mouseCoordY, xyRatio);
// 強調表示用の散布図のポイントを、上で取得したポイントの座標にセットします。
// これにより、カーソル近傍のポイントに赤丸がついたように見せることができます
HighlightedPoint.Xs[0] = pointX;
HighlightedPoint.Ys[0] = pointY;
HighlightedPoint.IsVisible = true;
// カーソル近傍のポイントが変わった場合のみ、描画を行います
if (LastHighlightedIndex != pointIndex)
{
LastHighlightedIndex = pointIndex;
formsPlot1.Render();
}
// 画面上部のタイトルの部分に赤丸がついたポイント座標を表示します
Text = $"Point index {pointIndex} at ({pointX:N2}, {pointY:N2})";
}
}
}
コードのポイント
全体の流れ
コードは以下の処理に分かれます。
- ベースとなるグラフデータを作成・表示。
- ScottPlotのコントロール上にカーソルが来たら、formsPlot1_MouseMove()を呼び出す。
- カーソル近傍のポイント座標を取得する。
- 赤丸を表示して、座標の表示
赤丸用の散布図(線なし)の作成
ハイライト用の赤丸として、データが1つしかない「線なしの散布図」(ScatterPoint)を作成します。
その他赤丸の大きさや形状などを設定しています。
// ポイントを強調表させるための、線なしの散布図を準備しておきます
HighlightedPoint = formsPlot1.Plot.AddPoint(0, 0);
HighlightedPoint.Color = Color.Red;
HighlightedPoint.MarkerSize = 10;
HighlightedPoint.MarkerShape = ScottPlot.MarkerShape.openCircle;
HighlightedPoint.IsVisible = false;
マウス座標の取得と近傍点の検索
ScottPlotのグラフコントロール(formsPlot1)から「マウスの座標」「X軸とY軸の比率」を計算します。
上記2つの情報を、近傍点を探すGetPointNearrest() に渡すことで、マウスカーソルに近いポイントの座標・ポイント番号が取得できます。
また、取得したポイントを「線なしの散布図」座標にセットすることで、マウスカーソルの近傍のポイントに赤丸が表示されるようになります。
// マウスの座標を取得します
(double mouseCoordX, double mouseCoordY) = formsPlot1.GetMouseCoordinates();
// グラフのX軸/Y軸の単位から比率を計算します
double xyRatio = formsPlot1.Plot.XAxis.Dims.PxPerUnit / formsPlot1.Plot.YAxis.Dims.PxPerUnit;
// マウスの座標・グラフの縦横比から、カーソル近傍のポイント座標を取得します
(double pointX, double pointY, int pointIndex) = MyScatterPlot.GetPointNearest(mouseCoordX, mouseCoordY, xyRatio);
// 強調表示用の散布図のポイントを、上で取得したポイントの座標にセットします。
// これにより、カーソル近傍のポイントに赤丸がついたように見せることができます
HighlightedPoint.Xs[0] = pointX;
HighlightedPoint.Ys[0] = pointY;
HighlightedPoint.IsVisible = true;
まとめ
ScottPlotでマウスで選んだポイントの座標を表示する方法を紹介しました。参考になればうれしいです。
お知らせ
今月号のSoftware Designは「もっとTypeScriptの力を引き出そう」
JavaScriptの拡張言語でしょ?と思っているかたへ、Union型などTypeScriptの持つ秘めたる力を解説する特集となっています。
個人的には第2特集の「Ubuntuの現代的な使い方」がの方が気になりました。より詳しい内容は以下のリンクからご覧ください。
質問・要望 大歓迎です
「こんな解説記事作って」「こんなことがしたいけど、〇〇で困ってる」など、コメント欄で教えてください。 質問・要望に、中の人ができる限り対応します。
使えたよ・設定できたよの一言コメントも大歓迎。気軽に足跡を残してみてください。記事を紹介したい方はブログ、SNSにバシバシ貼ってもらってOKです。