I have a matrix a and I want to add pictures from my computer to certain cells whenever I display pcolor. I want to add pictures where the ones are. How would I go about that if the picture is in the same directory as the matlab file?
code:
a=[
1 0 0;
1 1 0;
0 0 0];
b=[NaN NaN NaN];
a = [a;b];
b = [b NaN];
b = b.';
a = [a b];
Cmap = [1 1 1];
colormap(Cmap);
pcolor(a)
I also have been noticing with pcolor that it shifts the matrix by 180 degrees, why is it that so?
This is the pcolor plot that I get:
I need something like this:
Here you see the image within pcolor cells, how can I accomplish this?
I will answer my own question this was what I did. I hope this can also help others.
a=[
1 0 0 0;
1 1 0 0;
0 0 0 0;
0 0 0 0];
aa = a;
ac = aa;
b=[NaN NaN NaN NaN];
a = [a;b];
b = [b NaN];
b = b.';
a = [a b];
I = imread('redirt.jpg');
J = imresize(I, 3, 'nearest');
[x , y] = size(aa);
delete(findall(gcf,'Tag','8puzzle'))
pos=get(gca,'position'); % getting the position
% calculating position
width=pos(3)/(y);
height =pos(4)/(x);
Cmap = [1 1 1];
colormap(Cmap);
pcolor(a)
axis off
% loop over the positions/cells you want to place image
for i=1:x
for j=1:y
if(aa(i,j) == 1)
% image position
axes('pos',[pos(1)+width*(i-1),pos(1)+height*(j-1),width,height], 'Tag','8puzzle');
% Show image
imshow(J)
end
if (i == 4 && j == 4)
axes('pos',[pos(1)+width*(i-1),pos(1)+height*(j-1),width,height], 'Tag','8puzzle');
% Show image
imshow('vacum.jpg')
end
end
end
set(gca, 'Ydir', 'reverse');
The image overlaps the cells just a little however, it is does not interfere with the display.
Related
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);
i want to patch points to obtain a square and do it for all other points on the axis, but i want to do it in a for loop.. Thereafter, i would apply some transformation properties to the patched points. This is what i have done so far. Any help will be well appreciated.
whitebg('g')
axis on
% first patch point on the axis
pts2 = [0 0 1 1 0;0 1 1 0 0];
% last patch point on the axis
pts3 = [29 29 30 30 29;29 30 30 29 29];
[n m] = size(pts2);
[o p] = size(pts3);
axis([0 30 0 30])
shg
theta=0;
dx=0;
dy=0;
d=patch(pts1(1,1:end),pts1(2,1:end),'b*-');
for pts1 = pts2:pts3
if (d==patch(pts1(1,1:end),pts1(2,1:end),'b*-'))
delete(d)
end
%function to process
rot = [cosd(theta) sind(theta);-sind(theta) cosd(theta)];
trans = [1 0 dx;0 1 dy; 0 0 1];
homogeneous_rot = eye(3);
homogeneous_rot(1:2,1:2) = rot;
homogeneous_pts1 = [pts1; ones(1,5)];
trans_pts1 = trans*homogeneous_rot*homogeneous_pts1;
hold off
f=patch(trans_pts1(1,1:end),trans_pts1(2,1:end),'r*-');
draw now
end
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)
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.
Let's say, I have a matrix (by imread) as following:
A = [0 0 1 0 0;
0 0 1 0 0;
0 1 1 1 0;
0 0 1 0 0;
0 0 0 0 0];
I would like to get the bounding box of non-zero elements as
BB = show_me_the_bounding_box(A);
BB = [1, 2, 4, 4]; % y0, x0, y1, x0
What function I should use to do that?
Use REGIONPROPS
stats = regionprops(A,'BoundingBox');
BB = stats.BoundingBox;
To get the result you want, please use:
[y,x] = ind2sub(size(A), find(A))
coord = [y, x]
[min(coord) max(coord)] % [1 2 4 4]
Note however that, with the correct conventions, the bounding box is:
[y,x] = ind2sub(size(A), find(A))
coord = [x, y]
mc = min(coord)-0.5
Mc = max(coord)+0.5
[mc Mc-mc] % [1.5 0.5 3 4]
which yields the same result as:
stats = regionprops(A, 'BoundingBox')
BB = stats.BoundingBox % [1.5 0.5 3 4]
The code can easily be adapted to 3D images, by using:
[y,x,z] = ind2sub(size(A), find(A));
coord = [x, y, z];
mc = min(coord)-0.5;
Mc = max(coord)+0.5;
[mc Mc-mc]