2

Is it possible to change the colour of a line, mid-plot, in matlab?

I am developing an ant colony optimisation algorithm in matlab, and i would like to be able to represent the trail intensities of different paths as different colours in the visualisation

Here is the plot I am generating:

ACO graph

The trail part of the graph is generated by the following code:

[Xt,Yt] = gplot(trails,XY,'-w'); % gplot does not allow custom colours
plot(Xt,Yt,'-o','Color',[0.75,0.75,0.75],...
    'MarkerFaceColor',[0.75,0.75,0.75],'LineWidth',2);

I have a matrix containing intensity values for each edge, and i would like to be able to change the [0.75,0.75,0.75] value for the line colour to some scaled value, based on the line intensity.

Is there a way to do this by making the colour value a function of some variable? or would i have to plot each line individually?

EDIT:

here is some sample data:

NODES: 4
<node x,y coords>
N1(10,10)
N2(82,19)
N3(38,77)
N4(30,150)

EDGES: 4
<edges connecting Na and Nb, T is intended greyscale luminance value>
E1(N1,N2) - T = 0.7  
E2(N1,N3) - T = 0.3
E3(N2,N3) - T = 0.6
E4(N3,N4) - T = 0.4

Here is a plot of the graph with random T values:

tiny test graph

guskenny83
  • 1,321
  • 14
  • 27
  • As I detail in this [answer](http://stackoverflow.com/questions/31685078/change-color-of-2d-plot-line-depending-on-3rd-value/31699594#31699594), I would suggest using a (thin) surface instead of a line, you get total control of the way the lines are colored (including `flat` or `interp` transitions). Then on top of that, you could add a `scatter` plot, which would also give you control over the color/shape/size of each point. – Hoki Sep 29 '15 at 15:21
  • If you do stick with lines, you'll need to plot each sub-trail separately and (in each iteration thru some loop) assign a color from some lookup table of colors which map to your trail intensities. This is much easier to do in `R`, btw. – Carl Witthoft Sep 29 '15 at 16:14
  • Could you add a small set of sample data ? (post an [mcve] please). – Hoki Sep 30 '15 at 08:10

2 Answers2

3

You can use a surface which looks like a line by replicating all the 2D input vectors (x and y) in order to have matrices. These matrices can be used to generate a surface object, which allow a lot more control over the line and point colours, thanks to the CData property.

First I have to generate sample data:

%% // sample gplot data (from matlab documentation example)
reset(groot) %// optional, only if you modified the default groot properties previoulsly
k = 1:30;
[B,XY] = bucky;
[xt, yt] = gplot( B(k,k),XY(k,:) ) ;

%% // sample custom properties (point/line colors)
nColor = 16 ;                    %// to start with low number of colors
c = randi([1 nColor],size(xt)) ; %// random colors for each point

Now we have a set of points and a scalar value (intensity or anything else) to be color coded in the display. We can use a surface object to take all these parameters into account in one single graphic object:

%% // create 'Matrix' style input from 2D line data
X = [xt,xt] ;                       %// replicate column vector "xt"
Y = [yt,yt] ;                       %// same for "yt"
C = [c c] ;                         %// replicate column vector "c"
Z = zeros(size(X)) ;                %// Z plane = 0

%% // DISPLAY - Surf only
figure
hs = surf(X,Y,Z,C,'EdgeColor','interp','FaceColor','none','Marker','*','LineWidth',1.5) ;
colormap(hsv(nColor)) %// choose a more distintive colormap (any other colormap will work)
colorbar
view(2)

Of course, you can choose the colormap that best fit your needs (very progressive colormap or very distinct). These 2 types of colormap will lend themselves more to a different type of shading.

You can also choose how the colour information will be handled for each line:

  • shading flat => One solid color for the full line, or
  • shading interp => a gradient of color between the 2 anchor points.

Below is an example with 16 colors for 2 different colormap (hsv and gray), with the different shading settings. enter image description here


This should give you the maximum control over the appearance of your lines, with only one graphic object to handle (of course you could always draw each line separately and set the custom properties but you will need a loop and a lot of graphic objects).

If you want even further control for the points, you can forget about the markers of the surface object, and superimpose a scatter plot to display the points. This would give you extra options on the point appearance. Below is a quick example on how to do that, check the scatter documentation for more usage example.

%% // DISPLAY - Surf and Scatter
figure
hs = surf(X,Y,Z,C,'EdgeColor','interp','FaceColor','none','Marker','none') ;
hold on
hp = scatter(xt,yt,25,c,'filled','LineWidth',1.5) ;
colormap(hsv(nColor)) %// choose a more distintive colormap (any other colormap will work)
colorbar
view(2)

Documentation:

Community
  • 1
  • 1
Hoki
  • 11,637
  • 1
  • 24
  • 43
  • Thanks for your response, i can get it to work fine with random colours, but I can't quite work out how to generate the c vector where edge(i,j) is a certain value.. i will update my question with a small set of data for a 4 point graph – guskenny83 Oct 06 '15 at 04:42
1

You can do this with the plot command by manipulating the ColorOrder property:

A = rand(10) > .5;
xy = rand(10,2);
[xt, yt] = gplot(A, xy);

c = bone(size(xt,1)/3); % your colors here

set(0,'defaultAxesColorOrder', c);
plot(reshape(xt, 3, []), reshape(yt, 3, []));

The result of the reshaping is that you get many line objects rather than a single one, which might be slow if you have many nodes.

(If you have a Matlab version > 2014b, MathWorks recommends using groot instead of 0 as the root object handle.)

Tokkot
  • 1,215
  • 7
  • 22
  • Interestingly (or not :-) ) , under Matlab 2012, the `set` command fails. I get lots of different colors across the rainbow. Possibly `groot` doesn't exist in versions prior to 2015. – Carl Witthoft Sep 30 '15 at 11:31
  • 1
    @CarlWitthoft, yes, the `groot` object is relatively recent. Try to use `0` instead: `set(0,'defaultAxesColorOrder', c);` – Hoki Sep 30 '15 at 11:33
  • @Hoki Thanks, I edited the answer to use `0` instead of `groot`, since `0` still works at least in 2015a. – Tokkot Sep 30 '15 at 11:38
  • @Tokkot, nice. Since you're modifying your post may be you could make an explicit mention of that. Something like "if you have a Matlab version > 2014b, it is recommended (_by MathWorks_) to use `groot` instead of `0` as the root object handle" – Hoki Sep 30 '15 at 11:40