Simon
Simon

Reputation: 5422

Updating data cursor position within a loop

I have a function updating a plot given a new point (it appends the last point to the line). I want to have the possibility to update the cursor such that it automatically appears on the last point. Currently, I do

for i = 1 : numel(dataObjs)
    X{i}(end+1) = newX{i};
    Y{i}(end+1) = newY{i};
    set(dataObjs(i), 'XData', X{i});
    set(dataObjs(i), 'YData', Y{i});

    set(cursorMode, 'enable', 'on');

    % Create a new data tip
    hDatatip = cursorMode.createDatatip(dataObjs(i));

    % Update annotation position
    hDatatip.Cursor.Position = [newX{i}, newY{i} 0];
end

However, it is slow since it always creates a new cursor. I cannot find where the old one is stored such that I don't have to create new ones.

Upvotes: 0

Views: 423

Answers (1)

Suever
Suever

Reputation: 65440

Rather than creating a new cursor object every time you add new data, you could create it once (per plot object) and save it to a variable. Then inside of the loop you can update the position.

set(cursorMode, 'Enable', 'on')

%// Create all of your data cursors once
for k = 1:numel(dataObjs)
    datacursors(k) = cursorMode.createDatatip(dataObjs(k));
end 

%// Now when you add new data
for k = 1 : numel(dataObjs)
    X{k}(end+1) = newX{k};
    Y{k}(end+1) = newY{k};
    set(dataObjs(k), 'XData', X{k});
    set(dataObjs(k), 'YData', Y{k});

    %// Update annotation position
    datacursors(k).Cursor.Position = [newX{k}, newY{k} 0];
end

And for the sake of a complete example:

hfig = figure();
data = rand(5,4);
hplots = plot(data);

cursorMode = datacursormode(hfig);

for k = 1:numel(hplots)
    datacursors(k) = cursorMode.createDatatip(hplots(k));
end

for k = 1:size(data, 1)
    for m = 1:numel(hplots)
        set(datacursors(m), 'Position', [k, data(k,m)])
    end
end

enter image description here

Update

As an alternative you could use findall to actually locate the data cursor for a given plot. The only downside of this is that it adds the overhead of having to find the data cursor every time that you want to update it.

datacursor = findall(ancestor(hplots(k), 'axes'), 'DataSource', hplots(k));

Another alternative

Rather than storing everything within a variable, you could store the data cursor in the UserData property of the plot objects themselves.

for k = 1:numel(hplots)
    set(hplots(k), 'UserData', cursorMode.createDatatip(hplots(k)))
end

Then to use it:

set(get(hplots(k), 'UserData'), 'Position', [x, y, 0])

Upvotes: 2

Related Questions