Rank: 5801 based on 19 downloads (last 30 days) and 1 file submitted
photo

Thomas Otterstaetter

E-mail
Company/University
University of Stuttgart

Personal Profile:
Professional Interests:

 

Watch this Author's files

 

Files Posted by Thomas
Updated   File Tags Downloads
(last 30 days)
Comments Rating
16 Jul 2012 Screenshot LineManipulator Allows mouse-based manipulation of the data of a line object. Author: Thomas Otterstaetter gui, mouse, plot, line, manipulate plot, manipulate line 19 4
  • 5.0
5.0 | 1 rating
Comments and Ratings by Thomas
Updated File Comments Rating
16 Jul 2012 LineManipulator Allows mouse-based manipulation of the data of a line object. Author: Thomas Otterstaetter

Thanks for the feedback :)
I incorporated the turning off feature - admittedly not very beautiful anymore by loading the Userdata of the line....but it works ;)

Comments and Ratings on Thomas' Files View all
Updated File Comment by Comments Rating
09 Aug 2012 LineManipulator Allows mouse-based manipulation of the data of a line object. Author: Thomas Otterstaetter Holmqvist, Sebastian

Also, if you happen to have very uneven axis ranges (one small, one very big), the behaviour can be somewhat odd with the cursor jumping between points seemingly at random.

Try

h = plot(linspace(1,7000,5),linspace(10,30,5)); pathManipulator(h, 'nocheck')

with one axis at 7000 ticks and the other at 5. As you can see, when you try to move one marker past another left/right, the cursor switches to the other marker even though the distance seems fairly large. This does not happen when passing the marker up/down.

My solution is to take the axis ranges into account and scale the vertical and the horizontal distances accordingly before calculating the pythagoras distance.

So swap out all lines

[~,minDistIndex]=min((XData-currentPoint(1,1)).^2+(YData-currentPoint(1,2)).^2);

with

cAxis=[get(axHandle,'XLim') get(axHandle,'YLim')];
xScale = cAxis(2)-cAxis(1);
yScale = cAxis(4)-cAxis(3);
[~,minDistIndex]=min(((XData-currentPoint(1,1))*yScale).^2+((YData-currentPoint(1,2))*xScale).^2);

and it should do the trick.

08 Aug 2012 LineManipulator Allows mouse-based manipulation of the data of a line object. Author: Thomas Otterstaetter Holmqvist, Sebastian

I believe I found a bug in your latest version.

First off, if a line is initiated (with this script) twice in a row, it's old styling is not recoverable since the Userdata already has been overwritten. That's a minor issue and could be prevented by checking if a line has been initiated and simply do LineManipulator(lineHandle, 'off') before initiating it once more.

The bug however, is when using either 'pushx' or 'pushy'. The pushing part works fine, but the points are unable to move freely in the other direction. So for e.g 'pushx' I simply added

YData(minDistIndex)=currentPoint(1,2);

on line 195. Similarly you add the corresponding piece of code on line 205.

16 Jul 2012 LineManipulator Allows mouse-based manipulation of the data of a line object. Author: Thomas Otterstaetter Otterstaetter, Thomas

Thanks for the feedback :)
I incorporated the turning off feature - admittedly not very beautiful anymore by loading the Userdata of the line....but it works ;)

03 Jul 2012 LineManipulator Allows mouse-based manipulation of the data of a line object. Author: Thomas Otterstaetter Holmqvist, Sebastian

03 Jul 2012 LineManipulator Allows mouse-based manipulation of the data of a line object. Author: Thomas Otterstaetter Holmqvist, Sebastian

Beautiful piece!

Would be nice with a feature that allows turning the whole thing on and off and restoring the line properties. E.g LineManipulator(h, 'off') or similar.

Also, I modified your script to check the closest distance for all line objects, not just the most recent one.

%% ClosestPoint
% Find the closest point in all available line objects
function [lineHandle, minDistIndex] = ClosestPoint(currentPoint)
lineHandles = get(axHandle, 'Children');

% Init output etc.
minDist = Inf;
minDistIndex = 0;
lineHandle = 0;

% Iterate through all children of the current axes
for i = 1:length(lineHandles)
objType = get(lineHandles(i), 'Type');
objTag = get(lineHandles(i), 'Tag');

% Only check line objects
if strcmp(objType, 'line') && ~strcmp(objTag, 'Ghost')
XData = get(lineHandles(i), 'XData');
YData = get(lineHandles(i), 'YData');
[dist, distIndex] = min((XData - currentPoint(1,1)).^2 + (YData - currentPoint(1,2)).^2);

if dist < minDist
minDist = dist;
minDistIndex = distIndex;
lineHandle = lineHandles(i);
end
end
end
end

Just comment out all lines
[~,minDistIndex]=min((XData-currentPoint(1,1)).^2+(YData-currentPoint(1,2)).^2);
and insert
[lineHandle, minDistIndex] = ClosestPoint(currentPoint);
before lines
XData=get(lineHandle,'XData');
YData=get(lineHandle,'YData');

I just disabled the ghost lines from plotting, but you can easily modify the script to tag those lines with e.g 'Ghost' to exclude them. Example:
plot(axHandle,get(lineHandle,'XData'),get(lineHandle,'YData'),'Color',get(lineHandle,'Color')...
,'Linewidth',get(lineHandle,'LineWidth')*0.5,'LineStyle',':','Tag','Ghost')

Contact us