points id and scatter markers distance adjustment in figure.

1 view (last 30 days)
% for example;
x=[1000;1100;1200];
y=[2000;2100;2200];
points_id={'p100';'p200';'p300'};
figure(1),scatter(x, y, 'b^');grid on;
text(x, y+10, points_id); %it writes points id, a bit above scatter.
x=[10000;11000;12000];
y=[20000;21000;22000];
points_id={'p100';'p200';'p300'};
figure(1),scatter(x, y, 'b^');grid on;
text(x, y+10, points_id);
It writes the IDs a bit above scatter point markers but this time it isn't sufficient, because the coordinates are 10 times bigger than the previous one. When the user applies a zoom towards the points, the points IDs move farther away from the markers. Is there any way to adjust the distance between markers and ids each time automatically, and fix the points ID position when the user applies a zoom?

Accepted Answer

Geoff Hayes
Geoff Hayes on 25 May 2014
Yes, it just depends on how you feel about using global variables. (This is just something I looked at for the first time, so there may be more elegant approaches.) You can capture zoom events and adjust your text widgets based on whether the user is zooming in or out. Suppose you take your block of code (from above) and place it in a new function called moving_ids:
function moving_ids
close all;
global GRID_TEXT_HANDLES; % global var of all text handles (for ids)
global X_COORDS; % global var of the x coordinates
global Y_COORDS; % global var of the y coordinates
X_COORDS=[10000;11000;12000]; % need this info in post-zoom callback
Y_COORDS=[20000;21000;22000]; % need this info in post-zoom callback
points_id={'p100';'p200';'p300'};
figure(1),scatter(X_COORDS, Y_COORDS, 'b^');grid on;
% save handles to text/ids for post-zoom callback
GRID_TEXT_HANDLES = text(X_COORDS, Y_COORDS+10, points_id);
% get the figure's zoom mode object
h = zoom;
% set the pre-zoom callback
set(h,'ActionPreCallback',@prezoom);
% set the post-zoom callback
set(h,'ActionPostCallback',@postzoom);
In the above, we have set the framework to capture zoom events in the figure. Now you need to define the callbacks. The pre-zoom callback will be used to capture the limits (prior to zoom) of each axis:
function prezoom(obj,event_obj)
% obj handle to the figure clicked on
% event_obj object containing struct of event data
% (same as the event data of the
% 'ActionPreCallback' callback)
global PREZOOM_AXIS_X_LIMITS; % global var of the pre-zoom x-axis limits
global PREZOOM_AXIS_Y_LIMITS; % gloval var of the pre-zoom y-axis limits
PREZOOM_AXIS_X_LIMITS = get(event_obj.Axes,'XLim');
PREZOOM_AXIS_Y_LIMITS = get(event_obj.Axes,'YLim');
We are going to use the above pre-zoom limits to determine how the label position should be adjusted relative to the marker during the post-zoom. Now we handle the post-zoom action which will be used to adjust the text for each marker:
function postzoom(obj,event_obj)
% obj handle to the figure clicked on
% event_obj object containing struct of event data
% (same as the event data of the
% 'ActionPreCallback' callback)
global PREZOOM_AXIS_X_LIMITS;
global PREZOOM_AXIS_Y_LIMITS;
global GRID_TEXT_HANDLES;
global X_COORDS;
global Y_COORDS;
% get the post-zoom limits for each axis
PSTZOOM_AXIS_X_LIMITS = get(event_obj.Axes,'XLim');
PSTZOOM_AXIS_Y_LIMITS = get(event_obj.Axes,'YLim');
% determine the difference in the limits (for y only since in your code,
% the x-coordinate of the marker and label are identical)
prezoomYDiff = abs(PREZOOM_AXIS_Y_LIMITS(2) - PREZOOM_AXIS_Y_LIMITS(1));
pstzoomYDiff = abs(PSTZOOM_AXIS_Y_LIMITS(2) - PSTZOOM_AXIS_Y_LIMITS(1));
% adjust each label
for i=1:length(Y_COORDS)
% get the y-coordinate only for the marker
y = Y_COORDS(i);
% get the text handle for the label
txtHandle = GRID_TEXT_HANDLES(i);
% get the 3D position of the label
txtPos = get(txtHandle,'Position');
% calculate the difference (between the marker and label) in y only
yDiff = abs(txtPos(2)-y);
% set the new difference/range (from marker to label) to be at least 1
% and at most 10 (chosen as per original placement) using the ratio of
% post-zoom y-axis limit wrt pre-zoom y-axis limit
newYDiff = min(10,max(1,pstzoomYDiff/prezoomYDiff*yDiff));
% set the new position for the label relative to the marker
set(txtHandle,'Position', [txtPos(1) y+newYDiff txtPos(3)]);
end
If you choose to have a different x-coordinate (for the label) then the above code would have to be adjusted to do something similar for the changing x. Hope that this helps!

More Answers (0)

Categories

Find more on Visual Exploration in Help Center and File Exchange

Tags

Community Treasure Hunt

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

Start Hunting!