plot3 line color based on value - matlab

I have a set of data that contains 3d Cartesian points (x, y, z) and a time stamp.
I would like to plot this data as a connected line in 3d space with the line colour changing based on the time stamp value.
Effectively i want to show the time difference in a colorbar.
Does anyone know of a way to do this?

Consider the following example of a 3D point moving along a helix-shaped path over time:
%# data
t = linspace(0,8*pi,200);
x = 20*t; y = cos(t); z = sin(t);
%# plot 3D line
plot3(x,y,z)
axis tight, grid on, view(35,40)
Now if you want to draw a multi-colored line, the naive solution would be to write a for-loop, drawing each small segment as a separate line, each having a different color. This is because a single line object can only have one color.
A better approach is to use a surface graphics object:
c = 1:numel(t); %# colors
h = surface([x(:), x(:)], [y(:), y(:)], [z(:), z(:)], ...
[c(:), c(:)], 'EdgeColor','flat', 'FaceColor','none');
colormap( jet(numel(t)) )
The result:

Related

How to mark a point (I have x,y,z for it) in a 3D big data scatter plot with different color using matlab?

I have two 3D volume images and I want to locate one point from the first image (I have specific x, y, and z values for this point) and mark it with a different color. I mean how I can insert the values of x, y, and z and get this point in my graph inside all the points with a different color.
Here are 2 options:
Option 1
Use hold to overlay another scatter only with the points you want to color differently:
data = rand(100,3); % some data
p = randi(100); % choose some point
scatter3(data(:,1),data(:,2),data(:,3),'Fill')
hold on
% here you plot only one point (p):
scatter3(data(p,1),data(p,2),data(p,3),'r','Fill')
hold off
Option 2
If you want to color more than one point, and/or use different colors for your points, it may be better to set the color by the point when you call scatter in the first time:
data = rand(100,3); % some data
p = randi(size(data,1),5,1); % choose some points
c = ones(size(data,1),1); % default color
c(p) = 2:(numel(p)+1); % set different color for each points in p
col = lines(numel(p)+1); % set the colormap for the points
scatter3(data(:,1),data(:,2),data(:,3),[],col(c,:),'Fill')
Assuming you're using scatter3, you can just make your scatterplot, then use "hold on" and add a scatterplot with your single point in a different color that will cover the original point, e.g.:
hold on;
scatter3(x,y,z,'MarkerEdgeColor','k','MarkerFaceColor',[0 .75 .75]);

visualizing 3d data volume in matlab

