Stuart’s MATLAB Videos

Watch and Learn

Coloring a line based on height, gradient, or some other value in MATLAB 8

Posted by Doug Hull,

MATLAB Answers is a great resource for getting help from the MATLAB community. There was a recent question that inspired this video. I took the question to mean, how can I change the color of a line to correspond with a third vector.

Here is my answer.

8 CommentsOldest to Newest

Brad Stiritz replied on : 1 of 8
Hi Doug, thanks for this interesting video. In your example, the goal appears to be to color 1-D points. What if we need to color actual 2-D line segments, as implied by your blog post title? Is there a simple way to achieve this, or will we have to construct a loop and manually color each line object? Thanks in advance.
Doug replied on : 2 of 8
@Brad, This is a good question. You would need to make each segment independently. I was actually going to start with that when I saw the question posted but realized this was pre-built. Seems like next week's topic is now picked!
Amro replied on : 3 of 8
Here is a related question on Stack Overflow:
BjornG replied on : 4 of 8
@Brad: In the matlab file exchange there are at least 2 functions that does that for you. To find them look for cline.
Julian replied on : 5 of 8
Base MATLAB has always offered colour 3-D plots, based on height, gradient or some other value, out of the box, using the builtin surface, as used in the popular example peaks. For 2-D plots, the only option seems to be scatter which is fine if you want a scatter plot with separate points but no good for a line plot. Faced with this problem quite some years ago I coded my own solution which used multiple lines for segment of a curve, allowing each line to be a distinct colour. More recently I spotted a very useful trick with this entry "Colored line or scatter plot" on the FEX. surface() will render 2-D lines, as a special case of 3-D, but you must pass into matrix valued data to make it work, so you have to duplicate the vector:
%% Some Data
x = linspace(0, 2*pi)';
y = sin(x);
plot(x, y); % a basic monochrome plot

%% Trick surface into a 2-D plot
surface('XData', [x x],             ... % N.B.  XYZC Data must have at least 2 cols
        'YData', [y y],             ...
        'ZData', zeros(numel(x),2), ...
        'CData', [y y],             ...
        'FaceColor', 'none',        ...
        'EdgeColor', 'interp',      ...
        'Marker', 'none');
Pekka replied on : 6 of 8
Coloring a line is more than slightly misleading here. You use scatter, which creates a separate patch object for each data point (until 2014a). That is horrible for anything more than "a few" elements. I have requested to have CData property for line objects quite a few times since maybe1995. Since it still has not happened I have also used surface to act as a line. color_line in file exchange.
Doug replied on : 7 of 8
Pekka, I mostly used that terminology because the people looking for something like this would not be googling for patch object, they would be googling for words in my title. I agree, this does not scale to big sizes well, but for the right situations, this is a decent solution. Doug
Joe replied on : 8 of 8

Thank you. I have looked for something like your surface trick for a long time. That works well, is fast and tolerates NaNs in the Cdata. For a case with N points and N-1 segments between them, I modified it to, e.g., [x(1:(end - 1)) x(2:end)] for Xdata, which also works.