MATLAB - Update Plot with Matrix - matlab

I want to plot data, which is stored in an array. A contains three columns, each column represents a different data set. The following code works fine:
A = [0 0 0;
0 1 0];
h = plot(A)
However, a new line is appended to A and the plot shall be updated. I read that you can update plots with set and 'XData':
A = [0 0 0;
0 1 0;
1 2 0];
set(h,'XData',A)
This throws me an error: Error using set.
Value must be a column or row vector. Is there any way to refresh the data instead of a new plot? The following works just fine?
A = [0 0 0;
0 1 0;
1 2 0];
h = plot(A)

The initial code
A = [0 0 0;
0 1 0];
h = plot(A)
generates three line objects, one for each column of A (check that h has size 3×1). So you need to update each of those lines in a loop. Also, you need to update both the 'XData' and 'YData' properties:
for k = 1:numel(h)
set(h(k), 'XData', 1:size(A,1), 'YData', A(:,k))
end

You could use linkdata (https://mathworks.com/help/matlab/ref/linkdata.html):
A = [
0 0 0;
0 1 0
];
plot(A);
linkdata on;
A = [
0 0 0;
0 1 0;
1 2 0
];
Another approach deleting the plot and redrawing it immediately after:
h = plot(x,y);
% modify data...
delete(h);
h = plot(x,y);

Related

Make a one simple code from several similar code

Hello everybody I have a very simple problem, I have too many data y, p and r. So I want to calculate it in a single code.
This an example of my code if I breakdown into separate code
y1=45
y2=56
y3=67
p1=34
p2=45
p3=56
r1=23
r2=34
r3=45
Ryaw1=[cosd(y1) -sind(y1) 0;
sind(y1) cosd(y1) 0;
0 0 1]
Rpitch1=[cosd(p1) 0 sind(p1);
0 1 0;
-sind(p1) 0 cos(p1)]
Rroll1=[1 0 0;
0 cosd(r1) -sind(r1);
0 sind(r1) cosd(r1)]
R1=Ryaw1*Rpitch1*Rroll1
Coordinate1=R1*X0
Ryaw2=[cosd(y2) -sind(y2) 0;
sind(y2) cosd(y2) 0;
0 0 1]
Rpitch2=[cosd(p2) 0 sind(p2);
0 1 0;
-sind(p2) 0 cos(p2)]
Rroll2=[1 0 0;
0 cosd(r2) -sind(r2);
0 sind(r2) cosd(r2)]
R2=Ryaw2*Rpitch2*Rroll2
Coordinate2=R2*X0
Ryaw3=[cosd(y3) -sind(y3) 0;
sind(y3) cosd(y3) 0;
0 0 1]
Rpitch3=[cosd(p3) 0 sind(p3);
0 1 0;
-sind(p3) 0 cos(p3)]
Rroll3=[1 0 0;
0 cosd(r3) -sind(r3);
0 sind(r3) cosd(r3)]
R3=Ryaw3*Rpitch3*Rroll3
Coordinate3=R3*X0
Coordinate=[Cooedinate1 Coordinate2 Coordinate3]
The goals is to find "Coordinate" (in matrix - combined from Coordinate1, Coordinate2, Coordinate3, .... ,Coordinate..) from every y, p and r data with the same "X0" as a single primary data for calculation.
Sorry for my bad english,
Thanks :)
Use vectors and matrices instead of individual scalars. These are indexed in almost the same way as you had before, i.e. y1 becomes y(1).
Then you can easily loop over the code 3 times and save the repetition.
See my commented code below.
% Define some X0. This should be a column vector.
X0 = [1; 2; 3];
% Make y,p,r into 3 element vectors
y = [45 56 67];
p = [34 45 56];
r = [23 34 45];
% Make R, Ryaw, Rpitch and Rroll 3x3x3 matrices
R = zeros(3,3,3);
Ryaw = zeros(3,3,3);
Rpitch = zeros(3,3,3);
Rroll = zeros(3,3,3);
% Make Coordinate a 3x3 matrix
Coordinate = zeros(3,3);
% Loop k from 1 to 3
% For each 3x3x3 matrix, the kth 3x3 matrix is equivalent to your Ryawk, Rpitchk, Rrollk, Rk
for k = 1:3
Ryaw(:,:,k) = [cosd(y(k)) -sind(y(k)) 0
sind(y(k)) cosd(y(k)) 0
0 0 1];
Rpitch(:,:,k)= [cosd(p(k)) 0 sind(p(k))
0 1 0
-sind(p(k)) 0 cos(p(k))];
Rroll(:,:,k) = [1 0 0
0 cosd(r(k)) -sind(r(k))
0 sind(r(k)) cosd(r(k))];
R(:,:,k) = Ryaw(:,:,k)*Rpitch(:,:,k)*Rroll(:,:,k);
Coordinate(:,k) = R(:,:,k)*X0;
end
disp(Coordinate)

How do I create a plot like this grid in MATLAB?

