You can actually do this by adding a 'WindowButtonMotionFcn'
to your figure (assuming nothing else is using it) that will display crosshair lines in your axes when your mouse is over it. Here's a function that creates such functionality for all axes in a figure:
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
If you do the following:
full_crosshair(gcf);
Then as you move the cursor over each axes in your figure the cursor will disappear and you will see two lines appear and track the mouse position. If any of the axes limits change, then the event listeners in the above code will detect and account for it. If axes are added to or removed from the figure, you will need to call full_crosshair
again to update 'WindowButtonMotionFcn'
accordingly.
Finally, you can turn it off by just clearing 'WindowButtonMotionFcn'
:
set(gcf, 'WindowButtonMotionFcn', []);