Show mouse position in another subplot
조회 수: 37 (최근 30일)
이전 댓글 표시
I have a plot with two subplots, one frontal xray and one sagital xray, both with the same height, taken at the some moment. Hence y position in subplot 1 equals y position subplot 2.
I have to mark some points in subplot 1, but while moving my mouse in subplot 1, i want to show a (also moving) horizontal line in sublot 2, indicating the y value of the current mouse position from subplot 1. How can i make this?
댓글 수: 0
채택된 답변
Ameer Hamza
2020년 10월 2일
You can use WindowButtonMotionFcn callback if figure. Run the following example
f = figure();
ax_up = subplot(2, 1, 1);
hold(ax_up);
ax_up.YLim = [0 2];
ax_down = subplot(2, 1, 2);
hold(ax_down);
ax_down.YLim = [0 2];
l = yline(0, 'r');
f.WindowButtonMotionFcn = @(fig, eve) btnCb(fig, eve, ax_up, l);
function btnCb(~, ~, ax_up, l_h)
y = ax_up.CurrentPoint(1, 2);
if (ax_up.YLim(1) < y) && (y < ax_up.YLim(2))
l_h.Value = y;
end
end
댓글 수: 6
Ameer Hamza
2020년 10월 5일
Following shows the line on both axes
f = figure();
ax_up = subplot(2, 1, 1);
hold(ax_up);
ax_up.YLim = [0 2];
l1 = plot([0 1], [0 0], 'r');
ax_down = subplot(2, 1, 2);
hold(ax_down);
ax_down.YLim = [0 2];
l2 = plot([0 1], [0 0], 'r');
f.WindowButtonMotionFcn = @(fig, eve) btnCb(fig, eve, ax_up, l1, l2);
function btnCb(~, ~, ax_up, l1, l2)
y = ax_up.CurrentPoint(1, 2);
if (ax_up.YLim(1) < y) && (y < ax_up.YLim(2))
l1.YData = [y y];
l2.YData = [y y];
end
end
추가 답변 (2개)
Adam Danz
2020년 10월 2일
편집: Adam Danz
2020년 10월 2일
Here's a full demo that tracks mouse movement in axis #1 and replicates it in axis #2. The windowbuttondownfcn function updates the position of xline and yline objects in both axes.
You can easily remove one of the reference lines or the line labels if they are not desired.
A right and left mouse click on axis #1 will turn the tracking off/on.
Key components:
- linkaxes(ax,'xy') - ensures the axis limits remain the same between axes (use 'y' to link y-axis only).
- hlink = linkprop() - used to yoke the x and y lines between the axes so when the position of those lines changes in axis #1, the lines in ax #2 follows. The hlink objects must be stored in axis #1 as the inline comments indicate.
% Create two axes
clf()
ax(1) = subplot(1,2,1);
title('Track mouse movement')
grid on
ax(2) = subplot(1,2,2);
title('Follow mouse movement')
grid on
linkaxes(ax,'xy') % Equate axis limits
% Set up crosshairs on each axis at the edges
gobj(1,1) = xline(ax(1),min(xlim(ax(1))), 'k-');
gobj(1,2) = yline(ax(1),min(ylim(ax(1))), 'k-');
gobj(2,1) = xline(ax(2),min(xlim(ax(2))), 'k-');
gobj(2,2) = yline(ax(2),min(ylim(ax(2))), 'k-');
hlink(1) = linkprop(gobj(:,1),{'Value','Label'}); % Yoke x lines
hlink(2) = linkprop(gobj(:,2),{'Value','Label'}); % Yoke y lines
ax(1).UserData = hlink; % hlink must be stored here so mouseMove() has access to it
% Assign windowbuttonmotion fcn on axis #1
set(ax(1).Parent,'windowbuttonmotionfcn', {@mouseMove, ax, gobj});
% Assign mouse button functions to start/stop tracking
WindowButtonMotionFcnInput = {@mouseMove, ax, gobj};
set(ax(1).Parent,'windowbuttondownfcn', {@startStopMouseMove, WindowButtonMotionFcnInput})
function mouseMove(~, ~, ax, gobj)
% Responds to mouse movement in axis #1
% ax is a vector of subplot handles; ax(1) tracks mouse movement, ax(2) follows.
% gobj(1,1) is xline in ax 1
% gobj(1,2) is yline in ax 1
% Get mouse coordinate
C = ax(1).CurrentPoint;
x = C(1,1);
y = C(1,2);
% If mouse isn't on axis #1, do nothing.
if x < ax(1).XLim(1) || x > ax(1).XLim(2) || y < ax(1).YLim(1) || y > ax(1).YLim(2)
return
end
% Update crosshairs (cross hairs in ax 2 are yoked).
gobj(1,1).Value = x;
gobj(1,1).Label = x;
gobj(1,2).Value = y;
gobj(1,2).Label = y;
end
function startStopMouseMove(hobj,~,WindowButtonMotionFcnInput)
% Turns mouse tracking off (right mouse button) and on (left mouse button)
buttonID = hobj.SelectionType;
switch buttonID
case 'normal' %left mouse button
% Start interactivity
set(hobj,'windowbuttonmotionfcn', WindowButtonMotionFcnInput);
case 'alt' % right mouse button
% Stop interactivity
set(hobj,'windowbuttonmotionfcn', []);
end
end
댓글 수: 0
Mario Malic
2020년 10월 2일
편집: Mario Malic
2020년 10월 2일
Here's something to get you started, this code does the following:
These two callbacks obtains the X and Y coordinates, twice - When the mouse button is pressed, and when the mouse button is released. You can create a helper function and call it within the callback to update the current values of X and Y.
properties (Access = public)
X_Start = [];
Y_Start = [];
X_End = [];
Y_End = [];
end
% Callback function: UIFigure, UIFigure
function UIFigureWindowButtonDown(app, event)
ax = app.UIFigure.CurrentAxes; % Gets the data from clicked axes
Start_Points = ax.CurrentPoint;
app.X_Start = Start_Points(1,1);
app.Y_Start = Start_Points(1,2);
HelperFun(app)
end
% Window button up function: UIFigure
function UIFigureWindowButtonUp(app, event)
ax = app.UIFigure.CurrentAxes; % Gets the data from clicked axes
End_Points = ax.CurrentPoint;
app.X_End = End_Points(1,1);
app.Y_End = End_Points(1,2);
% command to plot on right
end
function HelperFun(app)
% Check if key is pressed
while(Key_Pressed)
% get x and y values
% update the plot however you want to
end
end
Edit: WindowButtonMotionFcn callback seems like the way to go
댓글 수: 0
참고 항목
카테고리
Help Center 및 File Exchange에서 Subplots에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!