Interactive plot for classifying data - matlab

I am working with 3 matrices (Data1, Data2, Data3) where each row from each of the 3 matrices is a signal from the same time. I am attempting to have an interactive UI where the user can click if there's an abnormally or not. The code should record the answer from the toggle switch and plot the next 3 graphs until there's no more data.
I have two main issues:
When pressing the toggle button, it will stay toggled until pressed again to untoggle before pressing the next answer. It should untoggle--
The recorded answer 'Result' gets erased on every iteration and I am not sure why!
Results = table();
for ii = 1:10
pushbuttonPlot(Data1,Data2,Data3,ii)
waitforbuttonpress
end
The function is as follows:
function Results = pushbuttonPlot(Data1,Data2,Data3,ii)
f = figure(1);
c = uicontrol('Position',[10 60 60 22]); %left, bottom, width, height
c.String = 'JOINT!!';
c.Callback = #plotJointNext;
c2 = uicontrol('Position',[11+140 60 60 22]);
c2.String = 'NoJOINT!!';
c2.Callback = #plotNoJointNext;
waitforbuttonpress
Results =
function plotJointNext(src,event)
figure(1)
subplot(3,1,1)
ylabel('Height (mm)')
plot(Data1((ii),:))
title(['AOI 1, Index # ',num2str((ii))])
xlabel('Data Points (px)')
subplot(3,1,2)
plot(Data2((ii),:))
ylabel('Height (mm)')
title(['AOI 2, Index # ',num2str((ii))])
xlabel('Data Points (px)')
subplot(3,1,3)
plot(Data3((ii),:))
ylabel('Height (mm)')
title(['AOI 3, Index # ',num2str((ii))])
xlabel('Data Points (px)')
temp = 1 ;
Results = [Results ; temp];
end
function plotNoJointNext(src,event)
figure(1)
subplot(3,1,1)
ylabel('Height (mm)')
plot(Data1((ii),:))
title(['AOI 1, Index # ',num2str((ii))])
xlabel('Data Points (px)')
subplot(3,1,2)
plot(Data2((ii),:))
ylabel('Height (mm)')
title(['AOI 2, Index # ',num2str((ii))])
xlabel('Data Points (px)')
subplot(3,1,3)
plot(Data3((ii),:))
ylabel('Height (mm)')
title(['AOI 3, Index # ',num2str((ii))])
xlabel('Data Points (px)')
temp = 0 ;
Results = [Results ; temp];
end
end

I could not get the code working the way I wanted it to work so I made the following adjustments: the function has a ii=ii+1, so I avoid running the main function inside of the for loop. This helped as the waitforkey was not allowing for the uibutton to untoggle. The second thing is I created a global variable Results that kept count of all the times a certain button was pressed. There's probably better ways to do this but this is how I did it.

Related

How to make animation in MATLAB which the curve is moving, not axes is moving?

