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.
Francois Bouffard (2019). draggable (https://www.mathworks.com/matlabcentral/fileexchange/4179-draggable), MATLAB Central File Exchange. Retrieved .
1.3.0.0 | This update fixes a bug found by Esmerald Aliai in which draggable would not work for axes embedded in Panels. In fact this should also fix Shaun's bug mentioned in March 2012. |
|
1.2.0.0 | Major update. Now supports text objects. Diagonal constraints with arbitrary slopes added. Single call for applying draggable on multiple objects sharing the same parameters supported. Added the 'sliders' demo in dragdemo. General cleanup. |
|
1.1.0.0 | implemented a feature and fixed a bug (both user-suggested) |
|
1.0.0.0 | Bugfix for Matlab 7+: axes no longer disappear. Renderer option removed. |
|
- Bugfix: yet another correction to movement computation. Now behaves correctly when mouse is out of axes. |
||
- Bugfix: sanitized movement computation.
|
||
- Bugfix: now works with 1-element plot and line objects
|
||
- Changed the category from "GUI tools and examples" to more accurate "Graphics: Graphical Data Exploration and Interaction".
|
||
Changed the category from "GUI tools and examples" to more accurate "Graphics: Graphical Data Exploration and Interaction". |
Inspired: colorStudioMax: ColorBrowser+dictionary, colorBlind correct, DragDataTip, roitool, DIGITIZE07, Enhanced Dicom Viewer, imdisp (enhanced version), Add an ROI toolbar to your figure, draggableRect, AVPlay
Create scripts with code, output, and formatted text in a single executable document.
Francois Bouffard (view profile)
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 (view profile)
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 (view profile)
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 (view profile)
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 (view profile)
Francois Bouffard (view profile)
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 (view profile)
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 (view profile)
wei xu (view profile)
What an absolutely brilliant function. Thank you for making it.
Andra St. Quintin (view profile)
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 (view profile)
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 (view profile)
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 (view profile)
Bertrand Bevillard (view profile)
Guojin Feng (view profile)
Chaoyu Zhang (view profile)
Gabriel Marsh (view profile)
Jess (view profile)
Bhar_tex (view profile)
Excellent!
Aldi Wijaya (view profile)
Excellent Work, thanks Francois
Yang Yu (view profile)
Samarth Vadia (view profile)
Francois Bouffard (view profile)
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 (view profile)
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. (view profile)
Manuel (view profile)
liu (view profile)
samfort (view profile)
Massimo Ciacci (view profile)
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 (view profile)
I had to create an account and a community profile to rate this. This is simply awesome! Thank you Francois!
Timo Dörsam (view profile)
Yi Sui (view profile)
Jaroslaw Tuszynski (view profile)
This function allows me to place comment boxes on the plot and manually adjust them before inserting in presentation
Shahab (view profile)
Excellent, tahnks
Francois Bouffard (view profile)
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 (view profile)
Shaun (view profile)
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 (view profile)
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 (view profile)
Most excellent work...rock solid!
Steven Bierer (view profile)
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 (view profile)
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 (view profile)
Wow, amazingly well done!
Excellent, just what I was looking for!
Very handy file!
I love it because it learns me a lot about mousebutton handling.
I tried to make a text object draggable: that doesn't work!
It is a really great work with impressive options.
Congratulations!
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.