# Coloring a line based on height, gradient, or some other value in MATLAB8

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.

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

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!

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

Julian,

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.