I want to plot y=omega*x^2, which omega is -3 into 3 with step size 0.25, x from -4 into 4 with step size 0.001. But this code give me the curve is cannot moving and axes is moving. I want the curve is moving, like this.
x=-4:0.001:4;
for omega=-3:0.25:3
for i=1:length(x)
y(i)=omega*x(i)^2;
end
plot(x,y);
pause(0.1);
end
How to do that?
As another answer has indicated, you need to set the axis limits.
(Also note that there is no reason to calculate y using a loop.)
But instead of using plot every time through the loop it's more efficient to create the line only once, and then replace the x and y data of the line each time through the loop.
x=-4:0.001:4;
all_omega=-3:0.25:3;
for idx = 1:numel(all_omega)
omega = all_omega(idx);
y=omega*(x.^2);
if idx == 1
% create line
hl = plot(x,y);
axis([-4,4,-40,40]);
box on
grid on
else
% replace line data
set(hl,'XData',x,'YData',y);
end
title(sprintf('\\Omega = %.2f',omega));
pause(0.1);
end
Or you might want to use animatedline,
x=-4:0.001:4;
all_omega=-3:0.25:3;
for idx = 1:numel(all_omega)
omega = all_omega(idx);
y=omega*(x.^2);
if idx == 1
% create animated line
am = animatedline(x,y);
axis([-4,4,-40,40]);
box on
grid on
else
% replace the line
clearpoints(am)
addpoints(am,x,y);
end
title(sprintf('\\Omega = %.2f',omega));
pause(0.1);
end
A quick method is setting the x- and y-axes limits in the loop after each plot, using the axis([xmin, xmax, ymin, ymax]) command. This method isn't foolproof, in the case that the script gets help up after plotting but before setting the axes limits, but in most cases it should work.
figure(1)
x=-4:0.001:4;
for omega=-3:0.25:3
for i=1:length(x)
y(i)=omega*x(i)^2;
end
plot(x,y);
axis([-4 4 -50 50])
pause(0.1);
end
This is the same as #phil-goddard's answer, but makes more efficient use of handles to the animated YData and title string.
x = -4 : 0.001 : 4;
y = zeros(1, numel(x));
omega_range = -3 : 0.25 : 3;
% Create line and title, and obtain handles to them.
h_plot = plot(x, y);
axis([-4, 4, -40, 40]);
box on;
grid on;
h_title = title(sprintf('\\omega = %.2f', 0));
for idx = 1:numel(omega_range)
omega = omega_range(idx);
y = omega * (x.^2);
% Replace y data.
h_plot.YData = y;
% Replace title string.
h_title.String = sprintf('\\omega = %.2f', omega);
pause(0.1);
end

delete a line in a for loop with MATLAB

i'm struggling with this matter probably
i'm just starting with Matlab.this is my code,i
wanna rotate a two links arm,using rotation matrix:
clear all
close all
clc
myaxes = axes('Xlim',[-1 1 ],'Ylim',[-1 1],'Zlim',[-1 1]);
view(3);
grid on;
axis equal;
hold on
xlabel('X')
ylabel('y')
zlabel('Z')
P_0 = [0; 0; 0] ;
P_1 = [-0.5;0; 0] ;
P_2 = [-1; 0; 0] ;
alfa_1 = 0:1:30 ;
alfa_2 =(0:0.5:15) ;
for i = 1:length(alfa_1)
M3(:,:,i) = [cosd(alfa_1(i)) -sind(alfa_1(i)) 0
sind(alfa_1(i)) cosd(alfa_1(i)) 0
0 0 1] ;
P_1(:,i,i) = M3(:,:,i)*[-0.5;0; 0] ;
P_2(:,i,i) = M3(:,:,i)*[-1;0; 0];
figure(1)
line([0 P_1(1,i,i)],[0 P_1(2,i,i)],[0 P_1(3,i,i)]);
scatter(P_1(1,i,i),P_1(2,i,i));
hold on
M3_1(:,:,i) = [cosd(alfa_2(i)) -sind(alfa_2(i)) 0
sind(alfa_2(i)) cosd(alfa_2(i)) 0
0 0 1] ;
P_2_2(:,i,i) = M3_1(:,:,i)*P_2(:,i,i);
line([P_1(1,i,i) P_2_2(1,i,i)],[P_1(2,i,i) P_2_2(2,i,i)],[P_1(3,i,i) P_2_2(3,i,i)],'color','r');
scatter(P_2_2(1,i,i), P_2_2(2,i,i))
hold on
end
should i use delete function to obtain an animation without plotting
all the lines but only the current line?!?.
thanks in advance for your help and support.
You can use the drawnow function in MATLAB for this purpose. This function can be used inside a for loop to force a plot to be rendered every iteration, instead of being stored in a buffer until after the loop.
Update figure window and execute pending callbacks
An example: for a simpler code consider a object moves on circle
t = 0:0.05:2*pi;
x = cos(t);
y = sin(t);
for k=1:length(t)
plot(x(k),y(k),'ko')
axis([-1.2 1.2 -1.2 1.2])
axis square
drawnow
end
Please note the axis function in this method. If the axis lines are deleted from the code then, in every iteration, the axis limits will change and the animation is not smooth.
What about your code:
clear all
close all
clc
view(3);
xlabel('X');
ylabel('y');
zlabel('Z');
P_0 = [0; 0; 0] ;
P_1 = [-0.5;0; 0] ;
P_2 = [-1; 0; 0] ;
alfa_1 = 0:1:30 ;
alfa_2 = (0:0.5:15) ;
for i = 1:length(alfa_1)
% Calculate new values for plotting
M3(:,:,i) = [cosd(alfa_1(i)), -sind(alfa_1(i)), 0
sind(alfa_1(i)), cosd(alfa_1(i)), 0
0 , 0 , 1] ;
P_1(:,i,i) = M3(:,:,i)*[-0.5; 0; 0] ;
P_2(:,i,i) = M3(:,:,i)*[-1; 0; 0] ;
% Clear figure 1 and hold for all plots
figure(1)
clf
% Hold only needs to be applied around plots on same axes
hold on
line([0 P_1(1,i,i)],[0 P_1(2,i,i)],[0 P_1(3,i,i)]);
scatter(P_1(1,i,i),P_1(2,i,i));
% Recalculate plotting values
M3_1(:,:,i) = [cosd(alfa_2(i)), -sind(alfa_2(i)), 0
sind(alfa_2(i)), cosd(alfa_2(i)), 0
0 , 0 , 1] ;
P_2_2(:,i,i) = M3_1(:,:,i)*P_2(:,i,i);
line([P_1(1,i,i) P_2_2(1,i,i)], [P_1(2,i,i) P_2_2(2,i,i)], [P_1(3,i,i) P_2_2(3,i,i)], 'color', 'r');
scatter(P_2_2(1,i,i), P_2_2(2,i,i))
% Set axis limits for consistency in all plots, show grid
axis([-2 2 -2 2])
grid on
% Hold off is good practice to avoid later accidental plotting on same axes
hold off
% Draw from the buffer
drawnow
end
you can save(if you want) this animation with getFrame function and play it with movie function
and another function may helps you is comet.