I have data like this
-1 -1 -1 1 0 0 1 1 -1 0 1 -1 0 1
where each element of the vector is one of a several states. In this case (which is arbitrary and obviously only an example), are -1 0 1. I'm trying to make a plot like this grid:
The closest I was able to get was with a combination of spy and various tweaks:
%% ARBITRARY example data
states = [-1 0 1];
data = [-1 -1 -1 1 0 0 1 1 -1 0 1 -1 0 1];
%% Approximate plot using sparse matrix and spy
T = size(data, 2);
num_states = size(states, 2);
g = zeros(num_states, T);
for idx = 1:T
jdx = find(data(idx) == states, 1, 'first');
g(jdx, idx) = 1;
end
g = sparse(g);
%% Tweak plot
obj = figure();
obj.Color = 'white';
spy(g, 30)
s = obj.Children(1);
s.XLim = [1 T];
s.YLim = [1 num_states];
s.XLabel.String = '';
s.XGrid = 'on';
s.YTick = 1:num_states;
s.YTickLabel = num2cell(states);
s.GridLineStyle = '-';
s.YGrid = 'on';
However, this is far from ideal, since a) it's not actually a shaded grid, and b) the ticks on the y-axis are in descending order, starting from the bottom, because this is how spy functions, among other problems. How do I make a plot like this? I'm using MATLAB 2015b on a Windows 7 64-bit machine.
You'll want to play around with colours and grids, but this should be sufficient to get started:
data = [-1 -1 -1 1 0 0 1 1 -1 0 1 -1 0 1];
states = flipud(unique(data)');
im = bsxfun(#eq,data,states);
image(im);
colormap([1 1 1;0 0 0]);
axis equal;
axis tight;
set(gca,'XTick',1:length(data));
grid minor
set(gca,'YTickLabel',states);
The above results in

How to change size of grid & granularity in meshc function

Show mask by meshc function
z = [0 0 0 0;0 1 1 0;0 0 0 0];
meshc(z)
Output is:
Desired output:
There is a lot of guessing on my side, and I guess you want something like this:
%// data
z = [0 0 0 0;0 1 1 0;0 0 0 0];
%// grid
[n,m] = size(z);
[x,y] = ndgrid(1:n,1:m);
%// finer grid
[xq, yq] = ndgrid(linspace(1,n,100),linspace(1,m,100));
%// interpolation
F = griddedInterpolant(x, y, z, 'cubic')
zq = F(xq, yq);
%// interpolated plot
figure(1)
meshc(xq,yq,zq)

Why does my 3 axes system coordinate orientation change x with y values?

I am using Matlab and Euler Angles in order to reorient a 3axes coordinate system. Specifically,
Rz = [cos(ψ) sin(ψ) 0;-sin(ψ) cos(ψ) 0;0 0 1];
Ry = [cos(φ) 0 -sin(φ);0 1 0;sin(φ) 0 cos(φ)];
Rx = [1 0 0;0 cos(θ) -sin(θ);0 sin(θ) cos(θ)];
Rtotal = Rz*Ry*Rz
Then I loop through my old system coordinates (x,y,z) and make a vector coord_old. Then I get the reoriented system with (xn,yn,zn)
for i=1:size(num,1)
coord_old = [x(i,1);y(i,1);z(i,1)];
coord_new = Rtotal*coord_old;
xn(i,1) = coord_new(1,1);
yn(i,1) = coord_new(2,1);
zn(i,1) = coord_new(3,1);
end
My issue is that when θ,φ,ψ≃0 then x->-y and y->x and when θ,φ≃0 and ψ=90 then x and y will not rotate! That means that when x,y should rotate they don't and when they shouldn't rotate they stay as they were!
--EDIT--
For example, when ψ=20.0871, φ=0.0580 and θ=0.0088 I get these results
See that x->-y and y->x while z doesn't change at all!
Any thoughts?
Ok, I see two main problems here:
Rtotal = Rz*Ry*Rz is probably not what you want since Rz is multiplied twice. I think you mean Rtotal = Rz*Ry*Rx.
Your rotation matrix seems to be incorrect. Check this Wikipedia artice to get the correct signs.
Here a corrected rotation matrix:
Rz = [cos(psi) -sin(psi) 0; sin(psi) cos(psi) 0; 0 0 1];
Ry = [cos(phi) 0 sin(phi); 0 1 0; -sin(phi) 0 cos(phi)];
Rx = [1 0 0; 0 cos(theta) -sin(theta); 0 sin(theta) cos(theta)];
Rtotal = Rz*Ry*Rx;
With this matrix I get the correct results:
x=1; y=2; z=3;
psi=0; phi=0; theta=0;
[xn,yn,zn] >> 1 2 3
x=1; y=2; z=3;
psi=90/180*pi; phi=0; theta=0;
[xn,yn,zn] >> -2 1 3
And here a full graphical example of a cube in 3d-space:
% Create cube (not in origin)
DVert = [0 0 0; 0 1 0; 1 1 0; 1 0 0 ; ...
0 0 1; 0 1 1; 1 1 1; 1 0 1];
DSide = [1 2 3 4; 2 6 7 3; 4 3 7 8; ...
1 5 8 4; 1 2 6 5; 5 6 7 8];
DCol = [0 0 1; 0 0.33 1; 0 0.66 1; ...
0 1 0.33; 0 1 0.66; 0 1 1];
% Rotation angles
psi = 20 /180*pi; % Z
phi = 45 /180*pi; % Y
theta = 0 /180*pi; % X
% Rotation matrix
Rz = [cos(psi) -sin(psi) 0; sin(psi) cos(psi) 0; 0 0 1];
Ry = [cos(phi) 0 sin(phi); 0 1 0; -sin(phi) 0 cos(phi)];
Rx = [1 0 0; 0 cos(theta) -sin(theta); 0 sin(theta) cos(theta)];
Rtotal = Rz*Ry*Rz;
% Apply rotation
DVertNew = Rtotal * DVert';
% Plot cubes
figure;
patch('Faces',DSide,'Vertices',DVert,'FaceColor','flat','FaceVertexCData',DCol);
patch('Faces',DSide,'Vertices',DVertNew','FaceColor','flat','FaceVertexCData',DCol);
% Customize view
grid on;
axis equal;
view(30,30);
When I use your code and insert 0 for all angles, I get Rtotal:
Rtotal =
1 0 0
0 1 0
0 0 1
This is the identity matrix and will not change your values.
You have an error in your matrix multiplication. I think you should multiply: Rtotal*coord_old. I think you are missing the _old. depending on what is in you coordvariable, this may be the bug.
When I run:
for i=1:size(1,1)
coord_old = [1;2;3];
coord_new = Rtotal*coord_old;
xn(i,1) = coord_new(1,1);
yn(i,1) = coord_new(2,1);
zn(i,1) = coord_new(3,1);
end
I get the correct result:
coord_new =
1
2
3
Thank you both #Steffen and #Matt. Unfortunately, my reputation is not high enough to vote Up your answers!
The problem was not with Rtotal as #Matt correctly stated. It should be as it was Rz*Ry*Rx. However, both your ideas helped me test my code with simple examples (5 sets of coordinates and right hand rule), and realize where my (amateur) mistake was.
I had forgotten I had erased parts of codes where I was expressing my angles to degrees... I should be using sind & cosd instead of sin and cos.

MATLAB matrix not formatting correctly

I have some code below, and I cant seem to get the matrices formatted correctly. I have been trying to get the matrices to look more professional (close together) with \t and fprintf, but cant seem to do so. I am also having some trouble putting titles for each columns of the matrix. Any help would be much appreciated!
clear all
clc
format('bank')
% input file values %
A = [4 6 5 1 0 0 0 0 0; 7 8 4 0 1 0 0 0 0; 6 5 9 0 0 1 0 0 0; 1 0 0 0 0 0 -1 0 0; 0 1 0 0 0 0 0 -1 0; 0 0 1 0 0 0 0 0 -1];
b = [480; 600; 480; 24; 20; 25];
c = [3000 4000 4000 0 0 0 0 0 0];
% Starting xb %
xb = [1 2 3 4 5 6]
% Starting xn %
xn = [7 8 9]
cb = c(xb)
cn = c(xn)
% Get B from A %
B = A(:,xb)
% Get N from A %
N = A(:,xn)
% Calculate z %
z = ((cb*(inv(B))*A)-c)
% Calculate B^(-1) %
Binv = inv(B)
% Calculate RHS of row 0 %
RHS0 = cb*Binv*b
% Calculates A %
A = Binv*A
%STARTING Tableau%
ST = [z RHS0;A b]
for j=1:A
fprintf(1,'\tz%d',j)
end
q = 0
while q == 0
m = input('what is the index value of the ENTERING variable? ')
n = input('what is the index value of the LEAVING variable? ')
xn(xn==m)= n
xb(xb==n) = m
cb = c(xb)
cn = c(xn)
B = A(:,xb)
N = A(:,xn)
Tableuz = (c-(cb*(B^(-1))*A))
RHS0 = (cb*(B^(-1))*b)
TableuA = ((B^(-1))*A)
Tableub = ((B^(-1))*b)
CT = [Tableuz RHS0; TableuA Tableub];
disp(CT)
q = input('Is the tableau optimal? Y-1, N-0')
end
I didn't dig into what you are doing really deeply, but a few pointers:
* Put semicolons at the end of lines you don't want printing to the screen--it makes it easier to see what is happening elsewhere.
* Your for j=1:A loop only prints j. I think what you want is more like this:
for row = 1:size(A,1)
for column = 1:size(A,2)
fprintf('%10.2f', A(row,column));
end
fprintf('\n');
end
If you haven't used the Matlab debugger yet, give it a try; it makes a lot of these problems easier to spot. All you have to do to start it is to add a breakpoint to the file by clicking on the dash(-) next to the line numbers and starting the script. Quick web searches can turn up the solution very quickly too--someone else has usually already had any problem you're going to run into.
Good luck.
Try using num2str with a format argument of your desired precision. It's meant for converting matrices to strings. (note: this is different than mat2str which serializes matrices so they can be deserialized with eval)