How to plot several function calls in one figure - matlab

I made a matlab-function that plots a graph. When I call the function several times, I want it to plot all the graphs in one prepared figure. But instead my code opens with every function call the prepared figure in a new window with only one Graph in it.
My function looks like this
function myfunction(x,y)
if ~exist('myfigure')
myfigure = openfig('myfigure.fig')
assignin('base', 'myfigure',myfigure)
end
figure(myfigure);
plot(x,y)
end
With the if-function I tried to prevent it from opening a new figure-window, when myfigure is allready opened. But it seems like Matlab just ignores the if-function for my surprise. Even the Assignin didn't help out. Although checking in the command window, showed that exist('myfigure') changes its value.
I really don't know why the if-function is ignored by Matlab. Have you any suggestions how to fix this

The problem here is exist cannot see the previous figure, because it's handle is deleted when the previous call to the function was ended. My suggestion is as follow:
Pass the figure handle to the function, and also return it as output:
function myfigure = myfunction(x,y,myfigure)
if nargin<3 % if you pass 2 variables or less
myfigure = figure; % create a figure
else
figure(myfigure); % otherwise use the one in handle
end
plot(x,y)
end
Here a sample code for that:
x = 0:0.01:2*pi;
myfigure = myfunction(x,sin(x)); %first call
myfunction(x,cos(x),myfigure); % second call
myfunction(x,tan(x),myfigure); % third call...
Note that you only need to get myfunction output on the first call, then you can continue using it until you delete the figure.

The function figure that you used is probably why it opens a new figure.
What you might want to do is simply get the current axes and plot in it.
So your function would look like this
function myfunction(x,y)
myaxes = gca;
plot(myaxes,x,y)
end
This would work if you only have one active figure and axes, if you have more than you mihgt want to pass the axes handle to the function.

Related

Update gramm plot matlab crashing

I have a MATLAB GUI that calls an external function to make a plot (make_ethogram_plot).
The idea would be to have an external figure that is constantly updated with the output value from the figure. Every time the data gets updated it should replot the values, it updates at ~10 Hz. I chose gramm (https://github.com/piermorel/gramm/tree/master/%40gramm) because it is really easy to make a raster plot.
This is the function that gets called. I am having issues to
1) Make it only update in the parent figure with specific name, instead of plotting in the GUI(which is the active figure).
2) Make it not crash. It would open many figures or open or close the same figure at 10 Hz until crashing.
In this configuration, it gives error because it doesn't find g after the first plot. Making g , f, and p1 globals makes it crash (opens every time it gets called)
function make_ethogram_plot(datastructure)
% if the figure doesn't exists create it
if(isempty(findobj(0, 'Name', 'My_gramm_ethogram')))
f=figure('Name', 'My_gramm_ethogram');
p1 = uipanel('Parent',f,'BackgroundColor',[1 1 1],'BorderType','none');
g = gramm('x', datastructure.final_data.frameID, 'color', categorical(datastructure.final_data.behavior));
g.geom_raster();
g.set_parent(p1);
g.draw()
else
% defining f,p1, g here (or having them global) works but crashes
% due to refresh rate
g.update()
end
end
I wrote this code to try to replicate your problem:
function animate_random_data
N = 10000;
data = [cumsum(rand(N,1)),randn(N,1)];
for ii=0:1000
% Plot the data
make_ethogram_plot(data);
drawnow
% Compute new data
data(:,1) = cumsum(rand(N,1));
data(:,2) = randn(N,1);
end
function make_ethogram_plot(data)
fig = findobj(0, 'Name', 'My_gramm_ethogram');
if(isempty(fig))
% If the figure doesn't exists create it
fig = figure('Name', 'My_gramm_ethogram');
ax = axes(fig);
plot(ax,data(:,1),data(:,2));
drawnow
set(ax,'xlimmode','manual','ylimmode','manual');
else
% If it does, update it
line = findobj(fig,'type','line');
set(line,'xdata',data(:,1));
set(line,'ydata',data(:,2));
end
Here, I followed your concept of looking for a named figure window, and creating one if it didn't exist. However, if it does exist, I simply replace the XData and YData property of the line that is already there. This is the fastest way of animating a graph, much faster than deleting the existing plot and creating a new one. After plotting, I use drawnow to update the display. I set XLimMode and YLimMode to manual to prevent re-computation of axes limits and consequent re-drawing of the axes.
The function took 17 seconds to draw all 1000 frames, meaning it's drawing about 60 frames a second. It does not (and should not) crash MATLAB.
You can limit the display rate to 20 frames/sec with drawnow limitrate. It will skip updating the display if the frames come too fast.
I don't know what the gramm/update method does, the class is too complicated to quickly see what is going on, but I dare presume it deletes the axes and creates a new plot from scratch. Not that this should crash MATLAB, it might be worth while to submit a bug report. However, you would probably want to update the figure in the more efficient way, following the method I demonstrated above.
Note that this method can be used to update any of the graphical elements in a plot. For example, I have used this method to animate images.

