Plot Zero Value on Contour Plot in MATLAB - matlab

I'm plotting z values, 0 to 10, on a contour plot.
When I include data 1 or greater, I obtain a contour plot. Like the following:
longitude = [80 82 95]
latitude = [30 32 35]
temp = [1 4 6; 1 2 7; 3 5 7]
contourf(longitude,latitude,temp)
Now, I want to plot the ZERO VALUE also on the contour plot. While I was expecting one color representing the zero value, instead I obtained a white square.
longitude = [80 82 95]
latitude = [30 32 35]
temp = [0 0 0; 0 0 0; 0 0 0]
contourf(longitude,latitude,temp)
Thanks a lot,
Amanda

As Issac mentioned. To plot a constant data in a contourf is not possible.
When you try to do so you will obtain this warning from Matlab:
temp =
0 0 0
0 0 0
0 0 0
Warning: Contour not rendered for constant ZData
> In contourf>parseargs at 458
In contourf at 63
In TESTrandom at 45
However, if you put some numbers as 0, the contourf works fine:
longitude = [80 82 95];
latitude = [30 32 35];
temp = [0 4 6; 1 0 7; 0 5 9];
contourf(longitude,latitude,temp);
hcb = colorbar('horiz'); % colour bar
set(get(hcb,'Xlabel'),'String','Contourf Bar.')

Related

How to insert rows and columns of zeros into Matlab Matrix

I have a 3x3 matrix, k1, that I would like to convert into a 5x5 matrix, k1g. k1g is created by inserting zeros into certain rows and columns of k1. In this case I would like to insert zeros into rows 3 and 4 and columns 3 and 4, and keep existing values from k1 matrix. The code below accomplishes what I am trying to do but seems that it is a long method and I need to do this many times in numerous problems.
clc
clear all
format long;
k1 = [20,50,-20;
60,20,-20;
-20,-20,40]
k1g = zeros(5,5);
k1g(1:2,1:2) = k1(1:2,1:2);
k1g(5:5,1:2) = k1(3:3,1:2);
k1g(1:2,5:5) = k1(1:2,3:3);
k1g(5,5) = k1(3,3)
Here is output of above code:
k1 =
20 50 -20
60 20 -20
-20 -20 40
k1g =
20 50 0 0 -20
60 20 0 0 -20
0 0 0 0 0
0 0 0 0 0
-20 -20 0 0 40
Is there a better way to accomplish this?
You just need to generalise your approach. e.g. with:
function k1g = rowcolsof0s(k1,rowsof0s,colsof0s)
k1g = ones(size(k1)+[numel(rowsof0s) numel(colsof0s)]); %Initialising matrix with ones
k1g(rowsof0s,:) = 0; %Changing the elements of desired rows to zeros
k1g(:,colsof0s) = 0; %Changing the elements of desired columns to zeros
k1g(logical(k1g)) = k1; %Transferring the contents of k1 into k1g
end
Now call that function with:
rowsof0s = [3 4]; %rows where you want to insert zeros
colsof0s = [3 4]; %columns where you want to insert zeros
k1g = rowcolsof0s(k1, rowsof0s, colsof0s);

How do I calculate the area of a 3 dimensional projection?

