Error in longitude contour near the pole MATLAB - matlab

I want to plot lat/lon contours at the south pole, my data consists of grid cells, each with a lat and lon value. My problem is where the longitudes "meets" each other, as you can see in the picture, the vertical longitude in the lower part of the picture have a lot of lines on top of each other.
Does anyone know how to remove them? Here is my code:
coldiv = -57.5:2.5:-7.5;
min_pr = coldiv(1); max_pr = coldiv(end);
cmap = [0 0 0.4; 0 0 0.7; 0 0 1; 0 0.2 1; 0 0.4 1; 0 0.6 1; 0 0.8 1; 0 1 1;
0 1 0; 0.6 0.8 0; 0.6 0.6 0; 0.6 0.4 0; 0.6 0.2 0; 1 0 0];
x = linspace(1,length(coldiv)-2,length(cmap));
xi = 1:length(coldiv)-2;
cmap = interp1(x,cmap,xi);
cmap = [0. 0. 0.; cmap];
fig=figure();
set(fig, 'Position', [10 10 1500 700])
pcolor(mean(tas_ann_DMI_hist_tot,3))
shading flat
hold on;
contour(flip_lat_DMI, 'k','ShowText','on');
contour(flip_lon_DMI, 'k','ShowText','on');
caxis([min_pr max_pr]);colormap(cmap);
axesHandles = findobj(get(fig,'Children'), 'flat','Type','axes');
axis(axesHandles,'square')
set(gca,'YTick',[]);
set(gca,'XTick',[]);

I found a solution.
flip_lon_DMI(flip_lon_DMI<-160) = NaN;
flip_lon_DMI(flip_lon_DMI>190) = NaN;
...
contour(flip_lat_DMI,-90:5:-60,'k--','ShowText','on','Color',[.5 .5 .5]);
contour(flip_lon_DMI,-150:30:180,'k--','ShowText','on','Color',[.5 .5 .5]);

Related

There are an issue with Matlab app designer plots app.UIAxes

I'm creating an app in App Designer onMatlab R2017b that simulate the propagation of information in online social network. I'm displaying the results in plots app.UIAxes as shown in the figure.
Eventhough, I set all the parameters of the plot to automatic when I run the program it will set to manual again. And the following code will be generated after running the app:
% Create UIAxes7_2
app.UIAxes7_2 = uiaxes(app.Panel);
title(app.UIAxes7_2, 'Title')
xlabel(app.UIAxes7_2, 'X')
ylabel(app.UIAxes7_2, 'Y')
app.UIAxes7_2.DataAspectRatio = [1 1 1];
app.UIAxes7_2.PlotBoxAspectRatio = [1 1 1];
app.UIAxes7_2.XLim = [0 1];
app.UIAxes7_2.YLim = [0 1];
app.UIAxes7_2.ZLim = [0 1];
app.UIAxes7_2.CLim = [0 1];
app.UIAxes7_2.GridColor = [0.15 0.15 0.15];
app.UIAxes7_2.MinorGridColor = [0.1 0.1 0.1];
app.UIAxes7_2.Box = 'on';
app.UIAxes7_2.XColor = [0.15 0.15 0.15];
app.UIAxes7_2.XTick = [0 0.2 0.4 0.6 0.8 1];
app.UIAxes7_2.YColor = [0.15 0.15 0.15];
app.UIAxes7_2.YTick = [0 0.2 0.4 0.6 0.8 1];
app.UIAxes7_2.ZColor = [0.15 0.15 0.15];
app.UIAxes7_2.ZTick = [0 0.5 1];
app.UIAxes7_2.XGrid = 'on';
app.UIAxes7_2.YGrid = 'on';
app.UIAxes7_2.CameraPosition = [0.5 0.5 9.16025403784439];
app.UIAxes7_2.CameraTarget = [0.5 0.5 0.5];
app.UIAxes7_2.CameraUpVector = [0 1 0];
app.UIAxes7_2.Position = [365 233 337 202];
The way I fix this is by deleting the axis in the editor and replacing it with another. Then it runs and displays the plot on the axis as it should. but After few run the same issue come back again.The plot do not displays the hole figure but only a proportion.