MATLAB Using a single figure frame for chasePlot used inside a loop

I have a while loop inside of which I have to use a plot and a chasePlot function.
The problem is, it comes up with a new window figure each time the loop runs. I somehow want a single frame which can be updated rather than each time making a new window and figure for it.
Anybody knows how to prevent a new figure in each loop so that one figure is there and that keeps on updating.
Don't use 'figure' before the 'plot' command and the code will keep overwriting every time on the same figure. You can also use the 'drawnow limitrate' command for better visualization. See an example below:
clc; close all; clear all;
x = 0 :100 :1e5;
y = zeros(size(x));
for n = 1:numel(x)
y(n) = sin(x(n));
plot(x(1:n), y(1:n));
drawnow limitrate;
end

How to retrieve data from one gui to another gui in matlab?

I have two GUIs. In the first gui I want to plot an input signal (ex: sine signal). My problem is, how can I plot back the same signal in the second GUI after I clicked the 'load' pushbutton in the second GUI? Can somebody help me? I really need help.
Here is some code to get you going about using setappdata and getappdata. This is very basic and there are things which I did not mention (eg using the handles structure or passing variables as input arguments to functions) but using setappdata and getappdata is a safe way to go.
I created 2 programmatic GUIs. The code looks a bit different than when GUIs are designed with GUIDE, but the principle is exactly the same. Take the time to examine it and understand what everything does; that's not too complicated.
Each GUI is composed of one pushbutton and an axes. In the 1st GUI (sine_signal) the sine wave is created and displayed. Pressing the pushbutton opens the 2nd GUI (gui_filtering) and calls setappdata. Once you press the pushbutton of that 2nd GUI, setappdata is called to fetch the data and plot it.
Here is the code for both GUIs. You can save them as .m files and press "run" in the sine_signal function.
1) sine_signal
function sine_signal
clear
clc
%// Create figure and uicontrols. Those will be created with GUIDE in your
%// case.
hFig_sine = figure('Position',[500 500 400 400],'Name','sine_signal');
axes('Position',[.1 .1 .8 .8]);
uicontrol('Style','push','Position',[10 370 120 20],'String','Open gui_filtering','Callback',#(s,e) Opengui_filt);
%// Create values and plot them.
xvalues = 1:100;
yvalues = sin(xvalues).*cos(xvalues);
plot(xvalues,yvalues);
%// Put the x and y values together in a single array.
AllValues = [xvalues;yvalues];
%// Use setappdata to associate "AllValues" with the root directory (0).
%// This way the variable is available from anywhere. You could also
%// associate the data with the GUI itself, using "hFig_sine" instead of "0".
setappdata(0,'AllValues',AllValues);
%// Callback of the pushbutton. In this case it is simply used to open the
%// 2nd GUI.
function Opengui_filt
gui_filtering
end
end
And
2) gui_filtering
function gui_filtering
%// Same as 1st GUI.
figure('Position',[1000 1000 400 400],'Name','sine_signal')
axes('Position',[.1 .1 .8 .8])
%// Pushbutton to load data
uicontrol('Style','push','Position',[10 370 100 20],'String','Load/plot data','Callback',#(s,e) LoadData);
%// Callback of the pushbutton
function LoadData
%// Use "getappdata" to retrieve the variable "AllValues".
AllValues = getappdata(0,'AllValues');
%// Plot the data
plot(AllValues(1,:),AllValues(2,:))
end
end
To show you the expected output, here are 3 screenshots obtained when:
1) You run the 1st GUI (sine signal):
2) After pressing the pushbutton to open the 2nd GUI:
3) After pressing the pushbutton of the 2nd GUI to load/display the data:
That's about it. Hope that helps!

