Plot an interactive circular graph to illustrate connections in a network in MATLAB.
[row2,col2,v2] = find(correlationMatrix); %v2 will create Nx1 matrix of all correaltion values
diag = tril(correlationMatrix);
for n = 1:size(diag,1)
v2(n,1) = max(diag(n,:));
Follow up to my comment. Change both instances of
For those of you who want to control the line colors based on correlation value I have found a solution
Add a second input to the function call to include another matrix (ignore if only using one matrix, just replace correlationMatrix with adjacencyMatrix or matrix of your choice)
>function this = circularGraph(adjacencyMatrix,correlationMatrix, varargin)
After the line
>p = inputParser;
Paste the following to convert your assembled array of correlation values into instance-ordered RGB values:
>[row2,col2,v2] = find(correlationMatrix); %v2 will create Nx1 matrix of all correaltion values
>map = colormap(hot); %intialize colormap, change the color map scheme to one of your choice
>minv = min(v2(:)); %min max to establish bounds of colormap
>maxv = max(v2(:));
>ncol = size(map,1);
>s = round(1+(ncol-1)*(v2-minv)/(maxv-minv)); %scale indicies for conversion
>rgb_image = ind2rgb(s,map); %convert scaled indicies to RGB, gives Nx1X3 matrix
>defaultColorMap = reshape(rgb_image, [length(v2) 3]); %reshape into Nx3 matrix
Change current line 46 (will become line 54)
>addParameter(p,'ColorMap',defaultColorMap,@(colormap)length(colormap) == length(adjacencyMatrix));
>addParameter(p,'ColorMap',defaultColorMap,@(colormap)length(colormap) == length(defaultColorMap));
and current line 121 (will become line 130)
You can also create a custom colormap that is the length of the number of node connections you have and feed that into the the code (might require changing a couple lines). Hope this helps!
@Richard Thank you for fixing the lines outside disk bug!
For others, comment out this section:
if u(1) >= 0 && v(1) >= 0
% ensure the arc is within the unit disk
theta = [linspace(max(thetaLim),pi,50),...
theta = linspace(thetaLim(1),thetaLim(2)).';
And instead replace with this:
theta = linspace(thetaLim(1),thetaLim(2)).';
Hi, is there a way to adjust the colormap range from -1 to 1 while plotting the correlation coefficients?
thanks for the function, i really like it. is there a way to turn off the buttons? i tried to comment the respective parts of the code out, but somehow it doesn't affect the appearance... thanks!
Hi, is there any way to change the font size of the node numbers all at the same time without having to do them individually?
Hi , when I create a new label it is just overwriting it. How do I delete default labels first? New to matlab.
Thanks for sharing, cannot wait to try this.
I mean something like the 2nd figure in this article: http://circos.ca/intro/tabular_visualization/
How can I specify the number of nodes in the graph?
@Roman How did you made the circular graph and the colorbar?
@Paul there seems to be a problem with some arcs going outside rather than inside the circle; I think it can happen if the number of nodes is divisible by 4. In this case thetaLim(2) is +pi but the algorithm is expecting -pi and ends up drawing the wrong of the two possible arcs. I fixed this by explicitly checking which arc is shorter (sort thetaLim, and if the difference between the values is >pi subtract 2*pi from the larger one and put that first) and drawing that, rather than doing the u(1),v(1)>=0 check. Hope that helps!
@John, thanks! (:
Many thanks for this much appreciated code. I've wanted to try it for some time and "today was the day!"
@Roman, looks like an interesting article! Thanks for citing my code. I'm glad it was useful. I've shared your article with some friends at MathWorks who have been thinking about computation in chemistry / ChE curricula. Cheers!
i used and cited your code in my publication: http://www.sciencedirect.com/science/article/pii/S1749772816300768#fig0015
@Paul Great tool, thanks. One issue I'm having is some of my graphs have a few of the connections between nodes on the outside. Looks a bit weird and crosses over labels. Are you familiar with this and how to fix it? Many thanks.
You do not have control over the colors with this code (See answer to my question from Paul below).
In order to change the width of the lines: In circularGraph.m go to
%Calculate line width based on values of s (stored in v) and adjust the parameters
Hope it works.
Please I want to change the colors of lines and their widths, how can I do?
Dear all is it possible to start the plot a clock position 12:00 and then go clockwise, and not at 9:00? How can I manage this?
Your use case is beyond what my design can do. I designed the nodes and connecting lines as a single graphical object: a line() with a single marker. So, when you change the color of a node, you change the color of all the connections that come out of it. Your use case is likely quite common. If I find time, I'll consider overhauling this design to enable it. In the meanwhile, you can get quite far with the network graph capabilities in MATLAB nowadays. I wrote this before MATLAB included network graphs as fundamental data types. Check this documentation page out:
Thank you @Mathworks Physics Team
But I still have the problem to control the connectivity lines color.
Could you please help me to generate the connection lines based on the thresholds (say if the connectivity value is 1 then the connection lines are #red and if the connectivity value is 2 then the connection lines are #blue).
Thanks for your note and rating.
In makeLine() of Node.m, in the line object construction, add this line:
Add this line of code to updateColor() in Node.m
this.NodeMarker.MarkerFaceColor = this.Color;
Add this line of code to the end of updateTextLabel() in Node.m
this.TextLabel.FontWeight = 'bold';
To specify the color of each node:
c = circularGraph(x); % for some x
cmap = colormap(cool(length(c.Node))); % some colormap
for k = 1 : length(c.Node)
c.Node(k).Color = cmap(k,:);
Could you please help me to do the following:
1. Fill the specific nodes with a fixed colors.
2. Control the color of the lines.
3. Make the label font bold.
Thanks for this great tool.
Dear Paul, would it be possible to give meaning to the color of the connections? For example, can they be colored according to the strength of the connection, kind of like a heat map? Can you please give me some tips for how to accomplish that?
This is really helpful, thank you... I'm also wondering how to reduce the font size? Could you give any more information than that below? Also, how would i add connections from more than one node please? At the moment i'm only able to add connections for one node.
@Paul: Great visualization tool, simple, yet effective. Always wanted some version of Circos for MATLAB. On a side note, I had to modify Lines 120 & 143: from lineWidth(i) to abs(lineWidth(i)), so I can plot negative connections (anticorrelations)
@Paul, Thank you very much. I really appreciate your prompt response and help.
@ATIF, thanks for the compliment and rating.
I recommend editing the updateTextLabel() method in the node class (defined in node.m of this package). In updateTextLabel(), an underlying text() object is created (a class built-in to MATLAB), which is a good place to assign the text() object's FontSize property.
Let me know if you need further help.
This is awesome. Thanks for sharing.
I have a problem with the label fonts. I am plotting 50 nodes that have long labels. In my case, circular graph suppress the size of the actual graph and magnifies the label font size but I want it the other way around. Is there a way I can decrease the font of node label and magnify the graph itself?
1 word: Awesome:)
@Donald, in the file called node.m look for the line that reads
set(this.Connection,'Color',0.9*[1 1 1]);
and change it to
set(this.Connection,'Color',[1 1 1]);
This is useful. Is there a way to make the hidden connections turn white (to match the background) instead of gray?
@Ivan, thank you (:
Functionality can be extended a lot, but, still, a good job. Thank you.
@MarcVanKralingen might you have an example code snippet that demonstrates the issue?
One of the lines is placed outside the circle. I cannot find the bug.
You can fix the bug by changing line 112 in circularGraph.m from
if row(i) < col(i)
if row(i) ~= col(i)
Hi, very nice looking graph! Is it also working with directed graphs, that is having 1s in both upper and lower triangle of the matrix?
I ran the code on a matrix "hc", which has 1 values coresponding to the following labels:
ans = 'A' 'A'' 'ACC' 'MOFC'' 'MTG'' 'OF' 'PHG'' 'PMC' 'R'' 'TP''
ans = 'A'' 'ACC' 'PCC'' 'VLPFC'' 'aI'' 'pI''
However, when only highlighting node 4, labeled ACC' by clicking on it, only 4 lines are drawn, leading from ACC' to PCC', VLPFC', aI' and pI'.
Also, when looking at node 4, it returns 5 connections, although only the 4 mentioned above are visible on the graph:
node with properties:
Connection: [1x5 Line]
Position: [-0.9629 -0.2698]
Color: [0.2095 0.2331 0.6660]
Any thoughts on this issue? Apparently it only draws connections with nodes that have a higher number, in this example ignoring nodes 2 (A') and 3 (ACC).
Changed GitHub repository.
Changed line 112 in circularGraph.m
Major update. Went from functional programming to object oriented.