Assigning Different Colors to a Plot / Scatter - matlab

So I have a vector called C1_Vector that has been previously filled with different shades of 1 RGB color ([0 0.5 1]), blue. So there are many different vectors within the C1_Vector
ex:
C1_Vector = ([0 0.5 1], [0 0.45 0.98], [0 0.49 1.01], etc.)
I want to each one of my points, in s1, to correspond to a different color. This is what I've been playing around with, and struggling with. Can someone help me with this syntax?
plot(s1(1,:),s1(2,:),'.', 'color', C1_Vector );
where,
s1 =
3.0000 3.0000 3.0000 1.5000 1.5000 1.5000 0 -1.5000
1.5000 0 -1.5000 1.5000 0 -1.5000 0 3.0000

Using the scatter function makes it quite easy as long as you provide the same number of color vectors than element to plot.
Basically for each pair of points to display the function assign it the corresponding color in the color matrix provided, which is M x 3 where M is the number of points.
Therefore for the demo I added colors to C1_Vector so that it contains as many elements as s1.
C1_Vector = [0 0.5 1; 0 0.45 0.98; 0 0.49 1.01;1 0 1; rand(1,3); 0 1 0; 0 1 1;rand(1,3)];
s1 = [3.0000 3.0000 3.0000 1.5000 1.5000 1.5000 0 -1.5000;
1.5000 0 -1.5000 1.5000 0 -1.5000 0 3.0000];
scatter(s1(1,:),s1(2,:),[],C1_Vector,'filled')
grid on
Output:
Is that what you meant?

Related

Fill convex area between 3D points in Matlab

I have a collection of 3D points in Matlab
PY=0.5000 0 0.5000;
0.5000 0.1250 0.3750;
0.5000 0.2500 0.2500;
0.5000 0.3750 0.1250;
0.6250 0 0.3750;
0.6250 0.1250 0.2500;
0.6250 0.2500 0.1250;
0.6250 0.3750 0;
0.7500 0 0.2500;
0.7500 0.1250 0.1250;
0.7500 0.2500 0];
These points are parts of the unit simplex
close all
patch([0 0 1],[0 1 0],[1 0 0],[0.8 0.8 0.8]);
axis equal
axis([0 1 0 1 0 1])
view(120,30)
hold on
scatter3(PY(:,1), PY(:,2), PY(:,3))
Question: I would like to fill the convex region that one gets by connecting these points. I'm unable to do that. Could you help?
This is what I tried
1) CHPY=convhull(PY(:,1),PY(:,2),PY(:,3) );
which gives me as error
Error computing the convex hull. The points may be coplanar or collinear.
2)
T = delaunayTriangulation(PY);
K = convexHull(T);
which gives me as error
Error using delaunayTriangulation/convexHull
The triangulation is empty.

Solve System of Linear Equations in MatLab with Matrix of Arbitrary Size for Finite Difference Calculation