How to correct the code to get the graphs of ALL functions together in one graph?

This is related to an old question of mine. I was trying to plot the graphs of the functions f_k(t)=t+k for 1<=k<=10 in the , but whenever I write the following code
syms t;
k=1;
while k<=6;
f_k(t)=k+t;
ezplot(f_k,[0,5]);
k=k+1;
end;
it runs perfectly and gives me the graph of f_6(t)=t+6 only. I checked with replacing 6 by 10 and the same thing happens. I checked the code, and couldn't detect any logical error. I also tried 1)using #(t) and function command in the while loop and 2)also using for loop, but couldn't plot because there were other errors.
a)What exactly is wrong with my code?
b)How can I fix this without minimal correction?
Each time you call ezplots, the current figure is overwritten. Call hold on so the figure is not overwritten and hold off after the code to allow overwriting again.
Further I would recommend to use a for loop instead of while.
syms t;
hold on;
for k=1:6
f_k(t)=k+t;
ezplot(f_k,[0,5]);
end
hold off

How to check if a figure is opened and how to close it?

My m-file opens figures depending on parameters. Sometimes is one figure, sometimes it opens 2 figures.
If the user call the function, the figures appear. If he calls the function again, with other parameters, I'm clearing figures with clf before the new plots.
If the second call is set to draw only one figure, the second one (opened by the previous call) remain gray (because of the clf).
Is there any way to check if it is opened and close it?
close all
Will close all open figures.
You can use findobj() to find objects that may exist by specifying search parameters. For example:
figure('name','banana')
Creates a figure with the name banana.
close(findobj('type','figure','name','orange'))
Does nothing because there are no figures open with the name orange.
close(findobj('type','figure','name','banana'))
Closes the figure.
You can specify search parameters to meet your needs.
I'm a little unclear about what you mean by "open". Figures don't really have "open" or "closed" states. They either exist or they don't. The FIGURE command will return a handle to the figure it makes:
hFig = figure(...your arguments here...);
You can also get a figure handle from the FINDOBJ function, which will find all graphics objects matching the property values you pass to it:
hFig = findobj(...your property/value pairs here...);
You can get rid of a figure with either of these commands:
close(hFig);
delete(hFig);
You can check if a figure has been closed/deleted using the function ISHANDLE:
ishandle(hFig) %# Returns 'true' if the figure exists, 'false' if it doesn't
Figures can also be "visible" or "invisible". They have a 'Visible' property that you can get or set the value of:
get(hFig,'Visible') %# Returns 'on' or 'off'
set(hFig,'Visible','off') %# Makes a figure invisible, but it still
%# exists (i.e. it's not closed)
If you're wanting to check if a figure is minimized, that may be a little more difficult. I believe there are some files that may help you with that on the MathWorks File Exchange: here's one to check out.
In MATLAB, you can GET information on the 'root'. Figures are children of 'root' (handle of root is 0) they are the only children of the root.
http://www.mathworks.com/help/techdoc/creating_plots/f7-41259.html
Knowing this, you can try this code that looks for the children of root, and gives you a list.
>> close all
>> get(0,'children')
ans =
Empty matrix: 0-by-1
>> figure(1)
>> get(0,'children')
ans =
1
>> figure(3)
>> get(0,'children')
ans =
3
1
I think you will find this the most direct way to query what figures are open.
isempty(findobj('name','Your_Figure_Name'))
if the answer is 0, then your figure is open
If inside your method, you create a figure without a 'name':
function [] = myMethod()
myFigure = figure()
end
you won't be able to access myFigure handle the next time through. So:
function [] = myMethod()
if ishandle(myFigure) % will fault, cant find variable myFigure
close(myFigure) % will fault
delete(myFigure) % will fault
end
myFigure = figure()
end
gnvoice wasn't 100% clear when he says:
You can check if a figure has been closed/deleted using the function
ISHANDLE:
He means you can only check AFTER you have recovered the handle:
function [] = createMyFigure()
recoveredHandle = findobj('type','figure', 'Name', 'myFigureName')
close(recoveredHandle)
delete(recoveredHandle)
ishandle(recoveredHandle)
myFigure = figure('Name','myFigureName') % now create figure
end
To close figure there is the "close" function. I'm still looking one to check if a figure is open.
for f=1:numel(findobj('type','figure'))
close(figure(f));
end
clear('f')