I have many points in 3d (x,y,z), and for each point I have it's disparity (0-10 value), different points can have the same disparity.
I want to plot this data that each point will have a color according to it's disparity.
I want it to be something like this picture: (small disparity will have one color, and as it's gets bigger the color changes)
how can I do it?
Use scatter3:
x = rand(1,1000);
y = rand(1,1000);
z = rand(1,1000); %// example x, y, z
d = x.^2+y.^2+z.^2; %// example disparity
scatter3(x,y,z,8,d,'fill');
colorbar
The fourth input argument to scatter3 is marker size. The fifth determines color. 'fill' uses filled markers.

Fill in points on an already existing line in matlab

Im trying to create a triangle wave in matlab with equal rise and fall slope.
I searched around abit and found a code example:
n=input ('Enter the length of the sequence N= ');
t=0:n;
y=(-1).^t;
stem(t,y);
ylabel ('Amplitude');
xlabel ('Time Index');
TITLE ('Triangular waveform');
This code creates the the triangle form, but there are only data plots at the tip of each triangle. I want more data plots that follow the lines of the triangles.
Is there any function in matlab that can fill in data points with a specific width between the plots in the plotted lines from the graph?
If no, how am I supposed to solve this?
You need to linearly interpolate:
t2 = 0:0.5:n;
y2 = interp1(t, y, t2);
where t and y are the arrays from your example. You can use any size of interval for t2:
t2 = 0:0.1:n;
for example.
Change t=0:n; to t=0:0.1:n; and y=(-1).^t; to y=2*abs(mod(t,2)-1)-1;
This is what I got:

Matlab extend plot over all axis range

I'm trying to use Matlab for some data plotting. In particular I need to plot a series of lines, some times given two points belonging to it, some times given the orthogonal vector.
I've used the following to obtain the plot of the line:
Line given two points A = [A(1), A(2)] B = [B(1), B(2)]:
plot([A(1),B(1)],[A(2),B(2)])
Line given the vector W = [W(1), W(2)]':
if( W(1) == 0 )
plot( [W(1), rand(1)] ,[W(2), W(2)])
else
plot([W(1), W(1) + (W(2)^2 / W(1))],[W(2),0])
end
where I'm calculating the intersection between the x-axis and the line using the second theorem of Euclid on the triangle rectangle formed by the vector W and the line.
My problem as you can see from the picture above is that the line will only be plotted between the two points and not on all the range of my axis.
I have 2 questions:
How can I have a line going across the whole axis range?
Is there a more easy and direct way (maybe a function?) to plot the line perpendicular to a vector? (An easier and more clean way to solve point 2 above.)
Thanks in advance.
Do you know the bounds of your axis for displaying the plot? If so, you can specify the range of the plot with the axis([xmin, xmax, ymin, ymax]) function.
So, from your question, if you know the slope m and intercept b, you can make sure your function plots the line across the whole window by specifying:
plot([xmin, xmax], [m*xmin + b, m*xmax + b]);
axis([xmin, xmax, min(m*xmin+b, m*xmax+b), max(m*xmin+b, m*xmax+b)]);
where xmin and xmax are values you specify as the range of your x-axis. This will make your line go from the corner of your plot to the other corner. If you want a buffer in the y-direction, then add one like so:
buffer = 5; % for example, you set this to something that looks good.
axis([xmin, xmax, min(m*xmin+b, m*xmax+b)-buffer, max(m*xmin+b, m*xmax+b)+buffer]);

MATLAB, Filling in the area between two sets of data, lines in one figure

I have a question about using the area function; or perhaps another function is in order...
I created this plot from a large text file:
The green and the blue represent two different files. What I want to do is fill in the area between the red line and each run, respectively. I can create an area plot with a similar idea, but when I plot them on the same figure, they do not overlap correctly. Essentially, 4 plots would be on one figure.
I hope this makes sense.
Building off of #gnovice's answer, you can actually create filled plots with shading only in the area between the two curves. Just use fill in conjunction with fliplr.
Example:
x=0:0.01:2*pi; %#initialize x array
y1=sin(x); %#create first curve
y2=sin(x)+.5; %#create second curve
X=[x,fliplr(x)]; %#create continuous x value array for plotting
Y=[y1,fliplr(y2)]; %#create y values for out and then back
fill(X,Y,'b'); %#plot filled area
By flipping the x array and concatenating it with the original, you're going out, down, back, and then up to close both arrays in a complete, many-many-many-sided polygon.
Personally, I find it both elegant and convenient to wrap the fill function.
To fill between two equally sized row vectors Y1 and Y2 that share the support X (and color C):
fill_between_lines = #(X,Y1,Y2,C) fill( [X fliplr(X)], [Y1 fliplr(Y2)], C );
You can accomplish this using the function FILL to create filled polygons under the sections of your plots. You will want to plot the lines and polygons in the order you want them to be stacked on the screen, starting with the bottom-most one. Here's an example with some sample data:
x = 1:100; %# X range
y1 = rand(1,100)+1.5; %# One set of data ranging from 1.5 to 2.5
y2 = rand(1,100)+0.5; %# Another set of data ranging from 0.5 to 1.5
baseLine = 0.2; %# Baseline value for filling under the curves
index = 30:70; %# Indices of points to fill under
plot(x,y1,'b'); %# Plot the first line
hold on; %# Add to the plot
h1 = fill(x(index([1 1:end end])),... %# Plot the first filled polygon
[baseLine y1(index) baseLine],...
'b','EdgeColor','none');
plot(x,y2,'g'); %# Plot the second line
h2 = fill(x(index([1 1:end end])),... %# Plot the second filled polygon
[baseLine y2(index) baseLine],...
'g','EdgeColor','none');
plot(x(index),baseLine.*ones(size(index)),'r'); %# Plot the red line
And here's the resulting figure:
You can also change the stacking order of the objects in the figure after you've plotted them by modifying the order of handles in the 'Children' property of the axes object. For example, this code reverses the stacking order, hiding the green polygon behind the blue polygon:
kids = get(gca,'Children'); %# Get the child object handles
set(gca,'Children',flipud(kids)); %# Set them to the reverse order
Finally, if you don't know exactly what order you want to stack your polygons ahead of time (i.e. either one could be the smaller polygon, which you probably want on top), then you could adjust the 'FaceAlpha' property so that one or both polygons will appear partially transparent and show the other beneath it. For example, the following will make the green polygon partially transparent:
set(h2,'FaceAlpha',0.5);
You want to look at the patch() function, and sneak in points for the start and end of the horizontal line:
x = 0:.1:2*pi;
y = sin(x)+rand(size(x))/2;
x2 = [0 x 2*pi];
y2 = [.1 y .1];
patch(x2, y2, [.8 .8 .1]);
If you only want the filled in area for a part of the data, you'll need to truncate the x and y vectors to only include the points you need.