For example, using the following code, I have a coordinate matrix with 3 cubical objects defined by 8 corners each, for a total of 24 coordinates. I apply a rotation to my coordinates, then delete the y coordinate to obtain a projection in the x-z plane. How do I calculate the area of these cubes in the x-z plane, ignoring gaps and accounting for overlap? I have tried using polyarea, but this doesn't seem to work.
clear all
clc
A=[-100 -40 50
-100 -40 0
-120 -40 50
-120 -40 0
-100 5 0
-100 5 50
-120 5 50
-120 5 0
-100 0 52
-100 0 52
20 0 5
20 0 5
-100 50 5
-100 50 5
20 50 52
20 50 52
-30 70 53
-30 70 0
5 70 0
5 70 53
-30 120 53
-30 120 0
5 120 53
5 120 0]; %3 Buildings Coordinate Matrix
theta=60; %Angle
rota = [cosd(theta) -sind(theta) 0; sind(theta) cosd(theta) 0; 0 0 1]; %Rotation matrix
R=A*rota; %rotates the matrix
R(:,2)=[];%deletes the y column
The first step will be to use convhull (as yar suggests) to get an outline of each projected polygonal region. It should be noted that a convex hull is appropriate to use here since you are dealing with cuboids, which are convex objects. I think you have an error in the coordinates for your second cuboid (located in A(9:16, :)), so I modified your code to the following:
A = [-100 -40 50
-100 -40 0
-120 -40 50
-120 -40 0
-100 5 0
-100 5 50
-120 5 50
-120 5 0
-100 0 52
-100 0 5
20 0 52
20 0 5
-100 50 5
-100 50 52
20 50 5
20 50 52
-30 70 53
-30 70 0
5 70 0
5 70 53
-30 120 53
-30 120 0
5 120 53
5 120 0];
theta = 60;
rota = [cosd(theta) -sind(theta) 0; sind(theta) cosd(theta) 0; 0 0 1];
R = A*rota;
And you can generate the polygonal outlines and visualize them like so:
nPerPoly = 8;
nPoly = size(R, 1)/nPerPoly;
xPoly = mat2cell(R(:, 1), nPerPoly.*ones(1, nPoly));
zPoly = mat2cell(R(:, 3), nPerPoly.*ones(1, nPoly));
C = cell(1, nPoly);
for iPoly = 1:nPoly
P = convhull(xPoly{iPoly}, zPoly{iPoly});
xPoly{iPoly} = xPoly{iPoly}(P);
zPoly{iPoly} = zPoly{iPoly}(P);
C{iPoly} = P([1:end-1; 2:end].')+nPerPoly.*(iPoly-1); % Constrained edges, needed later
end
figure();
colorOrder = get(gca, 'ColorOrder');
nColors = size(colorOrder, 1);
for iPoly = 1:nPoly
faceColor = colorOrder(rem(iPoly-1, nColors)+1, :);
patch(xPoly{iPoly}, zPoly{iPoly}, faceColor, 'EdgeColor', faceColor, 'FaceAlpha', 0.6);
hold on;
end
axis equal;
axis off;
And here's the plot:
If you wanted to calculate the area of each polygonal projection and add them up it would be very easy: just change the above loop to capture and sum the second output from the calls to convexhull:
totalArea = 0;
for iPoly = 1:nPoly
[~, cuboidArea] = convhull(xPoly{iPoly}, zPoly{iPoly});
totalArea = totalArea+cuboidArea;
end
However, if you want the area of the union of the polygons, you have to account for the overlap. You have a few alternatives. If you have the Mapping Toolbox then you could use the function polybool to get the outline, then use polyarea to compute its area. There are also utilities you can find on the MathWorks File Exchange (such as this and this). I'll show you another alternative here that uses delaunayTriangulation. First we can take the edge constraints C created above to use when creating a triangulation of the projected points:
oldState = warning('off', 'all');
DT = delaunayTriangulation(R(:, [1 3]), vertcat(C{:}));
warning(oldState);
This will automatically create new vertices where the constrained edges intersect. Unfortunately, it will also perform the triangulation on the convex hull of all the points, filling in spots that we don't want filled. Here's what the triangulation looks like:
figure();
triplot(DT, 'Color', 'k');
axis equal;
axis off;
We now have to identify the extra triangles we don't want and remove them. We can do this by finding the centroids of each triangle and using inpolygon to test if they are outside all 3 of our individual cuboid projections. We can then compute the areas of the remaining triangles and sum them up using polyarea, giving us the total area of the projection:
dtFaces = DT.ConnectivityList;
dtVertices = DT.Points;
meanX = mean(reshape(dtVertices(dtFaces, 1), size(dtFaces)), 2);
meanZ = mean(reshape(dtVertices(dtFaces, 2), size(dtFaces)), 2);
index = inpolygon(meanX, meanZ, xPoly{1}, zPoly{1});
for iPoly = 2:nPoly
index = index | inpolygon(meanX, meanZ, xPoly{iPoly}, zPoly{iPoly});
end
dtFaces = dtFaces(index, :);
xUnion = reshape(dtVertices(dtFaces, 1), size(dtFaces)).';
yUnion = reshape(dtVertices(dtFaces, 2), size(dtFaces)).';
totalArea = sum(polyarea(xUnion, yUnion));
And the total area for this example is:
totalArea =
9.970392341143055e+03
NOTE: The above code has been generalized for an arbitrary number of cuboids.
polyarea is the right way to go, but you need to call it on the convex hull of each projection. If not, you will have points in the centers of your projections and the result is not a "simple" polygon.

Values do not match data in matlab geographic plot

I am plotting trajectories in Matlab using contourf. I am having an issue with the colors matching the data. I have posted my current image below. All areas that do not have data should be white as they are zero which I specifically specified in the script(they are currently blue-ish which is the the 0.1 to 1 range). In addition, values that are yellow, should be in the blue range(<1). Any suggestions?
Here is the part of my script where I do the plotting:
axesm('mercator', 'MapLatLim', latlim, 'MapLonLim', lonlim,...
'Frame', 'on', 'Grid', 'on', 'MeridianLabel', 'on', 'ParallelLabel', 'on')
setm(gca,'mlabelparallel',-20)
load coastlines
Contours = [0.001 0.01 0.1 1 10 100];
[c,h] = contourfm(latlim, lonlim, u, log(Contours));
colorbar('YTick', log(Contours), 'YTickLabel', Contours);
myColorMap = jet(256).^.3;
myColorMap(1,:) = [1];
colormap(myColorMap)
colorbar
caxis(log([Contours(1) Contours(length(Contours))]));
colorbar('FontSize', 12, 'YTick', log(Contours), 'YTickLabel', Contours);
geoshow(coastlat, coastlon,'Color', 'k')
Contour level, V, in contourfm(lat,lon,Z, V) does not scale your data or colour. It works in a different way than what you thought.
Let's see one example first:
u = rand(8)+0.1; u(1:2,:) = 0; u(5:6,:) = 10; u(7:8,:) = 100;
V = [0,1,40,100];
contourfm([0,1], [0,1], u, V);
mycm = jet(256).^.3; mycm(1,:) = 1;
colormap(mycm)
contourcbar('FontSize', 12, 'YTick', V, 'YTickLabel', V);
where u is
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0.1947 0.6616 0.2413 0.6511 0.4403 0.9112 1.0016 0.5654
0.8422 0.3159 0.5695 0.6478 0.9933 0.1686 0.8387 0.5362
10 10 10 10 10 10 10 10
10 10 10 10 10 10 10 10
100 100 100 100 100 100 100 100
100 100 100 100 100 100 100 100
As you can see, for V = [0,1,40,100] all values from 0 to 1 are white, values from 1 to 40 are cyan and above are red.
Therefore, you must scale your u then assign appropriate contour level. Use contourcbar instead of colorbar to check the colours first.
Apart from the problem with contour level, I suspect the u parameter contains negative values. The colour at the bottom of the colour bar is always assigned to the minimum z value. You must ensure 0 is the minimum value in u, i.e. remove the negative values.

Remove internal edges in 3D MATLAB plot using patch function

I am plotting a 3D object, say a cube, in MATLAB.
Node = [0 0 0; 1 0 0; 1 1 0; 0 1 0; 0 0 1; 1 0 1; 1 1 1; 0 1 1];
Elem = cell(1); Elem{1} = 1:8;
figure
for elm = 1:size(Elem,1)
X = Node(Elem{elm},:); K = convhulln(X); hold on;
patch('Faces',K,'Vertices',X,'FaceColor',rand(1,3),'FaceAlpha',1.0);
end
view(3); grid off; axis equal; cameramenu; axis off;
In the plot, how do I remove the internal diagonal lines? The plot should just show edges of cube. I am looking for a general solution which is applicable to any polyhedron.
the output of K=convhulln(X); is causing this, because convex hull will have triangular facets... (that's the default).
if instead you'd define K to be:
K= [1 2 3 4; ...
2 6 7 3; ...
4 3 7 8; ...
1 5 8 4; ...
1 2 6 5; ...
5 6 7 8];
You'll get it right.
Another option is to use geom3D from the FEX.

matlab - graph plotting

I have two arrays to plot, in x axis : array a. In y axis array b (ones and zeros)
I want to plot vertical lines when the values of array b =1
i.e
a=[23 12 76 43 21 90]
b=[1 0 1 1 0 1]
You may try bar plot.
a=[23 12 76 43 21 90];
b=[1 0 1 1 0 1];
bar(a,b)