MATLAB can't save each axes mouse-clicks on subplot using ButtonDownFcn

I have a 3x1 subplot, and I have figured out how to capture the mouse-click coordinates and store them into an array within each axes. However, I'd like to modify my code so that I am able to store the mouse clicks from each axes all in one go around.
Here is my code:
function Callbacks
x = 0:30;
y1 = 1.5*cos(x);
y2 = 1.5*cos(x)*10;
y3 = 1.5*cos(x)*100;
subplot(3,1,1)
plot(x,y1,'ButtonDownFcn',{#lineCallBack,'plot1'})
subplot(3,1,2)
plot(x,y2,'ButtonDownFcn',{#lineCallBack,'plot2'})
subplot(3,1,3)
plot(x,y3,'ButtonDownFcn',{#lineCallBack,'plot3'})
end
function lineCallBack(src,evt,tag_name)
src.Tag = tag_name;
N=2;
P1array = zeros(N,2);
P2array = zeros(N,2);
P3array = zeros(N,2);
for k = 1:N
if strcmp(tag_name,'plot1')
[P1array(k,1),P1array(k,2)] = ginput(1);
hold on;
plot(P1array(k,1),P1array(k,2),'*r')
elseif strcmp(tag_name,'plot2')
[P2array(k,1),P2array(k,2)] = ginput(1);
hold on;
plot(P2array(k,1),P2array(k,2),'*r')
elseif strcmp(tag_name,'plot3')
[P3array(k,1),P3array(k,2)] = ginput(1);
hold on;
plot(P3array(k,1),P3array(k,2),'*r')
end
end
OUTPUT
P1array =
1 2
3 4
P2array =
0 0
0 0
P3array =
0 0
0 0
As shown on the output above, after clicking through, it seems to only capture the coordinates for the last axes I clicked on. I'd like to be able to have values for all the axes points. Can anyone help? Thanks.

Finite Element - Plotting with stresses in triangle mesh

I'm making program where I need to plot some area which has been split up in many triangles. I have calculated strains in each node / each corner of the triangle. Now I need to plot the triangle with the strains.
Now I have three ways of plotting the triangles. But in one of them I fill each triangle with the average of it's corners strains. What I want to do is...
Put the strain on the corner and get a plot that looks like contour or contourf. - I don't really understand how they work.
Can anyone help me?
clear; clc;
TC = [ 1 2 3 ; 2 3 4 ] ; % Triangles node Connection.
NC = [ 0,0 ; 0,1 ; 1,0 ; 1,1 ] ; % Node Coordinates.
strain = [ 300 , 400 , 500 ; 400 , 500 , 600]; % Strains in each node.;
[ne,np] = size(TC); % Just finding how many elements.
element = zeros([3 2 ne]); % Creating a matrix for each element.
% My first and second plot...
for i=1:ne
no1 = TC(i,1); no2 = TC(i,2); no3 = TC(i,3);
element(:,:,i) = [ NC(no1,1),NC(no1,2);
NC(no2,1),NC(no2,2);
NC(no3,1),NC(no3,2);]; % Defining each element for each loop.
% Node 1 Node 2 Node 3
xe = [element(1,1,i),element(2,1,i),element(3,1,i)]; % Defining coordinates to plot.
ye = [element(1,2,i),element(2,2,i),element(3,2,i)];
subplot(3,1,1)
plot([xe, xe(1)],[ye, ye(1)]) % ATTEMPT ONE % Only plotting the triangles. Using first value also last to close the triangle.
xlim([-1 2]); ylim([-1 2])
hold on
subplot(3,1,2)
fill(xe,ye,mean(strain(i,:))) % ATTEMPT TWO % Fill triangles with average strain.
hold on
xlim([-1 2]); ylim([-1 2])
end
% ATTEMPT 3
subplot(3,1,3)
TR = triangulation(TC,NC);
triplot(TR)
hold on
xlim([-1 2]); ylim([-1 2])
Thanks in advance.
You can use the fill function to get the shading that you desire. With a little bit of customization for your application I believe the following code will work, although some vectorization may be in order if the for loop slows your program too much.
X = zeros(3,size(TC,1));
Y = zeros(3,size(TC,1));
C = zeros(3,size(TC,1));
for i = 1:size(TC,1) % for all triangle connection definitions
for j = 1:3 % for all nodes in a triangle
X(j,i) = NC(TC(i,j),1)'; % format X points
Y(j,i) = NC(TC(i,j),2)'; % format Y points
C(:,i) = strain(i,:)'; % format color based on strain value
end
end
fill(X,Y,C)
The result:
You may want to check this documentation for further details on how X,Y and C are interpreted

Moving Window in Matlab

I'm looking to use Matlab to run through a set of data, 5446100 x 6 called xdata1.
I'm looking it to plot the first 100 data points, and after this to run through each point individually.
To start I have:
for i=1:100
NOC1 = CPMD_PCA(xdata1(99+i,:);
How would I then get this to carry on continuously, other than writing out i=2:101, i=3:102 etc
I am not sure about what CPMD_PCA is doing so I'll show you how to plot a moving windows on a simple matlab plot, on a sample data set.
You'll have to adjust the code to your exact application.
%% // just to create a sample set
x = ( 0:pi/10:150*pi ).' ; %//'
y = cos(x).*cos(3*x)+cos(x./4) ;
xdata = [y , -y/2] ;
%% // adjust moving window size and compute other useful parameters
window_size = 100 ; %// the length (in points) of the moving window
nPts = size(y,1) ; %// number of points in a column
n_windows = nPts-window_size ; %// the total number of windows
%% // Do the initial plot (not moving yet) of the first 100 points
idx = 1:window_size ;
hp = plot( xdata( idx , 1) ) ;
%% // Move the plot by one point at each iteration of the loop
for iwin =1:n_windows
idx = idx + 1 ;
set( hp , 'YData' , xdata(idx,1) )
drawnow %// you can comment that line (try with and without)
pause(0.1) %// adjust the timing to your needs
end
To answer you question directly you can wrap your current code in another loop:
for outer_loop_index = 1 : (size(xdata1,1) - 100)
for inner_loop_index = outer_loop_index : outer_loop_index + 99
NOC1 = CPMD_PCA(xdata1(inner_loop_index,:);
end
end