File Exchange

image thumbnail

draggable

version 1.4.0.0 (11.9 KB) by Francois Bouffard
Allows graphical objects to be dragged in a figure.

14 Downloads

Updated 13 Apr 2020

View Version History

View License

Editor's Note: This file was selected as MATLAB Central Pick of the Week

This function enables a graphical object (be it a line, plot, patch, rectangle, text box, etc.) to be dragged inside an axis, with a very simple syntax ("draggable(h)"), following or not horizontal, vertical or diagonal constraints. Limits can be imposed on the object's movement.

Some figure properties are changed by the function, but previous properties are restored as soon as the drag is stopped. The behavior of the object can be reverted to its original, non-draggable state, by issuing "draggable(h,'off')".

Typical uses of this function would include non-standard GUI elements, such as markers that are moved on a figure or image. A function which is called when the object is moved can be provided as an optional argument, so that the movement triggers further actions.

See the provided file dragdemo.m for usage examples.

Cite As

Francois Bouffard (2021). draggable (https://www.mathworks.com/matlabcentral/fileexchange/4179-draggable), MATLAB Central File Exchange. Retrieved .

Comments and Ratings (74)

Francois Bouffard

This version of draggable won't be updated to work with 2021a if it is indeed broken. I suggest everyone to take a look at William Warriner's implementation. It has much better chances to work on future versions of Matlab than this one. https://www.mathworks.com/matlabcentral/fileexchange/78739-draggable

Boyd Tolton

This is a Brilliant add-on. However it appears that 2021a has broke it.

Anna Rothweil

Sanjeev Reddy

Thanks very much. Brilliant.

Francois Bouffard

Raphael: you can of course set the line to be thicker (increase the linedwidth property). If you need more than that, I suggest you take a look at the 'polymove' demo in dragdemo.m. In this demo, the polygon vertices are small circles. Each time one is moved, the polygon is redrawn. You can use a similar strategy in your case. Of course, the 'group' demo is also relevant, and uses the same technique with 'motionfcn' arguments. I've never came around to implement true grouping functionalities however.

Raphael Kriegl

Hey, I have another Question: I implemented a draggable line, but it's pretty thin.
Can I add another shape that is easier to grab and move them in unison?

Raphael Kriegl

Hi Francois, thanks for reply. Your suggestion worked perfectly. Thanks

Francois Bouffard

Raphael: you may have run into a problem with a previous bugfix intended to make draggable work with axes embedded into ui Panels. I suggest going into the draggable.m file to lines 188-189. You'll see 188 is commented ( fgh = get(axh, 'Parent'); ) while 189 is active (fgh = gcbf;). Try switching this around (uncomment 188 and comment out 189). If the situation is fixed for your case, then it means I should try to find a more universal way to obtain the figure handle. In the meantime you'll have a workaround. If it doesn't fix the solution, I suggest sending me a minimal example of your situation (by email) so that I can look at it more closely.

Raphael Kriegl

Hey, great submission, used it for a while now.
However, I ran into an issue after changing my app. When I have a uifigure and a normal figure, the draggable object on the axes inside the figure only updates position when I move my mouse over the uifigure window. Until then it seemingly stays still but registers the position change internally.
Do you have an idea what could be happening here?

Eugene Du

Francois Bouffard

Hi Claudius... I can't reproduce your problem on my old Matlab version. Try the following simple example and if you still can't zoom or move the plot afterwards, this will be most likely due to differences in the Matlab version and I'll suggest you take a look at William Warriner's draggable re-implementation (see comments below).

f = figure; axis equal; box on; xlim([0 1]); ylim([0 1]);
r = rectangle('Position', [0.7 0.1 0.1 0.2], 'FaceColor', 'g');
draggable(r); # Fool around with the rectangle a bit
draggable(r, 'off'); # Turn draggable off
# Now try zooming or moving the plot around

On my side (R2009b!) the zoom and hand tools are working on the plot in this simple example.

I have a short question, after meddling with it a bit:
I admit that handles are not the most intuitive thing to me, but I am able to make a line draggable using syntax provided. However, once I have disabled draggable on that figure / all objects I used it on, I am now unable to move the plot around or zoom in or out. Anyone know how to solve that? Or is it an innate problem of draggable that it locks the axes completely?

Francois Bouffard

Thanks William. To people who still have problems with integrating draggable with AppDesigner, and/or use a non-ancestral version of Matlab, this might be the way to go!

William Warriner

Hi Francois, good news! I've added my version of draggable to the FileExchange which has compatibility for UIAxes and UIFigures! https://www.mathworks.com/matlabcentral/fileexchange/78739-draggable

Francois Bouffard

Johannes, at this point, given that I can't test any fix myself regarding App Designer, I think someone should simply fork Draggable and make a version that doesn't necessarily aim for backward compatibility and that makes use of all the capabilities of the UIgraphics system. Sorry that I can't be of more help...

Johannes

Hi Francois, that is a great tool. I used it a lot but have problems with the implementation in App Designer.
I get the following error (Matlab R2018b):

Error using matlab.ui.control.UIAxes/get
There is no CurrentPoint property on the UIAxes class.

Error in draggable>movefcn (line 354)
current_point = get(axh,'CurrentPoint');

Is there a fix for this or what am I doing wrong?

Thanks!

Jose Manuel Amigo

.

Francois Bouffard

I just published a new version of draggable that probably fixes issues with App Designer apps. Thanks to William Warriner for helping me with this. If this still causes problems or break things for you, please let me know.

William Warriner

Hi Francois, I've got it fixed to work with both figure() and uifigure(). I'm happy to send along my copy if you have a preferred method. If you contact me through my profile we can set it up.

Sorry there was originally more to this. It turns out the issue was with raw calls to gcf and gca in click_object(), and gca in movefcn(). With some function currying I was able to pass the top-level fgh and axh down the callback stack to where they are used. Since gcbf() correctly returns the uifigure() and get(h, 'parent') correctly returns the uiaxes(), everything works as expected for both a figure() and for uifigure() with uiaxes().

Francois Bouffard

If anybody can find the cause of why draggable doesn't work with App Designer GUIs, I'd be happy to try and fix it. Feel free to contact me by email at fbouffard on gmail if you think you know why.

robin tournemenne

O_O Wouhaaaaa!

Hakki Eres

Thank you, Francois.

I have tried your suggestion about handleVisibility attribute, but it still behaves the same way. I will keep using the GUIDE design for now.

Best wishes

Francois Bouffard

Hi Hakki -- does the advice I gave to Alexander below help in your case? I can't really comment further as I don't have access to App Designer.

Francois Bouffard

Sorry, I really meant to type Hakki.

Hakki Eres

Hi, Francois.

I have been using your function successfully on Matlab GUIs designed with GUIDE. However, I was unable to use the draggable function with the new App Designer based apps. Can you recommend any workaround or solution?

Best wishes.

Francois Bouffard

Hi Alexander, it's hard for me to comment on your problem as I don't currently have access to app designer. Maybe the problem is that you app's handle visibility is set to off? It's the only thing I can think of now. In fact, I can reproduce what you describe if I just create a figure and do set(gca(), 'handleVisibility', 'off') before setting an object draggable. So I guess setting the figure and/or axes handleVisibility property to 'on' might work.

Alexander Hodge

This is a great function! I am trying to implement it into app designer, and I'm having running into some problems though. When I try to drag an object, it loads a separate figure, and the draggable object only moves if the cursor moves along certain spots on that separate figure. To fix this, Are there some functions in draggable that I should move into my app as callbacks? Thanks!

Francois Bouffard

Hi Allen, sorry for the delay. I currently do not have access to a recent Matlab license so I can't debug the problem with datetime objects. Contact me (email address is in the file or in my profile) if you are interested in trying to fix this. This might just be a matter of adding a case to handle datetime limits. It might be impossible for me to fix this though. If someone has a fix that doesn't break the demos in dragdemo, then I could upload it as well.

Allen

Francois, great function. I have implemented it into a function that allows for draggable data tips, which work fairly seamlessly. One limitation that I have discovered involves axes that contain 'datetime' data types in at least one axis. Hope that you are interested in updating to work with such cases and look forward to a new version if so. Cheers!

Lai man

Francois Bouffard

Kerim: it should be possible. Take a look at the 'polymove' example in dragdemo.m and modify it to suit your needs. In that example, the line is closed but it is straightforward to make it a general plot.

Kerim Khemraev

Nice! Is it possible to independantely drag points of the same line? I mean I plot 2D data and I want interactively edit it.

Zilong Liang

wei xu

What an absolutely brilliant function. Thank you for making it.

Andra St. Quintin

Excellent, thank you! Did exactly what I needed to create an adjustable curve with as many manual adjustment points as needed, which I can then interpolate smoothly between.

Francois Bouffard

Hi HpW. Check the 'sliders' demo in dragdemo.m for an example on how to use the end function. You can't send arbitrary arguments to the end function. It is specified this way for object handle objh:

draggable(objh, ..., 'endfcn', @myendfcn);

Function myendfcn should only have a single argument, and the handle objh will be passed as this argument. So if you want to send more arguments to myendfcn, tuck them in the objectusing setappdata/getappdata on objh.

Hope this helps.

HpW

Really nice! Im having trouble using this in a large GUI with multiple axes. I can get the objects/lines to move by dragging, but I cant get the endfunction to play nice with handles. Any ideas on how to make this work? Tried passing handles in the endfunction like {@end_function,handles} but that doesnt seem to work.

HpW

Bertrand Bevillard

Guojin Feng

Chaoyu Zhang

Gabriel Marsh

Jess

Bhar_tex

Excellent!

Aldi Wijaya

Excellent Work, thanks Francois

Yang Yu

Samarth Vadia

Francois Bouffard

Armindo: this is possible by changing the axes limits (using xlim and ylim) inside the callback function provided as a parameter. I'm trying to make a demo but doing it so that it's not confusing to the user (e.g. axes panning too fast) requires care.

Armindo

Very nice...

would be possible to drag an object horizontally while updating the axes 'xlim' property.

Basically I need to be able to drag a patch and while iam doing that when Iam near de limits of the plot the plot adjust the limits so I can still be able to drag...

Can you help me on this please

Sergei P.

Manuel

liu

samfort

Massimo Ciacci

Well written, and plenty of demos... I am speechless, exactly what i was looking for!

More precisely I loved how accurate and concise are both the demo code and the function itself! Well done!

Scott

I had to create an account and a community profile to rate this. This is simply awesome! Thank you Francois!

Timo Dörsam

Yi Sui

Jaroslaw Tuszynski

This function allows me to place comment boxes on the plot and manually adjust them before inserting in presentation

Shahab

Excellent, tahnks

Francois Bouffard

Shaun's problem should be fixed now; I instead simply used fgh = gcbf; -- it should work in all situations. Thanks to Esmerald Aliai for pointing out a similar bug.

Sebastian Holmqvist

Shaun

I love it, and I use it all the time.
One mod I have made for axes which live inside UICONTAINERS...

fgh = get(axh,'Parent');
while ~strcmp(get(fgh,'Type'),'figure')
fgh = get(fgh,'Parent');
end

Francois Bouffard

Sorry for the years-long delay since the last update... The Jan 13 update contains a bug fix by G. Fortin and Steven Bierer's drag-end function call. I'll try to add Brett's suggestion shortly.

Brett Shoelson

Most excellent work...rock solid!

Steven Bierer

An excellent, deviously simple tool. The code is well commented, and I was easily able to modify it to include a new input argument: a function handle that executes AFTER the object has been dragged. (I will contact the author with this addition, in case he'd like to incorporate it.)

Florian Jousset

Thanks!
I used it to move text, and it worked well after adapting your code to objects having a "Position" property of 3 values.

Nathan Tomlin

Wow, amazingly well done!

Chris Sarantos

Excellent, just what I was looking for!

Paul Premakumar

Very handy file!

Tom Nagel

I love it because it learns me a lot about mousebutton handling.
I tried to make a text object draggable: that doesn't work!

w L

Laszlo Balkay

It is a really great work with impressive options.

Congratulations!

Ohad Gal

Well done.
you might want to add an option for the following:
1. force a movement of the object, using an outside calling function.
2. enable the user to choose it's rendering mode
3. export (and update a given edit box) the DX and DY movement of the object

anyways, It's great. thanks you !

Ohad.

MATLAB Release Compatibility
Created with R2020a
Compatible with any release
Platform Compatibility
Windows macOS Linux

Community Treasure Hunt

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

Start Hunting!