Gaussian Probabilities plot around a trajectory - matlab

I am trying to write some code to generate a plot similar to the one below on matlab (taken from here):
I have a set of points on a curve (x_i,y_i,z_i). Each point generates a Gaussian distribution (of mean (x_i,y_i,z_i) and covariance matrix I_3).
What I did is I meshed the space into npoint x npoints x npoints and computed the sum of the probability densities for each of the 'sources' (x_i,y_i,z_i) in each point (x,y,z). Then, if the value I get is big enough (say 95% of the maximum density), I keep the point. otherwise I discard it.
The problem with my code is that it is too slow (many for loops) and the graph I get doesn't look like the one below:
Does anyone know whether there is a package to get a similar plot as the one below?

Using isosurface we can do reasonably well. (Although I'm not honestly sure what you want, I think this is close:
% Create a path
points = zeros(10,3);
for ii = 2:10
points(ii, :) = points(ii-1,:) + [0.8 0.04 0] + 0.5 * randn(1,3);
end
% Create the box we're interested in
x = linspace(-10,10);
y = x;
z = x;
[X,Y,Z] = meshgrid(x,y,z);
% Calculate the sum of the probability densities(ish)
V = zeros(size(X));
for ii = 1:10
V = V + 1/(2*pi)^(3/2) * exp(-0.5 * (((X-points(ii,1)).^2 + (Y-points(ii,2)).^2 + (Z-points(ii,3)).^2)));
end
fv = isosurface(X,Y,Z,V, 1e-4 * 1/(2*pi)^(3/2), 'noshare');
fv2 = isosurface(X,Y,Z,V, 1e-5 * 1/(2*pi)^(3/2), 'noshare');
p = patch('vertices', fv.vertices, 'faces', fv.faces);
set(p,'facecolor', 'none', 'edgecolor', 'blue', 'FaceAlpha', 0.05)
hold on;
p2 = patch('vertices', fv2.vertices, 'faces', fv2.faces);
set(p2,'facecolor', 'none', 'edgecolor', 'red', 'FaceAlpha', 0.1)
scatter3(points(:,1), points(:,2), points(:,3));

Related

Is there a matlab function(s) I can use to create a realistic diagram of the I.S.S?

As part of a project I am undertaking at the moment, I have to solve the two-body problem of the international space station orbiting the Earth. I have managed to approximate this so far by using the sphere/surf function, however, I was wondering if there was any way I could create a more realistic figure representing the ISS? Unfortunately,this project has to be done solely through MATLAB so I cannot use any other tools which may provide better visualisation
NASA has 3D models of many objects, including the ISS, which can be found here. This file can be converted to an STL however you want, I found this random website which worked for me.
In Matlab, you can read in this file via
stl = stlread('isscombined.stl');
V = stl.Points;
F = stl.ConnectivityList
Then, you can plot it using
p = patch('vertices',V,'faces',F,'FaceColor',[.8 .8 .8]);
and then you can update the object with new vertex positions as the station orbits the Earth. Obviously, you can also scale the object by multiplying the vertices by some amount. If you don't want the facet edges plotted, you can also add 'EdgeAlpha', 0 to your patch options.
Here's a simple example which shows the ISS orbiting around a sphere
% Note: not to scale
ISS_radius = 2; % distance from center of Earth
RE = 1; % radius of earth
theta = 0:.05:2*pi;
x = ISS_radius*cos(theta);
y = ISS_radius*sin(theta);
stl = stlread('isscombined.stl');
r = .01; % scaling factor
V = stl.Points * r;
V = V - mean(V); % center at origin
F = stl.ConnectivityList;
figure; hold on;
plot3(x,y,zeros(numel(theta)),'--');
[X,Y,Z] = sphere(50);
surf(RE*X,RE*Y,RE*Z,'FaceColor',[0 0 .8],'EdgeAlpha',0);
p = patch('Vertices', V*r, 'Faces', F, 'FaceColor', [0 0 0], 'EdgeAlpha', 0);
axis equal;
set(gca,'View',[200 13])
grid on;
counter = 1;
while true
p.Vertices = V + [x(counter), y(counter), 0];
pause(0.01);
drawnow
counter = mod(counter + 1, numel(theta)) + 1;
axis([-1 1 -1 1 -1 1]*ISS_radius*1.2)
end

Plotting unit circles in matlab and using the hold on to insert individual data points and plotting the intersection with circle

I was trying to produce the following figure:
as similar as possible. I was having difficulties because I wasn't sure how to plot the unit circle. How does one do that? I tried using the polar function but I couldn't then make it also plot the blue crosses and red crosses. Anyone has an idea?
Edited answer
Here is a part of the code:
% --- Plot everything on the same axes
hold on
% --- Plot the unit circle:
theta = linspace(0, 2*pi, 360);
plot(cos(theta), sin(theta), 'k--');
% --- Plot the blue points
x = [0.2 0.4 0.4 0.8];
y = [0.4 0.2 0.8 0.4];
scatter(x, y, 'bs');
% --- Plot the red points:
x = [0.4 0.8];
y = [0.4 0.8];
scatter(x, y, 'ro');
There are still many modifications to do to get the final plots, but at least this is a starting point.
Second edit
To answer your question about the intersection of a line and a circle, you have to start with the maths behind. Line and circle are defined by the following equations:
y = a.x + b % Cartesian definition of a line
(x-x0)² + (y-y0)² = r² % Cartesian definition of a circle
If you combine the two, you realize that finding the intersection is similar to finding the solution of:
(a²+1).x² + 2(a(b-y0)-x0).x + x0²+(b-y0)²-r² = 0
i.e. the roots of a polynom. As this is a trinom, there are 3 possibilities: 0 solution (no intersection), 1 solution (line is tangent to the circle) and 2 solutions (line crossing the circle).
So, in practice you have to:
Get the parameters a, b, x0, y0 and r of your problem
Find the roots of the polynom (for instance, with the function roots)
Decide what to do based on the number of roots.
Hope this helps,
%% Construct polar grid (put inside another function)
range = 0.2:0.2:1;
n = 50;
for i=1:length(range)
ro = ones(1,n);
ro = ro.*range(i);
th = linspace(0,pi*2,n);
[xx,yy] = pol2cart(th,ro);
plot(xx,yy, 'color',[.9 .9 .9]), grid on, hold on
n = round(n * 1.5);
end
%% Plot like normal
x1 = [.2 .4 .4 .8];
y1 = [.4 .2 .8 .4];
x2 = [.4 .8];
y2 = [.4 .8];
plot(x1,y1, 'bx',...
x2,y2, 'ro');
xlim([-.05 1]);
ylim([-.05 1]);

How to plot a intersection operation on two vectors MatLab

I'm trying to represent a the intersection of two fuzzy sets as a 3d mesh in MatLab.
Here are my sets of vectors:
x = [0.3 0.5 0.7]
y = [0.5 0.7 0.1]
Followed by these statements:
[u,v] = meshgrid(x,y)
w = min(u,v)
mesh(u,v,w)
The x and y ticks seem to be all over the place and do not correlate to the actual index number of each vector i.e. 1 to 3, and the graph should represent the shape of a small triangle/T-norm.
At the moment it looks like this:
Here is an example out of my book I'm following:
Ignore what looks like fractions, they are delimiters. Here is the resulting graph:
After looking up fuzzy sets and intersections, here's what I've come up with. First, let's reproduce the textbook example:
% possible values and associated degrees of truth for F
Fv = 1 : 5;
Ft = [0 0.5 1 0.5 0];
% possible values and associated degrees of truth for D
Dv = 2 : 4;
Dt = [0 1 0];
% determine degrees of truth for fuzzy intersection
It = bsxfun(#min, Ft', Dt);
% plot
h = mesh(Dv, Fv, It);
set(h, 'FaceColor', 'none')
set(h, 'EdgeColor', 'k')
xlim([0 4.5])
ylim([0 5])
xlabel D
ylabel F
view(37.5, 30)
The result is:
Not as pretty as in your book, but the same thing.
Applying the same code to your example yields:
Via the arguments u,v you are telling mesh to use the values in them, i.e. the values from x and y, for the positioning of the data points and corresponding ticks. If you just want positions and ticks at 1, 2, 3, leave these arguments out.
mesh(w)

quiver not drawing arrows just lots of blue, matlab

Can somebody tell me what I am doing wrong with the quiver plotting function when I don't really get arrows, it just fills the empty space with lots of blue.Look at the image below and then look at my code.
This is just a part of my contour since this eats up proccessing power if I try to draw it larger. But my function, the contours and everything else works, it's just the quiver I'm having trouble with.
interval = -100:100;
[X Y] = meshgrid(interval, interval);
h = figure;
contour(X, Y, Z);
hold on;
[FX,FY] = gradient(-Z);
quiver(X, Y, FX, FY);
hold off;
If I make my matrix more sparse, e.g. with "interval = linspace(-800, 1600, 1200);" the result will look like this:
EDIT:
What I need are contour lines like that, but the arrows should flow with them. Right now these just look like dots, even if I zoom in further. If I zoom out the entire window will be blue.
Here is the script in its entirety if anyone wants to play with it to figure this out.
m1 = 1;
m2 = 0.4;
r1 = [1167 0 0];
r2 = [-467 0 0];
G = 9.82;
w = sqrt( G*(m1+m2) / norm(r1-r2)^3 );
interval = linspace(-800, 1600, 1200);
% Element-wise 2-norm
ewnorm = #(x,y) ( x.^2 + y.^2 ).^(1/2);
% Element-wise cross squared
ewcross2 = #(w,x,y) w^2.*( x.*x + y.*y );
[X Y] = meshgrid(interval, interval);
Z = - G*m1 ./ ewnorm( X-r1(1), Y-r1(2) ) - G*m2 ./ ewnorm( X-r2(1), Y-r2(2) ) - 1/2*ewcross2(w,X,Y);
h = figure;
contour(Z);
daspect([1 1 1]);
saveas(h, 'star1', 'eps');
hold on;
[FX,FY] = gradient(-Z);
quiver(X, Y, FX,FY);
hold off;
The problem is that the mesh is too dense. You only want to have as few elements as necessary to generate a useful mesh. As such, try reducing the density of the mesh:
interval = -100:2:100
If you're going to be changing the limits often, you probably want to avoid using the X:Y:Z formulation. Use the linspace function instead:
interval = linspace(-100,100,10);
This will ensure that no matter what your limits, your mesh will be 10x10. In the comment below, you mention that the arrows are appearing as dots when you use a very large mesh. This is to be expected. The arrows reflect "velocity" at a given point. When your plot is scaled out to a very large degree, then the velocity at any given point on the plot will be almost 0, hence the very small arrows. Check out the quiver plot documentation, as well as the quivergroup properties, to see more details.
If you absolutely must see arrows at a large scale, you can try setting the AutoScale property to off, or increasing the AutoScaleFactor:
quiver(X, Y, FX, FY, 'AutoScale', 'off');
quiver(X, Y, FX, FY, 'AutoScaleFactor', 10);
You may also want to play with the MarkerSize and MaxHeadSize properties. I really just suggest looking at all the QuiverGroup properties and trying things out.
You could use a threshold
interval = -100:100;
[X Y] = meshgrid(interval, interval);
h = figure;
contour(X, Y, Z);
hold on;
[FX,FY] = gradient(-Z);
GM = sqrt(FX.^2 + FY.^2);
threshold = 0.1;
mask = GM > threshold;
quiver(X(mask), Y(mask), FX(mask), FY(mask));
hold off;
This will show only vectors with a magnitude > 0.1;

How do I plot confidence intervals in MATLAB?

I want to plot some confidence interval graphs in MATLAB but I don't have any idea at all how to do it. I have the data in a .xls file.
Can someone give me a hint, or does anyone know commands for plotting CIs?
After reading numerous threads, here's my attempt.
% Get some random data
x = linspace(0.3, pi-0.3, 10);
Data = sin(x) + randn(1, 10)/10;
Data_sd = 0.1+randn(1,10)/30;
% prepare it for the fill function
x_ax = 1:10;
X_plot = [x_ax, fliplr(x_ax)];
Y_plot = [Data-1.96.*Data_sd, fliplr(Data+1.96.*Data_sd)];
% plot a line + confidence bands
hold on
plot(x_ax, Data, 'blue', 'LineWidth', 1.2)
fill(X_plot, Y_plot , 1,....
'facecolor','blue', ...
'edgecolor','none', ...
'facealpha', 0.3);
hold off
Mostly based on this question: Plotting with transparency
I'm not sure what you meant by confidence intervals graph, but this is an example of how to plot a two-sided 95% CI of a normal distribution:
alpha = 0.05; % significance level
mu = 10; % mean
sigma = 2; % std
cutoff1 = norminv(alpha, mu, sigma);
cutoff2 = norminv(1-alpha, mu, sigma);
x = [linspace(mu-4*sigma,cutoff1), ...
linspace(cutoff1,cutoff2), ...
linspace(cutoff2,mu+4*sigma)];
y = normpdf(x, mu, sigma);
plot(x,y)
xlo = [x(x<=cutoff1) cutoff1];
ylo = [y(x<=cutoff1) 0];
patch(xlo, ylo, 'b')
xhi = [cutoff2 x(x>=cutoff2)];
yhi = [0 y(x>=cutoff2)];
patch(xhi, yhi, 'b')
See e.g. these m-files on Matlab File Exchange:
plot confidence intervals
confplot