I am trying to write a script in MatLab R2016a that can solve a system of linear equations that can have different sizes depending on the values of p and Q.
I have the following equations that I am trying to solve, where h=[-p:1:p]*dx. Obviously, there is some index m where h=0, but that shouldn't be a problem.
I'm trying to write a function where I can input p and Q and build the matrix and then just solve it to get the coefficients. Is there a way to build a matrix using the variables p, Q, and h instead of using different integer values for each individual case?
I would use bsxfun(in recent matlab versions this function may be implented to the interpreter, I don't know for sure):
p = 4;
Q = 8;
dx = 1;
h = -p:p*dx
Qvector = [Q,1:Q-1]'
Matrix = bsxfun(#(Qvector, h)h.^(Qvector)./factorial(Qvector), Qvector, h)
Output:
h =
-4 -3 -2 -1 0 1 2 3 4
Qvector =
8
1
2
3
4
5
6
7
Matrix =
1.6254 0.1627 0.0063 0.0000 0 0.0000 0.0063 0.1627 1.6254
-4.0000 -3.0000 -2.0000 -1.0000 0 1.0000 2.0000 3.0000 4.0000
8.0000 4.5000 2.0000 0.5000 0 0.5000 2.0000 4.5000 8.0000
-10.6667 -4.5000 -1.3333 -0.1667 0 0.1667 1.3333 4.5000 10.6667
10.6667 3.3750 0.6667 0.0417 0 0.0417 0.6667 3.3750 10.6667
-8.5333 -2.0250 -0.2667 -0.0083 0 0.0083 0.2667 2.0250 8.5333
5.6889 1.0125 0.0889 0.0014 0 0.0014 0.0889 1.0125 5.6889
-3.2508 -0.4339 -0.0254 -0.0002 0 0.0002 0.0254 0.4339 3.2508

Summing cumulative area under curves of overapping triangles

I have two matrices for several triangles:
x =
2.0000 5.0000 10.0000
8.0000 10.0000 12.0000
12.0000 24.0000 26.0000
22.0000 25.0000 28.0000
23.0000 26.0000 25.0000
23.5000 27.0000 27.5000
20.0000 23.0000 27.0000
21.0000 24.0000 27.0000
24.0000 25.0000 27.0000
24.0000 26.0000 27.0000
24.0000 28.0000 29.0000
19.0000 22.0000 25.0000
18.0000 21.0000 23.0000
y =
0 1.0000 0
0 0.8000 0
0 0.6000 0
0 0.8000 0
0 0.8000 0
0 0.8000 0
0 1.0000 0
0 1.0000 0
0 1.0000 0
0 1.0000 0
0 1.0000 0
0 1.0000 0
0 1.0000 0
one line is one triangle. Columns are x and y positions of each point of the triangles.
So, I plot all these triangles and I need to sum the cumulative area under the curve of the triangles.
I try to use the area function, but I couldn't find how to sum their areas.
EDIT: I need to plot the sum of the areas on a red line in the same graphics. So I don't want a number like 20 cm²... I would like something like that:
I suggest that you interpolate to create all your individual triangles and then add the results. First you will need to augment your x and y matrices with the beginning (the origin) and end points like so:
m = 30; %// This is your max point, maybe set it using max(x(:))?
X = [zeros(size(x,1),1), x, ones(size(x,1),1)*m];
Y = [zeros(size(y,1),1), y, zeros(size(y,1),1)];
then perform all the interpolations (I'll sum as I go):
xi = 0:0.1:m;
A = zeros(1,size(xi,2)); %// initialization
for row = 1:size(x,1)
A = A + interp1(X(row,:), Y(row,:), xi);
end
and finally plot:
plot(x,y,'k')
hold on
plot(xi,A,'r','linewidth',2)
using your example data this gives:

Blockdiagonal variation grid

I have the feeling I am missing something intuitive in my solution for generating a partially varied block-diagonal grid. In any case, I would like to get rid of the loop in my function (for the sake of challenge...)
Given tuples of parameters, number of intervals and percentage variation:
params = [100 0.5 1
24 1 0.9];
nint = 1;
perc = 0.1;
The desired output should be:
pspacegrid(params,perc,nint)
ans =
90.0000 0.5000 1.0000
100.0000 0.5000 1.0000
110.0000 0.5000 1.0000
100.0000 0.4500 1.0000
100.0000 0.5000 1.0000
100.0000 0.5500 1.0000
100.0000 0.5000 0.9000
100.0000 0.5000 1.0000
100.0000 0.5000 1.1000
21.6000 1.0000 0.9000
24.0000 1.0000 0.9000
26.4000 1.0000 0.9000
24.0000 0.9000 0.9000
24.0000 1.0000 0.9000
24.0000 1.1000 0.9000
24.0000 1.0000 0.8100
24.0000 1.0000 0.9000
24.0000 1.0000 0.9900
where you can see that the variation occurs at the values expressed by this mask:
mask =
1 0 0
1 0 0
1 0 0
0 1 0
0 1 0
0 1 0
0 0 1
0 0 1
0 0 1
1 0 0
1 0 0
1 0 0
0 1 0
0 1 0
0 1 0
0 0 1
0 0 1
0 0 1
The function pspacegrid() is:
function out = pspacegrid(params, perc, nint)
% PSPACEGRID Generates a parameter space grid for sensitivity analysis
% Size and number of variation steps
sz = size(params);
nsteps = nint*2+1;
% Preallocate output
out = reshape(permute(repmat(params,[1,1,nsteps*sz(2)]),[3,1,2]),[],sz(2));
% Mask to index positions where to place interpolated
[tmp{1:sz(2)}] = deal(true(nsteps,1));
mask = repmat(logical(blkdiag(tmp{:})),sz(1),1);
zi = cell(sz(1),1);
% LOOP per each parameter tuple
for r = 1:sz(1)
% Columns, rows, rows to interpolate and lower/upper parameter values
x = 1:sz(2);
y = [1; nint*2+1];
yi = (1:nint*2+1)';
z = [params(r,:)*(1-perc); params(r,:)*(1+perc)];
% Interpolated parameters
zi{r} = interp2(x,y,z, x, yi);
end
out(mask) = cat(1,zi{:});
I think I got it, building off your pre-loop code:
params = [100 0.5 1
24 1 0.9];
nint = 1;
perc = 0.1;
sz = size(params);
nsteps = nint*2+1;
% Preallocate output
out = reshape(permute(repmat(params,[1,1,nsteps*sz(2)]),[3,1,2]),[],sz(2));
%Map of the percentage moves
[tmp{1:sz(2)}] = deal(linspace(-perc,perc,nint*2+1)');
mask = repmat(blkdiag(tmp{:}),sz(1),1) + 1; %Add one so we can just multiply at the end
mask.*out
So instead of making your mask replicate the ones I made it replicate the percentage moves each element makes which is a repeating pattern, the basic element is made like this:
linspace(-perc,perc,nint*2+1)'
Then it's as simple as adding 1 to the whole thing and multiplying by your out matrix
I tested it as follows:
me = mask.*out;
you = pspacegrid(params, perc, nint);
check = me - you < 0.0001;
mean(check(:))
Seemed to work when I fiddled with the inputs. However I did get an error with your function, I had to change true(...) to ones(...). This might be because I'm running it online which probably uses Octave rather than Matlab.

How to apply indices I got from one row to other rows in matlab?

Let say if I have this data
my_data = [ 10 20 30 40; 0.1 0.7 0.4 0.3; 6 1 2 3; 2 5 4 2];
my_index = logical(my_data(4,:)==2);
What is the simplest way to use 'my_index' to give this output
10.0000 40.0000
0.1000 0.3000
6.0000 3.0000
2.0000 2.0000
my_data(:,my_index)
but I'm suspicious that this is so simple that it doesn't satisfy your (background) requirements ...