I have a data set on the form of 3 spatial coordinates x,y,z and an amplitude, here is a small crop of the data:
[ 0 2.9373 0.4646 2.9926
0.8384 1.5338 1.0000 1.0016
0 0.7619 0.5051 1.0033
1.0000 3.5288 0.6667 2.9894
0 0.5013 0.4343 1.0037
1.0000 2.8070 0.4848 2.9935
0.7980 4.0000 0.8586 2.9872
1.0000 0.1404 0.0707 1.0043
1.0000 1.7845 0.1818 1.0007
0.9798 3.1679 1.0000 2.9913]
What I would like is a 2D contour plot, where the interface is represented by the contour levels within, say, 2.0 +/- 0.05.
First I start by making the data 2D and thus choose the values z within +/- 0.01. Then I am only left with x,y,amplitude.
Then I used this for extracting the data sets that satisfy data(:,4) is within 2.0 +/- 0.05.
However, what remains now is actually making the contour plot. I tried contour but that requires the data to have a format of meshgrid, which it does not. So my question is, what is the easiest way to make a contour plot of the extracted data?
You should be able to create an interpolation function for your scattered data like this:
F_interp = scatteredInterpolant(x,y,amplitude);
Then setup a gridded mesh of interpolation points (using limits and sizes that could be based on the original data):
xMin = min(x);
xMax = max(x);
yMin = min(y);
yMax = max(y);
Nx = 2*length(x);
Ny = 2*length(y);
xpts = linspace(xMin,xMax,Nx);
ypts = linspace(yMin,yMax,Ny);
[X,Y] = meshgrid(xpts,ypts);
Interpolate the data at those gridded points:
A = F_interp(X,Y);
Now pass the interpolated data to the MATLAB contour function:
contour(X,Y,A);
Related
This question already has answers here:
how to plot this data?
(2 answers)
Closed 6 years ago.
There are certain points on a unit sphere and i want to join them smoothly along the sphere smoothly how can i do it in MATLAB,because when i do it using 3dplot function in matlab it simply joins the point using straight lines.
for example there is have a point in first quadrant and the second point in 8th quadrant then it join them using straight line. without following a curved path.
These are the values of theta:
theta = [ 80.0000 73.2995 65.7601 95.5007 100.4861 97.8834 94.0849 52.5174 74.4710 104.6674 52.7177 97.0538 75.7018 83.2817 97.5423 85.1797 84.2677 126.2296 81.1814 66.1376 91.6953 167.7085 46.5980 87.8220 113.4588 180.0000 80.7624 95.8623 115.0538 76.5773 61.9858 141.0402 109.9872 76.1273 84.4166 75.2734 110.4489 82.2434 96.8303 100.0815 73.2454 82.0755 64.6457 76.3510 87.7863 133.2706 86.1305 76.8670 86.3225 96.8016 49.2653 107.2900 145.9905 59.2158 107.7546 180.0000 93.9687 87.5474 103.1400 180.0000 136.8251 180.0000 106.2629 109.0069 ];
And the values of phi are:
phi = [ -90.0000 -78.5230 -51.6764 84.6854 58.1182 -75.9705 78.0541 -60.0560 88.8935 -84.6539 -44.1415 -86.7643 61.7764 -87.4767 -86.9440 -80.2459 -76.8752 88.9510 64.7297 -51.1245 -83.1606 -88.7280 -32.7110 81.0951 86.8393 -0.0000 52.6243 -88.7833 -75.4600 84.1374 79.8300 -86.7258 -65.8055 80.9829 -89.3172 57.1802 -80.6346 72.5277 -87.4452 74.2778 -86.1069 76.6124 -80.4604 89.2202 85.0649 89.2164 -79.0290 84.9961 -88.2301 -87.5064 50.4016 83.0830 82.4863 -50.8481 87.0335 -0.0000 88.4613 79.7583 -80.6474 -0.0000 80.0771 -0.0000 89.2428 -82.769 ];
can these be easily poltted
If you want MATLAB to plot along the unit sphere like that, you are going to need to specify all of the points in between because MATLAB will only ever connect points with a straight line.
To do this, we can adapt Roger Stafford's great solution on MATLAB central to draw the shortest great circle path between any two consecutive points.
Using the following function we can do just that. We will determine the shortest great circle path between two consecutive points and then interpolate between them to draw the line on the unit circle
function plotOnSphere(x,y,z,varargin)
%// Vectors representing each point
xyz = [x(:), y(:), z(:)].'; %'
%// One vector of the "first" points and one of the "next" points
v1 = xyz(:, 1:end-1);
v2 = xyz(:, 2:end);
%// Cross product between the vectors of one point and the next
cv1v2 = cross(v1, v2);
%// Compute unit vector in the plane defined by v1 and v2
v3 = normc(cross(cv1v2, v1));
%// Figure out the range of the inner angle between v1 and v2
nc = sqrt(sum(cv1v2.^2, 1));
t = atan2(nc, dot(v1, v2, 1));
%// Number of points to sample between any two points on the sphere
nPoints = 100;
%// Compute the interpolant
V = zeros([nPoints, fliplr(size(v1))]);
for k = 1:numel(t)
T = linspace(0, t(k), 100);
V(:,k,:) = (v1(:,k) * cos(T) + v3(:,k) * sin(T)).'; %'
end
%// Break the result out into x,y,z parts
xx = V(:,:,1);
yy = V(:,:,2);
zz = V(:,:,3);
%// Plot the lines
h = plot3(xx(:), yy(:), zz(:), varargin{:});
hold on
%// Plot the original data points
plot3(x,y,z, 'o', ...
'Color', get(h, 'Color'), ...
'Parent', get(h, 'Parent'), varargin{:});
end
If we apply the input data that you have provided.
theta = [ 80.0000 73.2995 65.7601 95.5007 100.4861 97.8834 94.0849 52.5174 74.4710 104.6674 52.7177 97.0538 75.7018 83.2817 97.5423 85.1797 84.2677 126.2296 81.1814 66.1376 91.6953 167.7085 46.5980 87.8220 113.4588 180.0000 80.7624 95.8623 115.0538 76.5773 61.9858 141.0402 109.9872 76.1273 84.4166 75.2734 110.4489 82.2434 96.8303 100.0815 73.2454 82.0755 64.6457 76.3510 87.7863 133.2706 86.1305 76.8670 86.3225 96.8016 49.2653 107.2900 145.9905 59.2158 107.7546 180.0000 93.9687 87.5474 103.1400 180.0000 136.8251 180.0000 106.2629 109.0069 ];
phi = [ -90.0000 -78.5230 -51.6764 84.6854 58.1182 -75.9705 78.0541 -60.0560 88.8935 -84.6539 -44.1415 -86.7643 61.7764 -87.4767 -86.9440 -80.2459 -76.8752 88.9510 64.7297 -51.1245 -83.1606 -88.7280 -32.7110 81.0951 86.8393 -0.0000 52.6243 -88.7833 -75.4600 84.1374 79.8300 -86.7258 -65.8055 80.9829 -89.3172 57.1802 -80.6346 72.5277 -87.4452 74.2778 -86.1069 76.6124 -80.4604 89.2202 85.0649 89.2164 -79.0290 84.9961 -88.2301 -87.5064 50.4016 83.0830 82.4863 -50.8481 87.0335 -0.0000 88.4613 79.7583 -80.6474 -0.0000 80.0771 -0.0000 89.2428 -82.769 ];
%// Convert to cartesian coordinates
[x,y,z] = sph2cart(deg2rad(theta), deg2rad(phi), 1);
figure;
plotOnSurface(x,y,z);
%// Plot a unit sphere for reference
sphere()
s = findall(gca, 'type', 'surf');
set(s, 'FaceColor', 'k', 'FaceAlpha', 0.01, 'EdgeAlpha', 0.1)
Using the code for plot_pz([poles],[zeros])
function plot_pz(b,a)
b_roots = roots(b);
a_roots = roots(a);
plot(b_roots,'x black');
plot(a_roots,'o blue');
axis equal;
I can get my b_roots to plot properly, but my a_roots continually plot on the 1+0i axis (or x=1). For example, the Z-Transform H(z) = [[1 2 2],[0 1 .8]] gives the following poles and zeros (per matlab):
poles =
-1.0000 + 1.0000i
-1.0000 - 1.0000i
zeros =
-0.8000
It should look like this
but instead what I get is
Where my zeros are at -1+1i and -1-1i, and my poles seem to be at 1-.8i, but should instead be at -.8+0i
I'm sure it's something simple that I'm missing, but I can't figure it out. I think it only happens when I have a single pole or a single zero.
Does plot(X) always default to plotting 1+xi?
Fixed by being more clear with real() and imag()
plot(real(b_roots),imag(b_roots),'o blue');
plot(real(a_roots),imag(a_roots),'x red');
I'm trying to do an algorithm in Matlab to try to calculate a received power in dBm of a logarithmic model of a wireless telecommunication system..
My algorithm calculate the received power for a number of distances in km that the user specified in the input and stores it in a vector
vector_distances = { 1, 5, 10, 50, 75 }
vector_Prx = { 131.5266 145.5060 151.5266 165.5060 169.0278 }
The thing is that I almost have everything that I need, but for graphics purposes I need to plot a graph in where on the x axys I have my vector of receiver power but on the y axys I want to show the same received power but with the most complete logarithmic model (the one that have also the noise - with Log-normal distribution on the formula - but for this thing in particular for every distance in my vector I need to choose 50 numbers with 0.5 distance between them (like a matrix) and then for every new point in the same distance calculate the logarithmic model to later plot in the same graph the two functions, one with the model with no noise (a straight line) and one with the noise.. like this picture
!http://imgur.com/gLSrKor
My question is, is there a way to choose 50 numbers with 0.5 distance between them for an existing number?
I know for example, if you have a vector
EDU>> m = zeros(1,5)
m =
0 0 0 0 0
EDU>> v = 5 %this is the starter distance%
v =
5
EDU>> m(1) = 5
m =
5 0 0 0 0
% I want to create a vector with 5 numbers with 0.5 distance between them %
EDU>> for i=2:5
m(i) = m(i-1) + 0.5
end
EDU>> m
m =
5.0000 5.5000 6.0000 6.5000 7.0000
But I have two problems, the firs one is, could this be more simplex? I am new on Matlab..and the other one, could I create a vector like this (with the initial number in the center)
EDU>> m
m =
4.0000 4.5000 **5.0000** 5.5000 6.0000
Sorry for my english, and thank you so much for helping me
In MATLAB, if you want to create a vector from a number n to a number m, you use the format
A = 5:10;
% A = [5,6,7,8,9,10]
You can also specify the step of the vector by including a third argument between the other two, like so:
A = 5:0.5:10;
% A = [5,5.5,6,6.5,7,7.5,8,8.5,9,9.5,10]
You can also use this to count backwards:
A = 10:-1:5
% A = [10,9,8,7,6,5]
Ok guys. I have the following problem:
I have the data of the following plot.
So the data file of this plot contains three columns.
The 2nd and 3rd ones the x,y points. And the 1st one is to which system those points belong.
In this case the red ones are for the system of 20 years. The blue ones for the 30 years.
What I want to find is the curve at 25 years. So if I plot it it should be between the red and blue curves.
I have no idea how interpolate the data in order to obtain what I want. Actually I want to have for 21,22,...29 years, I guess if we can find it for a time in between these two, then the method should work for any time between 20 and 30.
PS: I guess the interpolation for each curve (in this case red or blue one) is quite easy. Just using interp1(x,y,xx) will work. But what happened with the other "dimension" (M)
The data.
20.0000 3.4076 0
20.0000 3.4226 99.5405
20.0000 3.4701 196.3360
20.0000 3.5592 287.0781
20.0000 3.6248 328.8516
20.0000 3.6643 348.3373
20.0000 3.7091 367.2823
20.0000 3.7591 385.4784
20.0000 3.8077 402.7170
20.0000 3.8957 437.5221
20.0000 4.0314 506.9907
30.0000 3.6335 0
30.0000 3.6373 49.8884
30.0000 3.6488 99.5405
30.0000 3.6685 148.5936
30.0000 3.7363 243.2204
30.0000 3.7876 287.7398
30.0000 3.8537 329.6097
30.0000 3.8935 349.9452
30.0000 3.9384 368.9776
30.0000 3.9892 387.2576
30.0000 4.0410 404.5759
30.0000 4.1350 439.5416
30.0000 4.2153 474.2420
30.0000 4.2813 509.3309
Actually, by looking at the Matlab documentation I found a simpler way. You can use the function griddata. (The doc in matlab help shows visual example). The resampling on a common grid and the interpolation is embedded in the function.
%// First separate (and name your column to identify them better)
t = d(:,1) ;
x = d(:,2) ;
y = d(:,3) ;
%// use the function 'griddata'
[TI,YI] = meshgrid( 20:30 , 0:20:500 ) ; %// change these values to change the grid limits
XI = griddata(t,y,x,TI,YI) ;
%// show result in 3D ... but could be projected in X-Y plane if necessary
plot3(TI,YI,XI , 'Marker','o' )
xlabel('Time') ; ylabel('Y') ; zlabel('X')
The last line of the code shows this plot:
All your interpolated data are in the XI matrix. The way to retrieve them depends on how you want to organize them ultimately.
EDIT:
To place all the interpolated data in a single table InterpData organized the same way of your original table, use the following:
nLine = numel(XI) ;
InterpData = [ reshape(TI,nLine,[]) reshape(XI,nLine,[]) reshape(YI,nLine,[]) ] ;
Regarding the NaNs. They will come to bother you every time you ask to do an interpolation outside of the initially known values.
For example, if your time in the original data is in the [20 to 30] interval, matlab will gladly interpolate anything within that interval, but will return NaN if you ask to return a value for time = 19 for example. Same goes for Y, the grid on which to interpolate has to be within the initial range. (as in this implementation we use a base grid formed by Time (column 1) and Y(column 3), to interpolate the X column).
Try this code, which implements #Hoki 's comment:
m20=[3.4076 0; 3.4226 99.5405; 3.4701 196.3360; 3.5592 287.0781; 3.6248 328.8516; 3.6643 348.3373; 3.7091 367.2823; 3.7591 385.4784; 3.8077 402.7170; 3.8957 437.5221; 4.0314 506.9907];
m30=[3.6335 0; 3.6373 49.8884; 3.6488 99.5405; 3.6685148.5936; 3.7363 243.2204; 3.7876 287.7398; 3.8537 329.6097; 3.8935 349.9452; 3.9384 368.9776; 3.9892 387.2576; 4.0410 404.5759; 4.1350 439.5416; 4.2153 474.2420; 4.2813 509.3309];
yy = [0:50:500];
xx20 = interp1(m20(:,2),m20(:,1),yy);
xx30 = interp1(m30(:,2),m30(:,1),yy);
for m = 1:9
mm(:,m) = xx20 + (xx30-xx20)*(m/(30-20));
end
plot(m20(:,1),m20(:,2),xx20,yy,xx30,yy,m30(:,1),m30(:,2),mm,yy)
You interpolate the given M vectors to find the x coordinate of a set of y values - these are the interp1 lines. Then, you linearly interpolate as a function of m between the interpolated x-coordinates.
I am trying to set the transparency of (MarkerFace) data points in a scatter plot in Matlab. I can see this has been asked before and most answers suggest using using patch. This isn't working for me, can someone tell me where I'm going wrong? Thanks!
h(1) = scatter(x1,y1,30,'MarkerEdgeColor',[0 0.5 0.5],'MarkerFaceColor', [0 0.5 0.5]);
hold on
h(2) = scatter(x2,y2,30,'MarkerEdgeColor','g','MarkerFaceColor', 'g');
h(3) = scatter(x3,y3,30,'MarkerEdgeColor',[0 0.3906 0],'MarkerFaceColor', [0 0.3906 0]);
h(4) = scatter(x4,y4,30,'MarkerEdgeColor',[0.4961 1.0000 0.8281],'MarkerFaceColor', [0.4961 1.0000 0.8281]);
PatchInPlot = findobj(h([1 2 3 4]), 'type', 'patch');
set(PatchInPlot, 'facea', 0.5)
The FaceAlpha property does not really refer to the markers. It rather refers to the area the markers span over, try
h = scatter(1:5,1:5,30,'MarkerEdgeColor',[0.4961 1.0000 0.8281],'MarkerFaceColor', [0.4961 1.0000 0.8281]);
PatchInPlot = findobj(h, 'type', 'patch');
set(PatchInPlot(2),'XData',[3.5;4.5;4.5;3.5;3.5],'YData',[3.5;3.5;4.5;4.5;3.5]);
set(PatchInPlot(2),'FaceColor',[1,0,0]);
set(PatchInPlot, 'facea', 0.2);
If you have a reasonable number of points that you want to plot you can consider creating a patch polygon for each marker and then set the transparity for each polygon. It may not be the only way, but I cannot give a better answer.