Looping over subplots and holding [duplicate] - matlab

This question already exists:
Matlab subplots in loop: only shows plots in last iteration
Closed 3 years ago.
I'm trying to create a plot and layer multiple functions over each of the subplots. The output I'm getting, however, is only showing the final plot in each iteration. In other words, all subplots are filled with something, but only with the last curve that I 'added' (or at least I thought I did) -- the cyan curve. I tried using hold onin a number of different places, to no avail. Does anyone see what the problem might be?
%% Training phase
% Setting for plots
figure;
for tai = 1:length(training_algorithms)
% Create first subplot (and make sure we stay there)
subplot(3,2,tai);
% Plot the (sampled) sine function
plot(x,y,'bx');
hold on
colors = ['r', 'm', 'c'];
for nh = 1:length(num_hid)
net = networks{tai, nh}; % Load network
net.trainParam.showWindow = false; % Don't show graph
% Train network, and time training
tic;
[net, tr] = train(net, p, t);
durations(tai)=toc;
% Simulate input on trained networks (and convert to double format)
y_result = cell2mat(sim(net, p));
% Evaluate result
[slo, int, correlations{tai}] = postregm(y_result, y);
% Add network to array
networks{tai} = net;
% Plot network approximation results
plot(x,y_result,colors(nh))
ylim([-3 3])
title(training_algorithms{tai});
end
hold off
end

It looks like this has been answered already but it is also worth noting that even though you are setting the net.trainParam.showWindow property to 'false,' Matlab may still create a new figure and make it active even though it remains hidden. Then any plots you perform after that won't stack like you want unless you make the original plot active again.
For example, if you run the below code (I stripped out all of your specific functions but recreated the affect) you will see that at the end, there are 20 or so figures open but only 1 is visible. Uncommment the line towards the bottom in order to create the kind of stacked subplots you are after... Hope this helps.
Cheers.
% Training phase
% Setting for plots
f1=figure(1);
for i = 1:6
% Create first subplot (and make sure we stay there)
subplot(3,2,i);
x=0:.1:2*pi;
y=sin(x);
% Plot the (sampled) sine function
plot(x,y,'b');
hold on
colors = {'r', 'm', 'c'};
for j=1:3
f2=figure;
set(f2,'Visible','off');
y2=sin(x+j);
% Plot network approximation results
% figure(f1) % - uncommment me
plot(x,y2,colors{j})
end
hold off
end
figHandles = findobj('Type', 'figure')

Related

Visualising fft-signal__Waterplot

