unable to plot on axes in matlab gui from listbox - matlab

I am working on MATLAB GUI in which i am updating the work-space variables in a list box and then trying to plot them on axes in GUI.
I have one other push button for performing plotting operation. But when i click on plot button, i get plots in a figure which pops up.
But according to my application i have to create the plots in axes. I am unable to do so
Kindly help
MY plot button code is as follows:
function plot_button_Callback(hObject, eventdata, handles, varargin)
% hObject handle to plot_button (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
[x] = get_var_names(handles);
if isempty(x)
return
end
if isequal(x,'a')
% figure(gcf)
try
figure(1)
evalin('base',['plot(a,b,''--r'')'])
hold all
evalin('base',['plot(a,c,''k'')'])
hold all
evalin('base',['plot(a,d,''g'')'])
figure(2)
evalin('base',['plot(a,e,''g'')'])
hold all
grid on
catch ex
errordlg(...
ex.getReport('basic'),'Error generating linear plot','modal')
end

Within each GUI callback, you have a variable called handles which is the key to editing/accessing any item in your GUI. In the case of plotting to an existing axis, you need to add an additional argument to the plot function. Here's a line of code I yanked from a GUI that I wrote:
plot(handles.axes1, xdata, ydata);
Now, this approach might not work easily for you because you are using the evalin function (which I don't recommend doing, it'd be much better to pass that information in to the gui). Regardless, a good way to implement your goal with these constraints is
a = evalin('base','a');
b = evalin('base','b');
plot(handles.axes1,a,b,'--r');
Your GUI axes might not be named axes, you'll have to check on that. You should also probably remove the figure(1) call, if I understand your goal correctly.
Also, you don't need to invoke hold all after each time you plot, once is sufficient.

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.

Matlab getrect function - How to skip the mouse input

In Matlab GUI, I need a user mouse input as a rectangle that I have to plot on the axes1.
For this, I have code below:
axes(handles.axes1);
filename = 'A';
img = imread(filename);
imshow(img);
hold on;
rect_cord = getrect(handles.axes1);
rectangle('Curvature', [0 0],'Position', [rect_cord],'EdgeColor',[1 0 0]);
This code runs fine (takes user input and plots the rectangle). However, for some images I don't want to get the user input from mouse (using getrect). In this case, how to skip the getrect function and move on to next image?
I have a pushbutton ("next"), I want to show next image when push button is pressed instead of taking user input.
Thanks,
I will try to rephrase and modify a bit: you want to draw a rectangle only if one clicks on the axes or image.
Therefore:
First of all I would suggest to put the getrect-part into another function. This function should only be triggered if one clicks on the image. The so called "ButtownDownFcn" seems to be suitable for this job. When using GUIDE, you will find it double-clicking on the axes within the property-inspector that is popping up.
Then put the getrect-part into this function:
function axes1_ButtonDownFcn(hObject, eventdata, handles)
% hObject handle to axes1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
rect_cord = getrect(handles.axes1);
rectangle('Curvature', [0 0],'Position', [rect_cord],'EdgeColor',[1 0 0]);
Now I thought that this is all that has to be done. But testing this with a plot or image within the axes prooved me wrong :o
Sadly one has to redirect the children of the axes to this function, because by default, it is only assigned to the background of the axes (=the blank axes).
by searching the net, I found the following solution here:
Matlab in Chemical Engineering: Interacting with your graph through mouse clicks
It works like this:
when plotting the image, you have to add the line
% and we also have to attach the function to the children, in this
% case that is the line in the axes.
set(get(gca,'Children'),'ButtonDownFcn', #mouseclick_callback)
Hope that helps!

Plotting an image (.tif) and a contour in one axes on GUI matlab

I'm working on a GUI able to display images and data associated with the latter images.
I have an x,y image, and a function f(x,y) (wich is a contour) and I'd like to show both the image and the contour in one single plot using an axes object.
This is how I get the image showed in the axes :
function aff_toto_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject handle to figure
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% varargin
imshow(handles.im_ref,'parent',handles.axes1);
Now I get a contour matrix :
[handles.c,handles.h] = contour(handles.coor_y,handles.coor_x,handles.fun,handles.vec_iso);
I'd like to plot these contour lines on the image itself, in handles.axes1. Does anyone have a clue ?
Thank you all for reading this.
EDIT :
For now I'm just tying to plot some random sine over my picture. I tried
imagesc(handles.im_ref,'parent',handles.axes1);
hold(handles.axes1,'on');
plot(handles.axes1,handles.coor_x,sin(handles.coor_x));
hold off;
which shows the picture but the plot remains invisible.
I eventually found out where my problem was. using gui objects the hold function has to be used in a different way. As shown below you can specify on whether object hold is working.
It is the same for the contour function. It is possible to declare the Parent property (which can be an axes).
function aff_toto_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject handle to figure
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% varargin
imagesc(handles.im_ref,'parent',handles.axes1);
hold(handles.axes1,'on');
set(handles.axes1,'color','none');
[handles.c,handles.h] = contour(handles.coor_y,handles.coor_x,handles.ch_tr,handles.vec_iso,'Parent',handles.axes1);
hold(handles.axes1,'off');
Using this code, I was able to solve my problem. See also this page in order to find further information about the issue of plotting a random curve on a random picture (image flip issues are discussed there for instance).

How to select for which plot window call function view(90,0)?

I need to apply it for two different plots on user button press not only the last one.
.I have wanted to ask is there some kind of a command that i could select plot from subplot and than proceed with it?
I have GUI and GUI displays me two 3d plots, but when i need to press some buttons for example which changes the view of those plots only one plot is changing the viewing angles other one is doing nothing.
So is there any tool to make both plots change?
function byheight_pushbutton_Callback(hObject, eventdata, handles)
% hObject handle to byheight_pushbutton (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
%Display contour plot of the currently selected data
%select the first plot
view(90,0), shading interp
%select the second plot
view(90,0), shading interp
Use the syntax:
view(ax,...)
where you can specify which axes you call the view function on. For more details, see the documentation page for the view function.
Arnaud

sending axes as parameter in matlab

I need a help with MatLab GUI .
I have a GUI with an axes on it,
and a function plotData(axes,data) which has axes as parameter.
The GUI has a button "plot Data".
How can I do the following:
When the button is clicked, call the function plotData with the parameter axes1 and the data that I want to plot?
I want the plot to be directed to axes1 which exists in the GUI.
It's suppose to be simple, but when I send the axes as parameter it doesn't plot on the GUI, or maybe it does but I cant see it.
It works fine for me without the function: just to plot the data. but to plot the data it's not 1 row :).
i tried calling ax which storing the GUI's axes handle on different M file, but since i call it as a function from different M file nothing happens with the GUI axes handle but it also not returning any error.
Side remark: Your question is a bit unclear: if you added small code snippet to illustrate what you have tried, better answers could be provided.
To the question at hand:
Have you tried directing the plot to axis1 in plotData?
function [] = plotData( ax, data )
% make ax the current axes for plot
axes( ax );
% continue with plotting the data
% ...
You can achieve the effect of axes( ax ); in a more efficient way through the specific plot commands you are using.
For example, if you are using simple plot
plot( ax, data ); % plots data to axes ax
check the documentation of the specific plot command you are using for the axes argument.