Append figure with new plots - matlab

I want to visualize two sets of data in different figures. Here is how do I realize it now:
f1 = figure;
for i=0:6
plot(stim(i)+i);
hold on;
end;
f2 = figure;
for i=0:6
plot(data(i)+i);
hold on;
end;
I think there have to be the way to combine these loops.

Sure. As per Matlab reference: first you create empty figures and do the hold-on (you don't need to do it every time):
f1 = figure;
hold on
f2 = figure;
hold on
Then you loop:
for i=0:6
figure(f1)
plot(stim(i)+i);
figure(f2)
plot(data(i)+i);
end
This time the figures are already created; calling figure here therefore switches the active figure so you can plot on it;

And without for loops, something like this:
idx = (0:6).';
figure(f1);
plot(stim(idx)+idx);
figure(f2);
plot(data(idx)+idx);
Make sure that you apply the solution to the right dimension. The column vectors are interpreted as one dataset; And for points, remember to set the markers.

Related

Handling and eliminating multiples entries in MatLab legend

I currently want to have the legend of graph, however i'm plotting several lines that should be group in only 3 types.
My currently option is to use a dummy plot out of the boundaries, plotting the relevant data and calling the legend just at the end. It works but it is prone to errors. I wanted to update the legend and select just a few of the plots.
I tried to use the leg_handle.String, but then it comes two problems:
It still plot 5 handles instead of 3.
It does not have the proper line style & color.
Any ideas?
Bellow follow the code (with dummy plot commented) and the pictures of the current version giving the error and what i want to look.
clear
figure()
hold on
%using
%dummy plot
% leg_text={'a','b','c'};
% plot(100,100,'-r')
% plot(100,100,'-b')
% plot(100,100,'-k')
for ii=1:20,
plot(1:11,linspace(0,ii,11),'-r')
end
for ii=30:50,
plot(1:11,linspace(0,ii,11),'-b')
end
for ii=70:80,
plot(1:11,linspace(ii,25,11),'-k')
end
Yaxl=[-1 80];
Xaxl=[1 11];
set(gca, 'Visible','on', ...
'Box','on', ...
'Layer','top',...
'Xlim',Xaxl, ...
'Ylim',Yaxl);
%using
% legend(leg_text)
%want to use
leg_hand=legend(gca,'show');
leg_hand.String=leg_hand.String([1 21 42]);
%extra comand will give the things that i wanted above
% leg_hand.String=leg_hand.String([1 2 3]);
What it gives:
What I expect to have:
I have tried this method using [a,b,c,d]=legend, but this give only the a handle that i already using.
This little workaround should do the job:
clear();
figure();
hold on;
h = gobjects(3,1);
for ii = 1:20
h(1) = plot(1:11,linspace(0,ii,11),'-r');
end
for ii = 30:50
h(2) = plot(1:11,linspace(0,ii,11),'-b');
end
for ii = 70:80
h(3) = plot(1:11,linspace(ii,25,11),'-k');
end
set(gca,'Box','on','Layer','top','Visible','on','Xlim',[1 11],'Ylim',[-1 80]);
legend(h,'A','B','C');
hold off;
Actually, what I did is very simple. I created an array of graphical objects of size 3 (one for each iteration) using the gobjects function. Then, inside each iteration, I assigned the last plotted line to its respective array placeholder. Finally, I created the legend using the three graphical objects I previously stored.
Alternatively:
clear();
figure();
hold on;
h1 = gobjects(20,1);
for ii = 1:20
h1(ii) = plot(1:11,linspace(0,ii,11),'-r');
end
h2 = gobjects(21,1);
for ii = 30:50
h2(ii-29) = plot(1:11,linspace(0,ii,11),'-b');
end
h3 = gobjects(11,1);
for ii = 70:80
h3(ii-69) = plot(1:11,linspace(ii,25,11),'-k');
end
set(gca,'Box','on','Layer','top','Visible','on','Xlim',[1 11],'Ylim',[-1 80]);
legend([h1(1) h2(1) h3(1)],'A','B','C');
hold off;
You create an array of graphical objects for storing the plot handlers produced by every iteration. Then you create the legend using the first (basically, any) item of each array of graphical objects.

How to connect points on a Matlab plot?

I wrote the code to get the relationship between the two variables. The code is as follows:
for fn=0.1:0.1:10
for Qe= [0.1,0.5, 1, 5]
fn2=fn.*fn;
Mg=abs((Ln*fn2)/(((Ln+1)*(fn2)-1)+1i*(((fn2)-1).*fn.*Qe*Ln)));
semilogx(fn,Mg,'b','linewidth',7);
hold on;
save;
end
end
However, The curves I got are scatters points. I want to get all points to be connected. When I increase the step point for fn, i.e fn=0.1:0.001:10, it is better, but it takes a very long time.
Your problem is that you plot a single point every iteration. Let the loops run their course, save the points as vectors, then call a single plot at the end plotting the vectors, which will automatically generate connected lines.
fn=0.1:0.1:10
Qe= [0.1,0.5, 1, 5]
Mg = zeros(numel(fn),numel(Qe)); %initialise output
for ii=1:numel(fn)
fn2=fn(ii)^2;
for jj = 1:numel(Qe)
Mg(ii,jj)=abs((Ln*fn2)/(((Ln+1)*(fn2)-1)+1i*(((fn2)-1).*fn(ii).*Qe(jj)*Ln))); %save in matrix form
end
end
figure
hold on;
semilogx(fn,Mg(:,1),'b','linewidth',7); % Generate plots with different colours
semilogx(fn,Mg(:,2),'r','linewidth',7);
semilogx(fn,Mg(:,3),'y','linewidth',7);
semilogx(fn,Mg(:,4),'g','linewidth',7);
I could solve it using this code. It could solve the problem, however, it is a little bit slow (
%%Parameters%%
Ln=8;
Mgmin=0.88;
Mgmax=1.18;
Qe= [0.25,0.3,0.35,0.7,1.65,4,8];
c= {'b','m','r','g','y','c','k'};
%%Gain Vs Frequecny Function%%
fn=0.1:0.001:10;
fn2=fn.*fn;
%%Gain Curve%%
figure;
for j=1:7
for i=1:9901
Mg(i)=abs((Ln*(fn2(i)))/(((Ln+1)*(fn2(i))-1)+1i*(((fn2(i))-1).*fn(i).*Qe(j)*Ln)));
end;
semilogx(fn,Mg,c{j},'linewidth',3);
hold on;
plot(fn,Mgmax,'k');
hold on;
plot(fn,Mgmin,'k');
save;
end;

how can i combine these 3 matlab graphs to a single one?

hello i have these three polar plots:
polar(a,(V1).^(-1),'-r')
polar(a,(V2).^(-1),'-g')
polar(a,(V3).^(-1),'-m')
where V1,V2,V3 are matrices , how can i combine these 3 graphs to a single one (not like subplot , more like copyobj)?
Note: The axes remain the same in every graph.
Thank you
You can use hold on as you would for any other types of graphs.
Example:
clear
clc
close all
figure;
theta1 = 0:0.01:2*pi;
rho1 = sin(2*theta1).*cos(2*theta1);
theta2 = 0:0.1:2*pi;
rho2 = cos(2*theta2).*cos(2*theta2);
theta3 = 0:0.1:2*pi;
rho3 = cos(2*theta2).*tan(2*theta2);
polar(theta1,rho1,'--r')
hold on
polar(theta2,rho2,'-b')
polar(theta3,rho3,'-g')
output:
Use hold on. It will "hold" every plot you make and put the others on top. If you want to stop holdin, then hold off.
thanks guys, solved it with:
figure;
b=polar(a,(V3).^(-1),'-m')
hold on
c=polar(a,(V2).^(-1),'-g')
hold on
a=polar(a,(V1).^(-1),'-r')
hold off;
for some reason when i change the series that i write the polars (for example a,b,c) the method doesn't work... But now it's ok, so never mind :)

How to arrange multiple figures in an array of subplots while keeping all properties?

Imagine I have function myPlot which creates a simple plot and returns figure and axes handle:
function [ fig_handle, axes_handle ] = myPlot( myTitle )
x = linspace(-10,10,100);
y = x.^2;
fig_handle = figure;
plot(x,y,'Color','b')
ylim([0,42]); xlim([-42/10,42/10]);
ylabel('y'); xlabel('x');
title(myTitle);
grid on;
axes_handle = gca;
end
Now I want to call that function multiple times with different input parameters and concatenate them into an array of subplots. The solution I came up with is
[f1,a1] = myPlot('Plot #1');
[f2,a2] = myPlot('Plot #2');
figure(3)
s221 = subplot(211);
s222 = subplot(212);
copyobj(get(a1,'children'),s221)
copyobj(get(a2,'children'),s222)
it gives me
so the new 2-part plot does not keep any property of the two plots before. Of course I am aware that I can just do:
set(s221,'Ylabel',get(a1,'Ylabel'))
with all properties. But I try to avoid this. Is there something easier I am missing?
Another workaround is to copy the full axes object (so all the properties come along) into a new figure. The only property you have left to set yourself is the position according to the rules of subplot(xyz).
To start with your example :
[f1,a1] = myPlot('Plot #1');
[f2,a2] = myPlot('Plot #2');
Then copy the axis of each figure into the new figure
h4 = figure(4)
copyobj(get(f1,'children'),h4)
copyobj(get(f2,'children'),h4)
They are both here, but they are still superimposed. You just have to reposition them now.
For a quick workaround I use an intermediate figure to let subplot calculate the position for me but these positions (axes arrangement) could probably be calculated by yourself with a helper function (rip some code from subplot.m if you need).
%// Just to get some position calculated for me
figure(3)
s221 = subplot(211);
s222 = subplot(212);
Then I apply the positions to axes in the figure:
hl = flipud( get(h4,'Children') ) ;
set( hl(1),'Position', get(s221,'Position') )
set( hl(2),'Position', get(s222,'Position') )
Just be careful, the axes/children list is upside down (so the use of the flipud function), but if you put that in a loop, you could just run the loop backward.
Edit
If you are going to discard the original figure (f1 and f2), then you can also simply move the axes to the new figure (instead of copying them) by assigning the Parent property of the axes, then close the figure (to keep things tidy). Just use :
set(a1,'Parent',h4) ; close(f1)
set(a2,'Parent',h4) ; close(f2)
instead of the 2 lines with copyobj. The rest of the solution is identical. Not sure if there is a performance gain by moving an object instead of replicating it (Matlab may do a copy in the background anyway ... or not) but if it involve many figures with heavy data sets it may at least save some memory during the process.
One possible workaround could be the following, not really generic though. Would be interested in a solution solving the original problem.
If it is possible to modify the myPlot function one could pass the figure handle and subplot specifier and plot everything correctly from the beginning.
function [ fig_handle, axes_handle ] = myPlot(fig_handle, sub, myTitle )
figure(fig_handle); subplot(sub)
....
end
called by
f = figure(3);
[f,a1] = myPlot(f, 221,'Plot #1');
[f,a2] = myPlot(f, 222,'Plot #2');

Legend in Matlab Graph

I need to produce a X vs Y graph and make a distinction between positive class and negative class (indicated in original data infile). How do I produce a legend in such a graph? This is my code for the graph right now :
infile = fopen('ClassData1.txt','r');
data = textscan(infile,'%f %f %f');
parameters = [data{1} data{2}];
label = [data{3}];
h = ones(100,9);
g = ones(100,9);
score1= ones(1,9);
sc = 0;
figure
for i = 1:100
if label(i)>0
plot(parameters(i,1),parameters(i,2),'r*')
hold on
else
plot(parameters(i,1),parameters(i,2),'b*')
end
end
To show each line type only once, you have to keep the handles. Storing only one handle per class is sufficient.
h=nan(2,1)
for i = 1:100
if label(i)>0
h(1)=plot(parameters(i,1),parameters(i,2),'r*')
hold on
else
h(2)=plot(parameters(i,1),parameters(i,2),'b*')
end
end
legend(h)
There are (more than) two ways to do this. Firstly, you can just use a single plot command and do the legend normally, by combining the plot definitions using logical indexing, or you can use the DisplayName property for each plot to give information about the legend.
% Some sample data
parameters=rand(100,2);
label=parameters(:,1)-0.5;
% Use logical indexing to replace the for loop and use a single plot command
figure(1)
plot(parameters(label>0,1),parameters(label>0,2),'r*',parameters(label<=0,1),parameters(label<=0,2),'b*')
legend('red','blue')
% Use DisplayName to set the legend entry for each plot, then show the legend using the names given
figure(2)
plot(parameters(label>0,1),parameters(label>0,2),'r*','DisplayName','Red')
hold on
plot(parameters(label<=0,1),parameters(label<=0,2),'b*','DisplayName','Blue')
hold off
legend('show')