This is the kind of plot i imagined myself.
https://de.mathworks.com/help/matlab/ref/waterfall.html
Ok, i don't want to explain too much, how my code works. It would take too much time. Just try the second code yourself. Take any small wav-file you can find. When you compile the code, you can see three frequency bands and see that many spectrums are plotted every 30ms. If you have a specifically question concerning my code, how it works, ask me in the comments.
I want every spectrum, at least from one frequency band, to plot it in a 3-dimensional plot. In short, what are the coordinates of the first spectrum and the 2nd, the 3rd, the 4th and so on.
My time segment on which is a fft applied, is 30 ms long. The first point on the x-axis is 30 ms, the next one 60ms and the next one 90ms and so on. What is the y-coordinate from the 30ms? This would be on the frequency axis or the y-axis. The z-axis would be the magnitude out of a frequency component at some point in time (or at a given sliding window frame). How can i do that? How do i write that? I am having big trouble with this matter. And since every explanation is in another language, it makes it much more harder for me.
As you may know, i have an audiofile (music) on which i compute a STFT. I want to visualise it. See the following explanation in my code. Read the comments!
My first idea to do this way, was using the function "mesh" or something similar.
Here is my mesh-code:
X=1:10;
Y=1:15;
Z = [];
% Here i would define the number of time segments
% See the next following code, to understand, what i mean.
for i = 1:length(X)
% Here in this line, i want to compute my short fft
%
% number of frequencies
for j = 1: length(Y)
Z(j,i) = 1.0/(i*j);
end
end
mesh(X,Y,Z)
This code plots me a mesh, i just wanted to know for myself, how this works. Anyway please be aware, that i am quite sure that i do not know, how the function "mesh" works to the fullest, but i think, i understood most of it.
Another thing i need to mention is, that i am defining frequency bands in my next following code. I did this, because i noticed, i have very high amplitudes in a range from 1 - 1000Hz, which is why, i defined 3 frequency bands. It is not necessary to plot all of them, but i want to visualise at least one. Not visualising the whole frequency range from the audio signal, but only the specificially chosen band.
%% MATLAB
%_________________________________________
[y,fs]=audioread('dontstopmenow.wav');
% audioread = Read WAV-file
% y = Vector, which contains audio signal
% fs = Sample Rate
% 'dontstopmenow' = WAV-file
%_________________________________________
%PARAMETER FOR STFT
%_________________________________________
t_seg=0.03; % Length of segment in ms
fftlen = 4096; %FFT-Points
%Defining the length of my frequency bands
f_LOW= 1:200; % contain lower frequencies
f_MEDIUM= 201:600; % contain medium frequencies
f_HIGH= 601:1000; % contain higher frequencies
%_______________________________________________________
segl =floor(t_seg*fs);
% Length of segment, on which we use the fft
% "floor" rounds off the result
windowshift=segl/2;
% size of window which goes to the next segment
window=hann(segl);
%hann function
window=window.';
% From a row vector to a column vector
si=1;
%Start index
ei=segl;
%End index
N= length(y)/windowshift - 1;
% Number of time segements in audio signal
f1=figure;
% New window
f=0:1:fftlen-1;
f=f/(fftlen-1)*fs;
% frequency vector
Ya=zeros(1,fftlen);
%Plotting time segments!
for m= 1:1:N
y_a = y(si:ei);
y_a= y_a.*window;
Ya=fft(y_a, fftlen);
Ya=abs(Ya(1:end/2));
%One-sided-spectrum
drawnow; %Updates graphical objects
figure(f1);
plot(f(1:end/2), 20*log10(Ya));
%STFT __ plots the whole audio signal after a stft, every 30ms
%% L,M,H - Bands
subplot(3,1,1)
y_low = Ya(f_LOW);
plot(f_LOW,y_low);
ylim([-20 60]);
title('Spektrum (LOW)');
xlabel('f(Hz)');
ylabel('dB');
grid on
subplot(3,1,2)
y_medium = Ya(f_MEDIUM);
plot(f_MEDIUM,y_medium);
ylim([-20 30]);
title('Spektrum (MEDIUM)');
xlabel('f(Hz)');
ylabel('dB');
grid on
subplot(3,1,3)
y_high = Ya(f_HIGH);
plot(f_HIGH,y_high);
ylim([-20 30]);
title('Spektrum (HIGH)');
xlabel('f(Hz)');
ylabel('dB');
grid on;
si=si+windowshift;
% start index updated
ei=ei+windowshift;
% end index updated
end
Here's the list of statements you could add to your code to generate the waterfall plot:
Let's store all STFT outputs in a matrix named Yb. Firstly, allocate the memory by adding this line before the for-loop.
Yb = NaN(N, fftlen/2);
Next, in the for-loop, save the fft result for each segment. This can be done by adding the following line after you have finished the computation of Ya (just before drawnow).
Yb(m,:) = Ya;
Now you're ready to generate the waterfall plot. This can be done by adding the following code after the end of the for-loop.
figure;
waterfall(f(f_LOW), (1:N)*windowshift/fs, Yb(:,f_LOW));
xlabel('Frequency (Hz)');
ylabel('Time (s)');
Hope this achieves what you want.
Following is not related to the main question: I also have the following suggestions to improve some other aspects of your code:
(1) The computation of the frequency grid f has a small scaling error. It should be:
f=f/fftlen*fs;
(2) Depending on the WAV file you use, your code may get fractional values in windowshift and N, but both of them need to be integers. So, use appropriate rounding methods while computing them. I'd suggest the following:
windowshift = round(segl/2);
N = floor(length(y)/windowshift);
(3) In the for-loop, you plot the whole fft only to overwrite that with the subplots immediately. That line should be removed.

How to remove the track of a N point matlab animation [duplicate]

