How to update xtick and xticklabel in for loop? - matlab

Imagine a = 1:1000, b = sin(a) and we want to segment this data with segment_length = 100 and plot only each segment and shift the segment with segment_length/2 in for loop. I want to plot a figure in a for loop in which xtick and xticklabel update in each loop: 1st loop is 1-100, 2nd is 51-150, 3rd is 101-200 and so on. In the following code I just plot the interested data in each loop but xtick and xticklabel do not change.
a = 1:1000;
b = sin(a);
segment_length = 100;
shift = segment_length/2;
seg_no = 1000/shift;
start = 1;
en = segment_length;
for i = 1 : seg_no-1
seg = b(start : en)
plot(seg)
start = shift + start
en = shift + en
end

note that you are not providing any information of the x-coordinates to Matlab. Thus, it must assume that your index always starts at 1. That is why they don't change.
Here is the solution
a = 1:1000;
b = sin(a);
segment_length = 100;
shift = segment_length/2;
seg_no = 1000/shift;
start = 1;
en = segment_length;
for i = 1 : seg_no-1
idx = start:en;
seg = b(idx);
plot(idx,seg)
start = shift + start;
en = shift + en;
drawnow % force matlab to draw/update the figure
pause(0.1) % / s | pause for 0.1 seconds
end
Note that I used the commands drawnow forcing Matlab to update the figure before proceeding. I also added pause() to define how long Matlab should wait to better see the updated figure.

Related

Plot graph with 2 variables in matlab

