2017-11-15 11 views
4

私は、グラフのプロットを完全な十字線で置き換えようとしています(つまり、プロットの端に縦横に伸びてマウスカーソルに従う2本の垂線のセット)。私は今、この行を実行しようとすると、しかし、私は次のメッセージを取得MATLABで推奨されていない十字線ポインタ機能を実装するにはどうすればよいですか?

set(gcf,'Pointer','fullcross') 

Warning: Full crosshair pointer is no longer supported. A crosshair pointer will be used instead. 

を私は本当にたい数年前、私はこのコード行でこれを達成することができましたこの機能を実装する別の方法を見つけることができましたが、これまでには不可能でした。私は、次の関数に遭遇しました:MYGINPUT、それは私が探しているものを達成するように見えません。誰にも何か提案はありますか?

答えて

7

これは実際にはをあなたの図に追加して(他に何も使っていないと仮定して)、マウスの上に十字線が表示されます。ここで、図中のすべての軸のような機能を作成する機能があります:

function full_crosshair(hFigure) 

    % Find axes children: 
    hAxes = findall(hFigure, 'Type', 'axes'); 

    % Get all axes limits: 
    xLimits = get(hAxes, 'XLim'); 
    xLimits = vertcat(xLimits{:}); 
    yLimits = get(hAxes, 'YLim'); 
    yLimits = vertcat(yLimits{:}); 

    % Create lines (not displayed yet due to NaNs) and listeners: 
    for iAxes = 1:numel(hAxes) 
    hHoriz(iAxes) = line(xLimits(iAxes, :), nan(1, 2), 'Parent', hAxes(iAxes)); 
    hVert(iAxes) = line(nan(1, 2), yLimits(iAxes, :), 'Parent', hAxes(iAxes)); 
    listenObj(iAxes) = addlistener(hAxes(iAxes), {'XLim', 'YLim'}, ... 
            'PostSet', @(~, ~) update_limits(iAxes)); 
    end 

    % Set callback on the axes parent to the nested function below: 
    set(hFigure, 'WindowButtonMotionFcn', @show_lines); 

    function update_limits(axesIndex) 
    xLimits(axesIndex, :) = get(hAxes(axesIndex), 'XLim'); 
    yLimits(axesIndex, :) = get(hAxes(axesIndex), 'YLim'); 
    set(hHoriz(axesIndex), 'XData', xLimits(axesIndex, :)); 
    set(hVert(axesIndex), 'YData', yLimits(axesIndex, :)); 
    end 

    function show_lines(~, ~) 

    % Get current cursor positions in axes: 
    cursorPos = get(hAxes, 'CurrentPoint'); 
    cursorPos = vertcat(cursorPos{:}); 
    cursorPos = cursorPos(1:2:end, 1:2); 

    % Determine if the cursor is within an axes: 
    inAxes = (cursorPos(:, 1) >= xLimits(:, 1)) & ... 
      (cursorPos(:, 1) <= xLimits(:, 2)) & ... 
      (cursorPos(:, 2) >= yLimits(:, 1)) & ... 
      (cursorPos(:, 2) <= yLimits(:, 2)); 

    % Update lines and cursor: 
    if any(inAxes) % Cursor within an axes 
     set(hFigure, 'Pointer', 'custom', 'PointerShapeCData', nan(16)); 
     set(hHoriz(inAxes), {'YData'}, num2cell(cursorPos(inAxes, 2)*[1 1], 2)); 
     set(hVert(inAxes), {'XData'}, num2cell(cursorPos(inAxes, 1)*[1 1], 2)); 
     set(hHoriz(~inAxes), 'YData', nan(1, 2)); 
     set(hVert(~inAxes), 'XData', nan(1, 2)); 
    else % Cursor outside axes 
     set(hFigure, 'Pointer', 'arrow'); 
     set(hHoriz, 'YData', nan(1, 2)); 
     set(hVert, 'XData', nan(1, 2)); 
    end 

    end 

end 

次ない場合:

full_crosshair(gcf); 

次に、あなたがあなたの図に、各軸の上にカーソルを移動すると、カーソルが消えます2つの行が表示され、マウスの位置が追跡されます。いずれかの軸のリミットが変更された場合は、上記コードのevent listenersが検出され、それを考慮します。図に軸が追加または削除された場合は、full_crosshairに再度電話して、'WindowButtonMotionFcn'を更新する必要があります。

最後に、あなただけの'WindowButtonMotionFcn'をクリアすることで、それをオフにすることができます

set(gcf, 'WindowButtonMotionFcn', []); 
+0

まず第一に、答えるために時間を割いてくれてありがとう!私は実際にこれを実際に実装する方法についてはかなり失われています。私が試したコードの私の元の質問に行った編集を見てください(編集は数分で終わるはずです)。再度、感謝します! – Alarik

+0

ありがとうございました!私は2行を変更することで作業するコードを得ました(元の記事のEDIT 2を参照してください)。フォローアップとして、複数のサブプロットがある場合、一度に複数のサブプロットでこの作業を行うことは可能ですか?元の 'set(gcf、 'Pointer'、 'fullcross')の実装は(個々のプロットではなく)図全体で機能します。これに似た何かをする方法はありますか? – Alarik

+1

@Alarik:なぜ最初のエラーが発生したのか分かりません。 'line'関数は、最初の引数として目的の親軸を渡せるようにします。あなたは '= = line(...、...、 'Parent'、hAxes);を試して、それがうまくいくかどうかを調べることができます。上のすべての軸について上記の作業を行うのはちょっと手間がかかりますが、可能な限り更新を追加します。 – gnovice

関連する問題