This question already has answers here:
Matlab update plot with multiple data lines/curves
(2 answers)
Closed 6 years ago.
I have animated the motion of N points in 1D. The problem is that I cannot find a way to get rid of the previous plots and remove the tracks created in the motion.
function sol=Draw(N)
%N is the number of points
PointsPos=1:N
for s=1:1000
for i=1:N
PointsPos(i)=PointsPos(i)+ rand(1,1)
%The position of the point is increased.
end
for i=1:N
%loop to draw the points after changing their positions
hold on
plot(PointsPos,1,'.')
end
pause(0.005)
%here I want to delete the plots of the previous frame s
end
end
A general guideline for MATLAB procedural animation is:
Avoid creating or deleting graphical objects as much as possible in the animation loop.
Therefore, if you invoke plot image surf or delete in the animation loop, then most likely you are not doing it optimally.
Here, the best practice is to create the plot BEFORE the animation loop, then use set(plot_handle, 'XData', ...) to update the x coordinates of the plot points.
Also you should add a rand(1, N) to PointsPos, as opposed to adding rand(1, 1) N times.
So you code should look somewhat similar to the following:
function sol=Draw(N)
PointsPos=1:N
h = plot(PointsPos, ones(1, N), '.');
for s=1:1000
PointsPos=PointsPos+ rand(1,N)
set(h, 'XData', PointsPos);
pause(0.005)
end
end
If I understood your goal, then this should do what you want:
function sol = Draw(N)
steps = 1000;
% N is the number of points
PointsPos = cumsum([1:N; rand(steps-1,N)],1);
p = scatter(PointsPos(1,:),ones(N,1),[],(1:N).');
colormap lines
for s = 2:steps
p.XData = PointsPos(s,:);
drawnow
end
end
Note that:
There is no need to compute anything inside the loop, use vectorization and cumsum to calculate all the positions of the points (i.e. all the PointsPos matrix) at once.
For plotting unrelated circles, scatter would be a better choice.
Instead of using pause with some arbitrary time you can use drawnow to update your plot.

Matlab: Loop over files, plot data in one figure & add file names as legend

I have a folder with several files, each of them containing some hundreds of data pairs (resistance R over Temperature T). The files do not contain the same amount of data points...
I want Matlab to read in the files, loop over them and plot R(T) of every single file, but all in one figure. Moreover, I want the file names as legends for the different graphs (eg, the plot resulting form file 'Example1.dat' should be indicated as 'Example1.dat' in the legend).
What I am doing right now is the following:
files=dir('*.dat') % Get all input files
hold on % multiple plots in one figure
for file=files' % loop over files
[T, R] = textread(file.name,'%f %f') %get data points
xlim([8.5 10]) % set limits
ylim([-0.5 2.5]) % set limits
plot(T,R) % plot
end
legend(files.name) % add legend
What I get does not look right, because every time I try it, the same graph gets a different name in the legend. How can I fix it?
try this
files=dir('*.dat') % Get all input files
hold on % multiple plots in one figure
for filenumber=1:length(files) % loop over files
[T, R] = textread(files(filenumber).name,'%f %f') %get data points
plot(T,R) % plot
end
%limits only need to be fixed at the end
xlim([8.5 10]) % set limits
ylim([-0.5 2.5]) % set limits
legend(files.name) % add legend

Plotting measured data along with Bode plot

I am taking a circuits class and for lab we need to do a little work with MATLAB to plot some of the results. I got the following code which I used to generate a Bode plot of the transfer function for a filter we were designing. I sort of get how it works but I don't really know or use MATLAB outside of this class.
clc;
close all
s=tf('s');
w=628*1000;
H=(1/(1 + 1.85*s/w + s^2/w^2))*(1/(1 + 0.77*s/w + s^2/w^2));
figure;
bode(H)
This worked fine but now I need to plot the transfer function I measured in the lab against this data on the SAME plot axis. How can I plot both of them together. I have the lab data as a list of gain frequency pairs.
Instead of bode(H), try:
[mag,ph,w] = bode(H); % gets the data without generating the figure
plot(w, mag, 'b'); % plots only the magnitudes
freqs = data(:,1); % These 2 lines depend on how your data is formatted
gains = data(:,2); % These 2 lines depend on how your data is formatted
hold on % will add new content to the existing figure without erasing the previous content
plot(freqs, gains, 'r');
hold off
you could also try (inspired by http://www.mathworks.com/help/ident/ref/bodeplot.html) :
h = bodeplot(H);
setoptions(h,'FreqUnits','Hz','PhaseVisible','off'); % suppress the phase plot
freqs = data(:,1); % These 2 lines depend on how your data is formatted
gains = data(:,2); % These 2 lines depend on how your data is formatted
hold on % will add new content to the existing figure without erasing the previous content
plot(freqs, gains, 'r');
hold off

How to switch between subplots of different figures inside a for loop in MATLAB

Consider the following code snippet,
%% Declare figures
figure(1); % Plot Measured (y) Vs Reference(x) data for 6 cases
figure(2); % Plot Regression fit for Measured vs Reference for 6 cases
%% Run algorithm for 6 cases
for i=1:6
:
:
subplot(3,2,i);plot(x,y); % should go to figure 1
:
linearfittype = fittype({'0','x','1'});
f = fit(f,x,y);
subplot(3,2,i);plot(f,x,y); % should go to figure 2
end
How do I allocate the subplots to the appropriate figures?
If I understand correctly, it suffices to write figure(1) or figure(2) before the subplot statement.
If h is the handle or the Number property value of an existing figure, then figure(h) makes that existing figure the current figure, makes it visible, and moves it on top of all other figures on the screen. The current figure is the target for graphics output.
So:
%% Declare figures
figure(1); % Plot Measured (y) Vs Reference(x) data for 6 cases
figure(2); % Plot Regression fit for Measured vs Reference for 6 cases
%% Run algorithm for 6 cases
for i=1:6
:
:
figure(1) %// make figure 1 the current figure
subplot(3,2,i);plot(x,y); %// should go to figure 1
:
linearfittype = fittype({'0','x','1'});
f = fit(f,x,y);
figure(2) %// make figure 2 the current figure
subplot(3,2,i);plot(f,x,y); %// should go to figure 2
end