Drawing with mouse on the GUI in matlab - matlab

I want to have a program in matlab with GUI, at run the program, user can draw anythings with mouse on the axes in GUI, and i want to saving created image in a matrix. how can i to do this?

Finally i find a good code and i have changed some parts for customizing for me. with this way, user can drawing anythings in the axes with mouse :
function userDraw(handles)
%F=figure;
%setptr(F,'eraser'); %a custom cursor just for fun
A=handles.axesUserDraw; % axesUserDraw is tag of my axes
set(A,'buttondownfcn',#start_pencil)
function start_pencil(src,eventdata)
coords=get(src,'currentpoint'); %since this is the axes callback, src=gca
x=coords(1,1,1);
y=coords(1,2,1);
r=line(x, y, 'color', [0 .5 1], 'LineWidth', 2, 'hittest', 'off'); %turning hittset off allows you to draw new lines that start on top of an existing line.
set(gcf,'windowbuttonmotionfcn',{#continue_pencil,r})
set(gcf,'windowbuttonupfcn',#done_pencil)
function continue_pencil(src,eventdata,r)
%Note: src is now the figure handle, not the axes, so we need to use gca.
coords=get(gca,'currentpoint'); %this updates every time i move the mouse
x=coords(1,1,1);
y=coords(1,2,1);
%get the line's existing coordinates and append the new ones.
lastx=get(r,'xdata');
lasty=get(r,'ydata');
newx=[lastx x];
newy=[lasty y];
set(r,'xdata',newx,'ydata',newy);
function done_pencil(src,evendata)
%all this funciton does is turn the motion function off
set(gcf,'windowbuttonmotionfcn','')
set(gcf,'windowbuttonupfcn','')

The ginput function gets the coordinates of moueclicks within a figure. You could use these as points of a line, polygon, etc.
If this doesn't fit your needs you need to decribe what exactly you expect the user to draw.
For freehand drawing this might be helpful:
http://www.mathworks.com/matlabcentral/fileexchange/7347-freehanddraw

The only way I know to interact with matlab windows using a mouse is ginput, but this will now let you draw anything with fluidity.
There are ways to use Java Swing components in matlab check http://undocumentedmatlab.com/ for more info.
EDIT: You may want to check this out as well.
http://blogs.mathworks.com/videos/2008/05/27/advanced-matlab-capture-mouse-movement/

Related

How to use "ButtonDownFcn" in a populated GUI axes?

I have a very simple GUI made in guide where i have a plot function initiated by a pushbutton which plots a scatter plot in axes (called Method1axes1):
handles.plot = scatter(X,Y, 'parent', handles.Method1axes1);
Now I want the user to be able to click the axes (plot) to get en new larger figure. I tried the below code which is working if i DON'T plot in the axes first. As soon as I run the plot function the scatterplot appears in Method1axes1 but I can no longer click the figure.
% --- Executes on mouse press over axes background.
function Method1axes1_ButtonDownFcn(hObject, eventdata, handles)
figure
scatter(X,Y);
What am I doing wrong?
This is a kind of special case for MATLAB, and it is not extremely well documented.
There are 2 things you need to consider:
1) The most obvious part. When you plot something in your axes, the plot is on the foreground. So when you click on your axes, the top plot intercept that click and tries to process it. You need to disable the mouse click capture from the plot/scatter/image objects you have in your axes. For that, you have to set the HitTest property of your scatter object to 'off'. (recent MATLAB version have changed the name of this property, it is now called PickableParts).
2) Much less obvious and documented. It used to be in the doc for the axes ButtonDownFcn callback but it is not explained anymore (although the behaviour persist). This is what I could find on old forums:
When you call PLOT, if the axes NextPlot property is set to 'replace'
(which it is by default) most of the properties of the axes (including
ButtonDownFcn) are reset to their default values.
Change the axes NextPlot property to 'replacechildren' to avoid this,
or set the ButtonDownFcn after calling PLOT, or use the low-level LINE
function instead of the higher-level PLOT function.
This is also discussed and explained here: Why does the ButtonDownFcn callback of my axes object stop working after plotting something?
For your case, I tried set(axe_handle,'NextPlot','replacechildren') and it works ok to let the mouse click reach the ButtonDownFcn, but unfortunately it creates havoc with the axes limits and LimitModes ... so I opted for the second solution, which is to redefine the callback for ButtonDownFcn after every plot in the axes.
So in summary, your code for the pushbutton1_Callback should be:
function pushbutton1_Callback(hObject, eventdata, handles)
% Whatever stuff you do before plotting
% ...
% Plot your data
handles.plot = scatter(X,Y, 'parent', handles.Method1axes1);
% Disable mouse click events for the "scatterplot" object
set(handles.plot,'HitTest','off') ;
% re-set the "ButtonDownFcn" callback
set(handles.Method1axes1,'ButtonDownFcn',#(s,e) Method1axes1_ButtonDownFcn(s,e,handles) )
And for your axes mouse click event, you might as well keep the handle of the new generated objects:
function Method1axes1_ButtonDownFcn(hObject, eventdata, handles)
handles.newfig = figure ;
handles.axes1copy = copyobj( handles.Method1axes1 , handles.newfig ) ;
Note that instead of plotting a new set, I simply use the copyobj function, very handy when you need to reproduce a plot.
Illustration:
If you want to set the figure/graph to enlarge and shrink on mouse
scroll/click, then just set the zoom property of the required axes in
OpeningFcn within the m file.
For example within the OpeningFcn in the GUI's m file, put the below code. Please ensure that you put the below code within the OpeningFcn function.
h1 = zoom(handles.Method1axes1);
h1.Enable = 'on';
Now, on each mouse scroll/click, you would be able to zoom in/out the graphs.
A sample screenshot of openingFcn for a GUI named ZoomAxesDemo is given below.

How to force drawnow Matlab GUI to draw in new window?

I have used drawnow to draw the characters of the mnist dataset.. which outputs the following output
when i created GUI with matlab and calling drawnow to display images after loading it draws the figure on the open window giving the following output
my question is how to force it to draw in new window ?
drawnow only asks Matlab to flush the event queue and update figure windows; it doesn't determine how and where things are plotted. It's hard to tell since you don't include any code, but in your case it looks like you just plot the character images and the GUI elements into the same figure.
You can control which figure window a graphics operation refers to by setting the "current figure", whose handle is always contained in the variable gcf (graphics: current figure).
You generate a new figure and make it current by calling
figure
If you want to later make this figure current again, you need to save its handle:
fa = figure;
You then make a figure with a given handle current again by
figure(fa)
Some rough sketch of a possible program:
% generate figure windows
fa = figure;
fb = figure;
% plot something in figure a and make the screen update
figure(fa)
plot(...)
drawnow
% put a UI element into figure b and make the screen update
figure(fb)
uicontrol(...)
drawnow

Clickable/ Interactive contour plots in Matlab

I have formed a 2D matrix of 180X360. In fact, it is a LatXLong grid of 1°X1°. Each grid point has a value calculated according to my algorithm.
If I want to plot this LatXLong grid using any contour function, it is easy to do.
Now, what I need to do is to make this grid a clickable/ interactive contour plot in a way that when the user clicks anywhere on my grid plot, he gets an onscreen information or a further plot to be displayed specifically related to that grid point.
In short, I want to make a grid/contour plot in which all grid points are hyperlinks and linked to further background information.
check this answer:
if you don't want to have the variable as title of the plot, you can modify the code as:
function mouseExample()
h = plot(rand(10,1), 'o-');
set(h, 'ButtonDownFcn',#buttonDownCallback)
function out = buttonDownCallback(o,e)
p = get(gca,'CurrentPoint');
out = p(1,1:2);
% title( sprintf('(%g,%g)',p) ) % --> no need this line anymore
end
end
the information is saved in the P variable that you can use later.
To get started, look into ginput and text. ginput will let you click on points in your plot and return the coordinates to some function that can generate information to be displayed in the current plot using text of by opening another figure.
You can use ginput in a loop to display multiple data points as you go:
for t = 1:10
[x,y] = ginput(1);
text(x,y,'some info');
end
I don't know of a way to remove the gird lines. NKN's solution might do that for you.

matlab selecting regions in matlab plot

I have a problem when i am working with plots in Matlab. Following are my issues with Plots:
How can one select Regions after plotting data using mouse?
After selecting the Regions how to get data from that region?
Any Ideas?
Selecting regions with a mouse is quite easy using the rbbox function.
First you add a ButtonDownFcn to the axes you are drawing rbbox on.
hax = axes( ... , 'ButtonDownFcn', #OnClickAxes);
Then you call rbbox within the callback like this
function OnClickAxes( hax, evt )
point1 = get(hax,'CurrentPoint'); % hax is handle to axes
rbbox;
point2 = get(hax,'CurrentPoint'); % hax is handle to axes
end
Here point1 and point2 will define the two corners of the rectangle drawn by your mouse in data coordinates. Type doc rbbox at matlab prompt for more information
Now to answer your second question for 2-D plots.
This bit of code will extract and return the data within the selected region for all lines within an axes.
https://gist.github.com/3107790

Make clicking MATLAB plot markers plot subgraph

In Matlab 2011b, I have a multidimensional matrix which is to be initially presented as a 2D plot of 2 of its dimensions. I wish to make the markers clickable with the left mouse button. Clicking on a marker draws a new figure of other dimensions sliced by the clicked value.
This question is related to Matlab: Plot points and make them clickable to display informations about it but I want to run a script, not just pop up data about the clicked point.
Googling hinted that ButtonDownFcn could be used, but examples I found require manually plotting each point and attaching a handler, like so:
hp = plot(x(1), y(1), 'o');
set(hp, 'buttondownfcn', 'disp(1)');
As there are many markers in the main graph, is it possible to just attach a handler to the entire curve and call the subgraph-plotting function with the index (preferable) or coordinates of the marker clicked?
this is an idea of what you need, and should help get you started if I understand your requirements.
In this case, when you select a curve, it will draw it in the bottom subplot preserving the color.
function main
subplot(211)
h = plot (peaks);
set (h,'buttondownfcn', #hitme)
end
function hitme(gcbo,evendata)
subplot (212)
hold on;
col = get (gcbo,'Color');
h2 = plot (get (gcbo,'XData'),get (gcbo,'YData'));
set (h2,'Color', col)
pt = get (gca, 'CurrentPoint');
disp (pt);
end
You can explore your options for get by simply writing get(gcbo) in the hitme function.