Live line plotting over a surface/mesh/imagesc plot.

12 次查看(过去 30 天)
Hello,
I have a matrix (size 1000x1000) of height values, that I can view with mesh command. From the same figure (that mesh is displayed) I use ginput to the get the coordinates of the mouse and based on the coordinates I can plot the horizontal and vertical line profiles:
[x y] = ginput(1);
figure(2)
subplot(2, 1, 1)
set(gcf, 'Units', 'Inches', 'Position', [5, 5, 10, 3], 'PaperUnits', 'Inches', 'PaperSize', [16, 9.0])
plot(Zp(:, round(x(1))), 'b-'); title('Vertical'); grid on
subplot(2, 1, 2);
plot(Zp(round(y(1)), :), 'k-'); title('Horizontal');
Now, what I really need is a live line profile plotting, so as I drag the mouse over the mesh figure I can see the two line profiles.
It is like continuously updating the values of x(1) and y(1) and updating figure(2).
Is it even possible? And if so, could anyone guide me with how to do it?
Thanks.
  11 个评论
Feri
Feri 2020-3-11
编辑:Feri 2020-3-11
I got it, was finally able to pass the correct values to the axes, great.
Thanks a million Adam.
How do I make this as the Accepted Answer?
Adam Danz
Adam Danz 2020-3-11
编辑:Adam Danz 2020-3-11
Using imagesc makes much more sense. See the demo below.
Note that this solution merely updates values of the line objects rather than replotting lines. This is much faster and more efficient than replotting lines.

请先登录,再进行评论。

采纳的回答

Adam Danz
Adam Danz 2020-3-11
编辑:Adam Danz 2020-3-12
Here's a functional demo that uses the WindowButtonMotionFcn property of a figure to capture the mouse position which is used to detect the closest (x,y) coordinates to the mouse within the axes. It continually updates a set of crosshairs that display the coordinates and updates two subplots showing the values along the selected row and column.
See inline comments for details.
Create the data and set up the plot
% Create data
data = peaks(1000);
% Plot data in main axis
ax(1) = subplot(4,1,[1,2]);
imagesc(ax(1), data)
ax(1).YDir = 'Normal';
axis(ax(1),'equal')
axis(ax(1),'tight') %required!
ax(1).Parent.WindowState = 'Maximized'; % maximize figure
ax(1).Toolbar.Visible = 'off'; % otherwise, toolbar may hide axis title
xlabel(ax(1), 'x axis lable')
ylabel(ax(1), 'y axis lable')
title(ax(1), 'Data')
% Set up cross hairs at axis edges
gobj(1) = xline(min(xlim(ax(1))), 'k-');
gobj(2) = yline(min(ylim(ax(1))), 'k-');
% Set up subplot 2; do all formatting here
ax(2) = subplot(4,1,3);
gobj(3) = plot(ax(2), 1:size(data,2), nan(1,size(data,2)), '-ko', 'MarkerSize', 4);
xlabel(ax(2), 'x index')
ylabel(ax(2), 'x value')
axis(ax(2), 'tight')
% Set up subplot 3; do all formatting here
ax(3) = subplot(4,1,4);
gobj(4) = plot(ax(3), 1:size(data,1), nan(1,size(data,1)), '-ko', 'MarkerSize', 4);
xlabel(ax(3), 'y index')
ylabel(ax(3), 'y value')
axis(ax(3), 'tight')
% After values are set above, assign windowbuttonmotion fcn
set(ax(1).Parent,'windowbuttonmotionfcn', {@mouseMove, data, ax, gobj});
Define the WindowButtonMotionFcn
function mouseMove(~, ~, data, ax, gobj)
% gobj(1) is xline
% gobj(2) is yline
% gobj(3) is subplot 2 line
% gobj(4) is subplot 3 line
% ax is a vector of subplot handles from top to bottom
% data is the imagesc data
% Get mouse coordinate, round to nearest integer.
C = ax(1).CurrentPoint;
x = round(C(1,1));
y = round(C(1,2));
% If mouse isn't on axis, 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
gobj(1).Value = x;
gobj(1).Label = x;
gobj(2).Value = y;
gobj(2).Label = y;
% Update main title
% title(ax(1), sprintf('(x,y) = (%d, %d)', x, y));
% Update x-subplot
gobj(3).YData = data(x,:);
title(ax(2), sprintf('X = %d', x))
% Update y-subplot
gobj(4).YData = data(:,y);
title(ax(3), sprintf('Y = %d', y))
end
Addendum: turn on/off interactivity
Press the left mouse button to turn on interactivity and the right mouse button to pause it so that the crosshairs and subplots do not update with mouse motion.
%% Add this section to the first block of code where the figure is created.
% Remove the windowbuttonmotionfcn in that section.
WindowButtonMotionFcnInput = {@mouseMove, data, ax, gobj};
set(ax(1).Parent,'windowbuttondownfcn', {@startStopMouseMove, WindowButtonMotionFcnInput})
%% This function responds to mouse clicks and either assigns
% or removes the windowbuttonmotionfcn
function startStopMouseMove(hobj,~,WindowButtonMotionFcnInput)
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
  6 个评论

请先登录,再进行评论。

更多回答(0 个)

类别

Help CenterFile Exchange 中查找有关 Specifying Target for Graphics Output 的更多信息

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by