3D line multiple colors - excel

I need help with Matlab.
I have an Excel sheet with three columns: X, Y and Z. I have used plot3 function to make one 3D curve.
But I need to vary it in colors.
What function/functions do I need to make X, Y and Z in different 3 colors(each column one color)?
Could you please send me link, where I can find out the way, or just write the function/functions needed for it?
Here is the code:
VCG=xlsread('VCGsheet.xls');
figure(1)
plot3(VCG(:,1),VCG(:,2),VCG(:,3));
grid on
I know that plot3 isn't suitable for it.

I'm not aware of a native command that draws line with varying color.
I will also assume that VCG vector is a vector of RGB values, so one color per row.
RGB = VCG(:,1:3);
If you want, you can replace it (VCG(:,1:3)) with any other vector of color derived from your data. Here is an example if you have a single value that can be calculated for each of your points, in the vector T for example, and that you want to show as a color.
map = jet(256);
RGB = map(round((T(:)-min(T(:)))/(max(T(:)) - min(T(:)))*255)+1,:);
For the plot, I propose two different ways:
you can make use of the scatter3 function
It will print points, but no lines connecting the points. The color vector is set with VCG(:,1:3)
colormap('jet')
scatter3(VCG(:,1), VCG(:,2), VCG(:,3), 70, RGB, 'filled');
You can make a direct use of line in a for loop.
It is a bit slower, but it is generally ok for graphs.
for i=2:size(VCG,1)
line(VCG(i-1:i,1), VCG(i-1:i,2), VCG(i-1:i,3), 'color', RGB(i-1,:));
end
If you want both, just use the hold function
I hope I understood what you needed !

Related

Computing the area filled by matplotlib.pyplot.fill(...)

I'd like to compute the area inside of a curve defined by two vectors a and b. For your reference the curve looks something like this (pyplot.plot(a,b)):
I saw matplotlib has a fill functionality that let you fill the area enclosed by the curve:
I'm wondering, there's any way to obtain the area filled using that same function? It would be very useful as the other way I'm thinking of computing that area is through numerical integration, much more cumbersome.
Thank you for your time.
If you really want to find the area that was filled by matplotlib.pyplot.fill(a, b), you can use its output as follows:
def computeArea(pos):
x, y = (zip(*pos))
return 0.5 * numpy.abs(numpy.dot(x, numpy.roll(y, 1)) - numpy.dot(y, numpy.roll(x, 1)))
# pyplot.fill(a, b) will return a list of matplotlib.patches.Polygon.
polygon = matplotlib.pyplot.fill(a, b)
# The area of the polygon can be computed as follows:
# (you could also sum the areas of all polygons in the list).
print(computeArea(polygon[0].xy))
This method is based on this answer,
and it is not the most efficient one.

Python3 - Interpolate many arrays of varied lengths

I have about 100 spectra that I need to eventually interpolate onto a single x-axis range. The data are stored as a "velocity" array of 100 sub-arrays, and a "flux" array of 100 sub-arrays. Each sub-array has a different length (in this particular case varying from about 100 to 1700), that eventually need to be interpolated onto a single velocity range, for comparison and plotting purposes. Currently, I have been trying to interpolate the arrays with respect to the shortest-length array (i.e. 100 in this case), resulting in my code looking something like this:
lengths=[len(VELOCITY[i]) for i in range(len(VELOCITY))]
minlen=min(lengths)
idx = np.where(np.asarray(lengths) == minlen)[0][0]
vel_new = np.linspace(VELOCITY[idx][0], VELOCITY[idx][-1],num=len(VELOCITY[idx]), endpoint=True)
for i in range(len(VELOCITY)):
interp = interp1d(VELOCITY[i], FLUX[i], kind='cubic', fill_value='extrapolate')
flux.append(interp(vel_new))
flux = np.asarray(flux)
However, the resulting plot isn't quite what I expect, with what I can only assume is extrapolated points from the interpolation becoming dominant. I'm surprised by this, considering I selected the smallest velocity array, and thus the extrapolation should be minimal.
My question is, am I going about the interpolation incorrectly? Alternatively, do you have a suggestion for a better method than the one I am pursuing? Thanks in advance for your feedback!

MATLAB: Plotting only ponts with colorbar based on another variable

