ScottPlot

【ScottPlot4.1】マウスで選んだポイント座標を表示する方法

ScottPlot41-hilightのアイキャッチ画像

はじめに

ScottPlotで、マウスで選んだポイント座標を表示する方法を紹介します。

ScottPlotにはOxyPlotのように、クリックしたポイントの座標を表示する機能はついていません。しかし、そのような機能への要望は多いようで、本サイトでも質問をいただいていました。

そんな中で本家のサイトを覗いていたところ、同様の質問へのFAQとして面白い方法が掲載されていたのでご紹介します。

マウスカーソルでポイントを選ぶ方法ですが、ストレスなく確認することができ、20行程度で実装することができます。(詳細は後述するGIF動画等をご覧ください)。

環境

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

マウスカーソルでのポイント情報の表示

以下のGIF動画が、FAQに掲載されていた方法です。

カーソルの近傍のポイントに赤丸をつけて強調表示(ハイライト)し、そのポイントの座標・インデックスをForm左上のタイトルに表示しています。

選択しているポイントもハイライトのおかげで分かりやすく、かなりいい方法だと思います。
ポイントを選ぶ際も意図したポイントがきちんとハイライトされ、拡大・縮小にも対応します。

また、動作も軽いのでストレスなく使うことができます。

ポイント情報を表示しているGIF動画
  • カーソル近傍のポイントを、赤丸でハイライト
  • 座標とインデックスを、左上のタイトルに表示
  • 拡大・縮小に対応。動作も軽い。

全体コード

全体コードは以下の通りです。本家の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})";
        }
    }
}

コードのポイント

全体の流れ

コードは以下の処理に分かれます。

  1. ベースとなるグラフデータを作成・表示。
  2. ScottPlotのコントロール上にカーソルが来たら、formsPlot1_MouseMove()を呼び出す。
  3. カーソル近傍のポイント座標を取得する。
  4. 赤丸を表示して、座標の表示

赤丸用の散布図(線なし)の作成

ハイライト用の赤丸として、データが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でマウスで選んだポイントの座標を表示する方法を紹介しました。参考になればうれしいです。

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

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

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

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

COMMENT

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