How to make a matrix for a particular surface plot? - matlab

I have a time column vector
t =
[0;
1;
3;
7;
10]
a frequency column vector
f =
[978;
573;
269;
102;
14]
and an impedance column vector
Z =
[0;
10;
64;
97;
103]
The kind of surface plot I'm looking for would be so that if you rotate the figure to display Z vs. t, you would see something equivalent to
plot(t, Z)
and if you rotate the figure to display Z vs. f, you would see something equivalent to
semilogx(f, Z)
x axis time, y axis frequency, and z axis impedance.
Here's what I have so far:
Zimp1 = flipud(toeplitz(flip(Z)));
figure(1);
surf(t, f, Zimp1);
set(gca, 'Yscale', 'log');
The problem lies within the Zimp1 matrix--the matrix that shows what's going on in the surface plot with the values of frequency and time. How do I construct the Zimp1 matrix to give me exactly that: plot(t, Z) on the view([-90, 0]) side and semilogx(f, Z) on the view([0, 0]) side?

Related

How to plot using surf gird in 2D using function value

if the function F is available it is easy to draw surf plot i.e.
x=1:0.1:4;
y=1:0.1:4;
[X,Y]=meshgrid(x,y);
Z=sin(X).^2+cos(Y).^2;
surf(X,Y,Z);
view(2) ;
in my case I calculated F function using least square:
for example I have x and y vectors
x = [0 9.8312 77.1256 117.9810 99.9979];
y = [0 2754.5 4043.3 5376.3 5050.4];
the linear function of these two vector is define by
F= [1149.73 , 37.63];
therefore the estimation is equal to
z= [ones(5,1) x']*F';
which is
z = [1149.73 1519.67 4051.96 5589.35 4912.65];
and if it is plotted
plot(x,y,'b.');
hold on;plot(x,y,'b-');
hold on; plot(x,z,'-r');
The linear z ( red line) is showing correctly. Now I want to plot it for all possible combination of x and y using grid and I need to have a mesh for all inputs
[X,Y] = meshgrid(x,y);
but how to make the Z matrix to show the intensity plot of function Z? The Z suppose to have high intensity close to z value and less value far from it. I should suppose to get something like this
Thanks
P.S: the F is calculated using pinv (least square).
You have to interpolate the scattered data to plot it on grid. Here is a simple example for your x, y and z vectors
xi=linspace(min(x),max(x),100)
yi=linspace(min(y),max(y),100)
[XI YI]=meshgrid(xi,yi);
ZI = griddata(x,y,z,XI,YI);
contourf(XI,YI,ZI)

Efficiently Plot Markers of varying individual size

The plot function allows us to plot all markers with a constant size s.
figure;
x = -10 : 10;
y = x .^ 2;
s = 10;
plot(x, y, 'bo', 'MarkerSize', s);
Suppose instead we would like each marker to have some individual size sx. For example, sx = abs(x) + 1.
One way to achieve this would be to use a for loop.
figure;
x = -10 : 10;
y = x .^ 2;
sx = abs(x) + 1;
hold on;
for i = 1 : length(x)
plot(x(i), y(i), 'bo', 'MarkerSize', sx(i));
end
This works well enough for small number of x. However, what if x is larger? For example, x = -100 : 0.01 : 100.
This now takes significantly longer, while plot(x, y, 'bo', 'MarkerSize', 100) would still complete almost instantly. Ideally, we would be able to do something such as plot(x, y, 'bo', 'MarkerSize', sx) where sx is a vector of sizes with each entry in sx corresponding to an entry in x and y. Unfortunately, that would give an error of Value not a numeric scalar.
Is there an efficient way to plot markers where each marker have varying individual sizes?
What you're trying to do is possible using scatter instead of plot as follows:
scatter(x,y,abs(x)+1)

How to plot spheres on top of scattered stars in MATLAB?

I would like to make a scattered stars and plot multiple spheres on top of it? I tried doing this:
x = rand(100,1); y = rand(100,1); z = rand(100,1);
scatter(x,y,z,'c*')
After this I tried plotting sphere but the sphere pushes the stars to the side. How do I fix this?
vec = [1;1;1]; rads = 1;
[x y z] = sphere;
x = rads*x+vec(1); y = rads*y+vec(2);
z = rads*z+vec(3);
surf(x, y, z, 'Edgecolor', 'none')
colormap colorcube
As you can see it pushed the stars to the side
Thank you.
Its pushing the scatter plot to the side because the range of the 'stars' is [0 1] because the command rand(...) generates values between 0 and 1. On the other hand, the sphere goes from 0 to 2 in all 3 directions.
To fix the problem, you can simply multiply the data used to generate the scatter plot by 2, so they will be in the range [0 2].
Doing so results in the following:
And the code. Note that I used scatter3 instead of scatter.
clear
clc
close all
xs = 2*rand(100,1); ys = 2*rand(100,1); zs = 2*rand(100,1);
hScatter = scatter3(xs,ys,zs,'c*')
hold on
vec = [1;1;1]; rads = 1;
[x y z] = sphere;
x = rads*x+vec(1); y = rads*y+vec(2);
z = rads*z+vec(3);
surf(x, y, z, 'Edgecolor', 'none')
colormap colorcube
rotate3d on

Plotting MATLAB values in two different colors

Anyway, I wish to plot two column vectors, filled with random numbers with no negative values in them, on a 2D plot(x and y).
The 'x-vector' I can leave as it is, but with the 'y vector', I wish to plot that any y values that is equal to zero as a different color(Say red) to the other positive non-zero values(Say blue).
Please try to keep solution relatively simple, if possible, as I myself am relatively new to MATLAB as well as to this site.
I'm not sure what you mean by 2D plot but I assuming you mean just a normal curve. Try this:
x = rand(10, 1);
y = rand(10, 1);
y([5 8]) = 0; %Force a couple of values to be 0 for visualisation
t = 1:10;
plot(t, x);
hold on
plot(t, y, 'g');
ind = y == 0; %Make a logical index that masks all the value where y is not 0
plot(t(ind), y(ind), 'r*');

Set surf minimum for matlab

I have a function which takes a voxel representation of a 3D landscape and can plot a X-Y section to show the middle of the landscape. The voxel representation is stored in a 3 dimensional matrix with a number that represents something important. Obviously the matrix is
1,1,1
2,2,2
in terms of accessing the elements but the actual 3D locations are found in the following method:
(index-1)*resolution+0.5*resolution+minPos;
where resolution is the grid size :
resolution
<-->
__ __ __
|__|__|__|
<- Min pos
and minPos is where the grid starts.
Now in terms of the actual question, i would like to extract a single X-Y section of this voxel representation and display it as a surf. This can be done by just doing this:
surf(voxel(:, :, section))
however then you get this:
The obvious problem is that the grid will start at 0 because that is how the matrix representation is. How can i set the minimum and cell size for surf, ie so that the grid will start at the minimum (shown above) and will have the grid spacing of resolution (shown above).
Read the documentation of surf, you can also provide x and y coordinates corresponding to your data points.
surf(X,Y,Z)
X and Y can be either vectors or matrices:
surf(X,Y,Z) uses Z for the color data and surface height. X and Y are vectors or matrices defining the x and y components of a surface. If X and Y are vectors, length(X) = n and length(Y) = m, where [m,n] = size(Z). In this case, the vertices of the surface faces are (X(j), Y(i), Z(i,j)) triples. To create X and Y matrices for arbitrary domains, use the meshgrid function
Example
Z=[ 0 1 2 3;
7 6 5 4;
8 9 10 11];
x=[-1 0 1 2];
y=[-2 0 2];
surf(x,y,Z);
Of course you have to match Z, x and y matrices/vectors as clearly described in the doc^^
Just remember that elements in columns of Z are surf'ed as values along the y-axis, elements in rows of Z are surf'ed as values along the x-axis. This is clearly to be seen in the example picture.
Solution
I think you switched the x and y-axis around, which you can fix by just transposing z:
s = size(voxel);
xi = (minPosX:resolution:(minPosX+resolution*s(1)-1));
yi = (minPosY:resolution:(minPosY+resolution*s(2)-1));
z = (voxel(:,:,section));
surf(xi, yi, z');
or that you're picking the wrong numbers for constructing xi and yi and it should be this instead:
xi = (minPosX:resolution:(minPosX+resolution*s(2)-1));
yi = (minPosY:resolution:(minPosY+resolution*s(1)-1));
z = (voxel(:,:,section));
surf(xi, yi, z);
So it was easy enough to do:
lets say we have a 3D matrix "voxel";
s = size(voxel);
xi = (minPosX:resolution:(minPosX+resolution*s(1)-1));
yi = (minPosY:resolution:(minPosY+resolution*s(2)-1));
z = (voxel(:,:,section));
[x y] = meshgrid(xi, yi);
x = x';
y = y';
surf(x, y, z);
Provides the following plot:
This is rotated which is annoying, I cant seem to get it to rotate back (I could just visualise around the other way but that's ok)