I'm planning to plot a graph of velocity against time using matlab. The change of time is 0.05 and total time 15. When time change, the graph will change and save a figure of that. I had mat file which contained all the data for time and velocity.
E.g, t=0, v=0, plot and save, t=0.05, v=1, plot and save until t=15.
I tried to use v=v+1 (which acts like i++) but failed to read the value of v in 2nd row. Any other method to do so?
Thank You.
The code is
i = 001
dt = t(2,1) - t(1,1);
k = dt*(i-1);
filename1 = 'front_data';
matFileName = sprintf('%s.mat', filename1);
matData = load(matFileName);
t = matData.time;
fv = matData.front_velocity;
fig = figure%('visible', 'off');
s = t(1,1);
fv = fv(1,1);
lot (s,fv,'*')
pic_filename = sprintf('front_data%02d.jpeg', k);
print(fig,pic_filename,'-djpeg')
istart = 002
iend = 301
for i = istart:iend
k = dt*(i-1);
t = t+dt
filename1 = 'front_data';
matFileName = sprintf('%s.mat', filename1);
matData = load(matFileName);
t = matData.time;
fv = matData.front_velocity;
v = fv(1,1);
v = v+1;
h = figure
axis([0 15 0 0.6])
plot(t,v,'*')
pic_filename = sprintf('front_data%02d.jpeg', k);
print(h,pic_filename,'-djpeg')
end
And the example I refer is the [https://www.mathworks.com/matlabcentral/answers/110632-how-to-increment-a-variable]
I reduced your example to the essential parts.
istart = 2;
iend = 301;
counter=istart;
%load data
% filename1 = 'front_data';
% matFileName = sprintf('%s.mat', filename1);
% matData = load(matFileName);
% t = matData.time;
% fv = matData.front_velocity;
%for demonstaration
t=0:.05:15;
fv=rand(size(t));
for i = istart:iend
%update
time = t(istart:counter);
values = fv(istart:counter);
%plot
plot(time,values,'*')
%increase index
counter=counter+1;
end
As you are loading always the same data in the loop you can do it once outside the loop, and for plotting you just update the length of your vector to be plotted. You could also just append the new value to the actual list.

How to find Orientation of axis of contour in matlab?

I want to find Orientation, MajorAxisLengthand MinorAxisLength of contour which is plotted with below code.
clear
[x1 , x2] = meshgrid(linspace(-10,10,100),linspace(-10,10,100));
mu = [1,3];
sigm = [2,0;0,2];
xx_size = length(mu);
tem_matrix = ones(size(x1));
x_mesh= cell(1,xx_size);
for i = 1 : xx_size
x_mesh{i} = tem_matrix * mu(i);
end
x_mesh= {x1,x2};
temp_mesh = [];
for i = 1 : xx_size
temp_mesh = [temp_mesh x_mesh{i}(:)];
end
Z = mvnpdf(temp_mesh,mu,sigm);
z_plat = reshape(Z,size(x1));
figure;contour(x1, x2, z_plat,3, 'LineWidth', 2,'color','m');
% regionprops(z_plat,'Centroid','Orientation','MajorAxisLength','MinorAxisLength');
In my opinion, I may have to use regionprops command but I don't know how to do this. I want to find direction of axis of contour and plot something like this
How can I do this task? Thanks very much for your help
Rather than trying to process the graphical output of contour, I would instead recommend using contourc to compute the ContourMatrix and then use the x/y points to estimate the major and minor axes lengths as well as the orientation (for this I used this file exchange submission)
That would look something like the following. Note that I have modified the inputs to contourc as the first two inputs should be the vector form and not the output of meshgrid.
% Compute the three contours for your data
contourmatrix = contourc(linspace(-10,10,100), linspace(-10,10,100), z_plat, 3);
% Create a "pointer" to keep track of where we are in the output
start = 1;
count = 1;
% Now loop through each contour
while start < size(contourmatrix, 2)
value = contourmatrix(1, start);
nPoints = contourmatrix(2, start);
contour_points = contourmatrix(:, start + (1:nPoints));
% Now fit an ellipse using the file exchange
ellipsedata(count) = fit_ellipse(contour_points(1,:), contour_points(2,:));
% Increment the start pointer
start = start + nPoints + 1;
count = count + 1;
end
orientations = [ellipsedata.phi];
% 0 0 0
major_length = [ellipsedata.long_axis];
% 4.7175 3.3380 2.1539
minor_length = [ellipsedata.short_axis];
% 4.7172 3.3378 2.1532
As you can see, the contours are actually basically circles and therefore the orientation is zero and the major and minor axis lengths are almost equal. The reason that they look like ellipses in your post is because your x and y axes are scaled differently. To fix this, you can call axis equal
figure;contour(x1, x2, z_plat,3, 'LineWidth', 2,'color','m');
axis equal
Thank you #Suever. It help me to do my idea.
I add some line to code:
clear
[X1 , X2] = meshgrid(linspace(-10,10,100),linspace(-10,10,100));
mu = [-1,0];
a = [3,2;1,4];
a = a * a';
sigm = a;
xx_size = length(mu);
tem_matrix = ones(size(X1));
x_mesh= cell(1,xx_size);
for i = 1 : xx_size
x_mesh{i} = tem_matrix * mu(i);
end
x_mesh= {X1,X2};
temp_mesh = [];
for i = 1 : xx_size
temp_mesh = [temp_mesh x_mesh{i}(:)];
end
Z = mvnpdf(temp_mesh,mu,sigm);
z_plat = reshape(Z,size(X1));
figure;contour(X1, X2, z_plat,3, 'LineWidth', 2,'color','m');
hold on;
% Compute the three contours for your data
contourmatrix = contourc(linspace(-10,10,100), linspace(-10,10,100), z_plat, 3);
% Create a "pointer" to keep track of where we are in the output
start = 1;
count = 1;
% Now loop through each contour
while start < size(contourmatrix, 2)
value = contourmatrix(1, start);
nPoints = contourmatrix(2, start);
contour_points = contourmatrix(:, start + (1:nPoints));
% Now fit an ellipse using the file exchange
ellipsedata(count) = fit_ellipse(contour_points(1,:), contour_points(2,:));
% Increment the start pointer
start = start + nPoints + 1;
count = count + 1;
end
orientations = [ellipsedata.phi];
major_length = [ellipsedata.long_axis];
minor_length = [ellipsedata.short_axis];
tet = orientations(1);
x1 = mu(1);
y1 = mu(2);
a = sin(tet) * sqrt(major_length(1));
b = cos(tet) * sqrt(major_length(1));
x2 = x1 + a;
y2 = y1 + b;
line([x1, x2], [y1, y2],'linewidth',2);
tet = ( pi/2 + orientations(1) );
a = sin(tet) * sqrt(minor_length(1));
b = cos(tet) * sqrt(minor_length(1));
x2 = x1 + a;
y2 = y1 + b;
line([x1, x2], [y1, y2],'linewidth',2);

Matlab - updating objects on a plot

I am trying to add a timer a simulation i am working on. At the moment i can get the timer to display in the location i want, however i cant make the numbers clear each other, i.e they all just stack on top of each other slowly creating a solid black mess. I have tried implementing a clf function but it just clears the entire figure. The code for the timer is:
HH = 0; MM = 0; SS = 0;
timer = sprintf('%02d:%02d:%02d',HH,MM,SS);
text(-450,450,timer); %% adjust location of clock in graph using the first two arguments: (x,y) coordinates
for t = 1:86400
SS = SS + 1;
if SS == 60
MM = MM + 1;
SS = 0;
end
if MM == 60
HH = HH + 1;
MM = 0;
end
timer = sprintf('%02d:%02d:%02d',HH,MM,SS); %% construct time string after all adjustments to HH, MM, SS
clf(f,'reset'); %% clear previous clock display
text(-450,450,timer); %% re-plot time to figure
if t == EventTimes(1)
uav1 = uav1.uavSetDestin([event1(2:3) 0]);
plot(event1(2),event1(3),'+')
hold on
end
if t == EventTimes(2)
uav2 = uav2.uavSetDestin([event2(2:3) 0]);
plot(event2(2),event2(3),'r+')
hold on
end
Is there a way i can reset only the timer function so it displays properly?
You want to store the handle to the text object and update the String property of this existing object rather than creating a new text object every time.
%// The first time through your loop
htext = text(-450, 450, timer);
%// Every other time through the loop
set(htext, 'String', sprintf('%02d:%02d:%02d',HH,MM,SS)
You will also want to do something similar with the plot objects rather than clearing the figure and redrawing all of the plots every iteration.
Integrating this with your code we get something like:
%// Create the initial text object
HH = 0; MM = 0; SS = 0;
timerString = sprintf('%02d:%02d:%02d',HH,MM,SS);
htext = text(-450, 450, timeString);
%// Create the plot objects
hplot1 = plot(NaN, NaN, '+');
hplot2 = plot(NaN, NaN, 'r+');
for t = 1:86400
SS = SS + 1;
%// I could help myself and made this significantly shorter
MM = MM + (mod(SS, 60) == 0);
HH = HH + (mod(MM, 60) == 0);
%// Update the timer string
timerString = sprintf('%02d:%02d:%02d',HH,MM,SS);
set(htext, 'String', timerString);
%// Update your plots depending upon which EventTimes()
if t == EventTimes(1)
uav1 = uav1.uavSetDestin([event1(2:3) 0]);
set(hplot1, 'XData', event1(2), 'YData', event1(3));
elseif t == EventTimes(2)
uav2 = uav2.uavSetDestin([event2(2:3) 0]);
set(hplot2, 'XData', event2(2), 'YData', event2(3));
end
%// Force a redraw event
drawnow;
end

Matlab plotting data with specified condition with contourf

I have data in a matrix generated in a nested for loop. I want to only plot the data that meets a certain condition (e.g. it must be bigger than 0.6). Whether or not the data point meets that condition is stored as 1 or 0 in my mlist matrix.
What is the easiest way to plot this in Matlab? For the data points that don't meet the condition, it can just be white space.
xlist = linspace(-1,1,20);
ylist = linspace(-2,2,30);
zlist = zeros(length(xlist),length(ylist));
mlist = zeros(length(xlist),length(ylist));
% iteration counter
ii = 0;
jj = 0;
for x = xlist
ii = ii + 1;
for y = ylist
z = sin(x*y);
jj = jj + 1;
zlist(jj) = z;
if z > 0.6
mlist(jj) = 1;
else
mlist(jj) = 0;
end
end
end
contourf(ylist,xlist,zlist)
mesh(ylist,xlist,zlist)
On way of "removing" data in plots in MATLAB without needing to actually remove it from your data (as you'll have problems with non-uniform grids and so on) is replacing it by NaN, as most of the MATLAB plots will treat a NaN as missing data and will not draw anything on that point.
You can change your program to not use loops as:
[x,y]=meshgrid(linspace(-1,1,20),linspace(-2,2,30));
z = sin(x.*y);
zlist(z<0.6)=NaN;
contourf(y,x,zlist); % // maybe x,y?
The easiest way, I believe, would be to limit the z-axis:
xlist = linspace(-1,1,20);
ylist = linspace(-2,2,30);
zlist = zeros(length(xlist),length(ylist));
mlist = zeros(length(xlist),length(ylist));
% iteration counter
ii = 0;
jj = 0;
for x = xlist
ii = ii + 1;
for y = ylist
z = sin(x*y);
jj = jj + 1;
zlist(jj) = z;
end
end
contourf(ylist,xlist,zlist)
mesh(ylist,xlist,zlist)
zlim([0.6,max(z)])
And for added visibility, I would consider changing the contourf and mesh calls to:
surf(ylist,xlist,zlist)

Using Heat Equation to blur images using Matlab

I am trying to use the PDE heat equation and apply it to images using Matlab. The problem i am having is that the image isn't blurring , it is just going white. Also, I am getting different results from the rest of the class who is using Maple.
Here is the code:
% George Lees Jr.
% Heat equation
clear,clc;
dx = 1;
dy = 1;
dt = .025;
%dt/(dx*dx)
t = 0;
time = 3;
T_old = imread('tulipgray.jpg');
T_temp=T_old;
[m,n,k] = size(T_temp);
%colormap gray;
%imagesc(T_temp);
%imshow(T_old);
T_new = T_temp;
T_new=ind2gray(T_new,colormap);
%T_new(:,50)=0;
%T_old(1,70)
%imagesc(T_new);
%diff_x = dt/(dx*dx)
%diff_y = dt/ (dy*dy)
%time = 0;
while t < time
for i = 2:1:m-1
for j = 2:1:n-1
T_new(i,j) = T_temp(i,j) + dt*(T_temp(i+1,j) -2*T_temp(i,j) + T_temp(i-1,j)) + dt*(T_temp(i,j+1)-2*T_temp(i,j) + T_temp(i,j-1));
t = t+dt;
T_temp(i,j) = T_new(i,j);
end
end
end
figure
imshow(T_new)
Yeah the image just gets whiter
There's 2 issues with your code:
1) you're incrementing the time counter after each individual pixel instead of after doing the whole image
2) you need to do the calculations on floating points values, not integers. dt is small, so the values from the RHS of the equation are <1
Fixed code should look something like this
clear,clc;
dt = 0.025;
time = 3;
T_old = imread('rice.png');
T_temp=double(T_old);
[m,n,k] = size(T_temp);
T_new = double(T_temp);
T_new=ind2gray(T_new,colormap);
while t < time
for i = 2:1:m-1
for j = 2:1:n-1
T_new(i,j) = T_temp(i,j) + dt*(T_temp(i+1,j) -2*T_temp(i,j) + T_temp(i-1,j)) + dt*(T_temp(i,j+1)-2*T_temp(i,j) + T_temp(i,j-1));
end
end
T_temp = T_new;
t = t+dt;
imshow(uint8(T_new))
getframe;
end