Population Modelling MATLAB

I have a Leslie Matrix
LeslieMatrixA = [0 0.4 0.7 0.5;
x 0 0 0;
0 0.8 0 0;
0 0 0.7 0]
and an initial population vector [10;10;10;10] where 0.7<=x<=0.9.
How can I create MATLAB code to show behaviour of the population over time?
Any help appreciated!
Thanks.
If you just want to show how the population changes you could just plot it right?
x=0.7;
LeslieMatrixA = [0 0.4 0.7 0.5; x 0 0 0; 0 0.8 0 0; 0 0 0.7 0];
P = [10;10;10;10];
for ct = 1:10
bar([1:4],P)
title(sprintf('iteration: %.0f',ct))
pause
P=LeslieMatrixA*P;
end

Going from camera-centric coordinates to pattern-centric coordinates

I currently have a camera alignment model set in camera as origin coordinates:
http://i.imgur.com/UnSCAvG.png
and, since the camera was stationary I'm trying to convert the system to a pattern-fixed model
http://i.imgur.com/OKunxwA.png
Matlab is nice enough to show it to me but alas there I've found no way to extract the data unless it's on a fixed-camera model. It should be a simple matter of applying the inverse of the translation and the rotation to change between systems but unfortunately this is not working and I can't see why.
oldpoint = [0 0 0 1]';
translation = ([1 0 0 18.1043121043; 0 1 0 31.092351038; 0 0 1 -80.0610295707; 0 0 0 1]);
rotation = [eul2rotm([0.0957937074 -0.0234017529 -0.037084526]) zeros(3,1); 0 0 0 1];
newpoint = translation * point;
newpoint = rotation * newpoint;
I've tried several different alternatives to this but thus far none aproximate the coordinates I'm trying to get.
Two things were going wrong, matlab was not using euler angles and Z needed to be inverted.
clc;
clear;
%%
oldpoint = [0 0 0 1]';
newpoints = zeros(13,4);
i = 1;
while( i<= length(translations) )
trans = translations(i,:);
rota = rotations(i,:);
display(trans);
display(rota);
translation = ([1 0 0 -trans(1); 0 1 0 -trans(2); 0 0 1 trans(3); 0 0 0 1]);
rotation = [rotationVectorToMatrix([-rota(1) -rota(2) -rota(3)]) zeros(3,1); 0 0 0 1];
newpoint = translation * oldpoint;
newpoint = rotation * newpoint;
newpoints(i,:) = newpoint;
i = i + 1;
end

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.

Is it possible to vectorize procedural operations (for/if ) in Matlab?

I wonder if the following code can be vectorized? Or, more straightforward, I am trying to match a number to several intervals, the result of which determines the update of a increment process. Thanks a lot!
pop_matrix = [10 0 0 0 0 0];
rand_num =rand;
divid = [0.05 0.05 0.1 0.2 0.1 0.1];
for i = 1:6
if rand_num < sum(divid(1:i))
pop_matrix(i) = pop_matrix(i)+1;
break
end
end
The following should work:
pop_matrix = [10 0 0 0 0 0];
rand_num =rand;
divid = [0.05 0.05 0.1 0.2 0.1 0.1];
idx = find(cumsum(divid) > rand_num,1);
pop_matrix(idx) = pop_matrix(idx) + 1;
EDIT: A method using interp1 which is about 10x faster, assuming you want to draw N samples from the distribution called divid:
pop_matrix = [10 0 0 0 0 0];
divid = [0.05 0.05 0.1 0.2 0.1 0.1];
N = 1000; %// number of random samples to take
rand_num = rand(N,1); %// generate N random numbers
dcs = cumsum(divid); %// get cumulative distribution
dcs = dcs/dcs(end); %// ensure this is normalized to 1
dcs = [0,dcs]; %// put a zero in front to create a new bin
s = interp1(dcs, 1:length(dcs), rand_num, 'previous', NaN); %// draw samples
pop_matrix = pop_matrix + accumarray(s,1)'; %'//add up samples together
This process is basically sampling from the probability distribution defined by divid using the Inverse Transform Sampling method, where dcs is the distribution's cumulative density function (CDF).