I want to plot only data points. Now I can plot the points which only considers 1 type of point. But my data contains different column variables. I want to plot different figures with different x and y variables from the data. Suppose I want to plot variable D against variable A or variable E against variable year but I want to plot data points with different colors or different types of points either *, dot, diamond etc. based on suppose, variable pub or variable E. Now for colormap I want to show colormap beside the figure with where the range of the variable value will be shown. For different type of points the point indexes will be suppose another variable E.
Also the 1st data should have a completely different point so that it can be distinguishable. My code actually shows different point for that data but it also plots with others.
Here is the truncated data.
Can anyone help me with that?
My code:
T = readtable('Data.xlsx');
year = T.Year;
pub = T.Publication;
A = T.A;
B = T.B;
C = T.C;
D = T.D;
E = T.F;
% Plot Data
f = figure;
%hold on; grid on, box on;
plot(A, D,'*')
hold on;
plot(A(1), D(1),'d')
It feels like this matlab example should be pretty close to what you want. It is a scatter plot (like your plot(A,D,'*') command), and has a colour scale that varies with a third variable c.
You should then combine this with a hold on command and plotting the first point using a different style suitable to your liking. You could something along the lines of the following (I have not downloaded your data, so I will use the example from the matlab link I provided):
x = linspace(0,3*pi,200); % Independent variable
y = cos(x) + rand(1,200); % Dependent variable
c = linspace(1,10,length(x)); % Colour variable
% Plot all points except the first one using colours in c and size 50:
scatter( x(2:end), y(2:end), 50, c(2:end) );
hold on
% Plot first point differently: twice the size, and with a filled marker:
scatter( x(1), y(1), 100, c(1), 'filled');
legend({'Data','First point'});
hold off

Matlab colormap reproducing gnuplot pm3d 30,31,32 RGB colour space

I am trying to implement a colorbar in Matlab that looks linear when printed in grey. The most straight forward approach I though would be to implement the gnuplot pm3d 30,31,32 RGB colour space. On this website I found a good introduction, which works OK for some of the easier gnuplot schemes. However, when trying to implement the 30,31,32 scheme I run into trouble.
The gnuplot instructions are
30: x/0.32-0.78125 31: 2*x-0.84 32: 4x;1;-2x+1.84;x/0.08-11.5
And I interpreted this such that for the blue channel I have to apply four different equations. One for each quarter of intensity values. This is what I have tried so far
x = linspace(0,1,128);
r = x/0.32-0.78125;
g = 2*x-0.84;
b(1:length(x)/4) = 4*x(1:length(x)/4);
b(length(x)/4:length(x)/2) = 1;
b(length(x)/2:length(x)*.75) = -2*x(length(x)/2:length(x)*.75)+1.84;
b(length(x)*.75:end) = x(length(x)*.75:end)/0.08-11.5;
pm3d303132=[r;g;b]';
but unfortunately it doesn't work. I end up with negative values and values that exceed 1, which Matlab cannot interpret.
I did read in the show palette rgbformulae help that
* negative numbers mean inverted=negative colour component
But I don't know how to implement this in Matlab; and I also don't understand how to deal with values exceeding 1. Can anyone help?
Ignoring the out of bound values seems to work. (http://juluribk.com/2011/05/18/843/)
pm3d303132(pm3d303132<0)=0;
pm3d303132(pm3d303132>1)=1;

How do I set a surf to one color (no gradient) in my matlab-plot?

My dataset consists of three vectors (x,y and z). I plot these values as dots in a 3d-plot with plot3(x,y,z), which is fine. I also want to show a plane in the same plot. To get the data of this plot I use linear regression on x and y to get a new z.
This is how it looks:
(source: bildr.no)
I want the surf to be filled with only one color (say light blue or gray) and set the opacity, to make it see-through. How can I do this?
The easiest way to create a surface that has just 1 color and a given transparency value is to set the 'FaceColor' and 'FaceAlpha' properties of the surface object:
hSurface = surf(...your arguments to create the surface object...);
set(hSurface,'FaceColor',[1 0 0],'FaceAlpha',0.5);
This example sets the surface color to be red and the transparency to 0.5. You can also set the edge properties too (with 'EdgeColor' and 'EdgeAlpha').
It is not clear to me what you want to do. When you say one color for the surf, do you mean exactly one color, or do you mean you want shades of gray?
Here is some code that will do a variety of things, you can choose which lines to use:
x = rand(1,20);
y = rand(1,20);
z = rand(1,20);
[X,Y] = meshgrid(linspace(0,1,10),linspace(0,1,10));
Z = rand(10)*0.1;
clf
plot3(x,y,z,'.');
hold on
h = surf(X,Y,Z)
hold off
%% This will change the color
colormap(copper)
%% This will remove colordata
set(h, 'cdata',zeros(10))
%% This will make transparent
alpha(0.5)
Completing the answer from gnovice, an extra ingredient in set(hsurface...) may be required (Matlab R2010b 64):
hSurface = surf(...your arguments to create the surface object...);
set(hSurface, 'FaceColor',[1 0 0], 'FaceAlpha',0.5, 'EdgeAlpha', 0);
to make invisible the point-to-point edges of the plotted surface
#matlabDoug has what you need, I think. The property cdata holds color data that gets a color map applied to it. Setting it to an array the same size as your surface data, with each element in that array having the same value, will make your surface one color. With the default color map, setting everything in cdata to zero will make your surface blue, and setting everything to 1 will make the surface red. Then you can play with the alpha to make it transparent.

Resources