{"id":1493,"date":"2015-11-18T17:48:46","date_gmt":"2015-11-18T22:48:46","guid":{"rendered":"https:\/\/blogs.mathworks.com\/steve\/?p=1493"},"modified":"2019-11-01T12:13:52","modified_gmt":"2019-11-01T16:13:52","slug":"graphs-in-matlab-r2015b","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/steve\/2015\/11\/18\/graphs-in-matlab-r2015b\/","title":{"rendered":"Graphs in MATLAB R2015b"},"content":{"rendered":"<div class=\"content\"><!--introduction--><p>I was inspired by ICIP 2015 and by the new graph functions in MATLAB R2015b to write some functions to help experiment with graph-based image processing algorithms. Earlier this week I <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/53-shift\">submitted the code to the File Exchange<\/a>. Here's a screen shot:<\/p><p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/www.mathworks.com\/matlabcentral\/mlc-downloads\/downloads\/submissions\/53614\/versions\/1\/screenshot.png\" alt=\"\"> <\/p><p>Over the next couple of weeks I want to show you how to get started with these functions. Today starts with a general introduction to graphs in MATLAB R2015b. I'll be picking on the state of Minnesota.<\/p><p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/steve\/files\/graphs_intro_10.png\" alt=\"\"> <\/p><!--\/introduction--><p>There are lots of ways to create a graph. A simple way is to provide two lists of nodes. Each corresponding pair of nodes corresponds to an edge. Nodes can be numbered or identified by text labels.<\/p><pre class=\"codeinput\">G = graph({<span class=\"string\">'A'<\/span>, <span class=\"string\">'B'<\/span>, <span class=\"string\">'B'<\/span>}, {<span class=\"string\">'B'<\/span>, <span class=\"string\">'C'<\/span>, <span class=\"string\">'D'<\/span>})\r\n<\/pre><pre class=\"codeoutput\">\r\nG = \r\n\r\n  graph with properties:\r\n\r\n    Edges: [3x1 table]\r\n    Nodes: [4x1 table]\r\n\r\n<\/pre><p>As shown above, a graph contains a table of nodes and a table of edges.<\/p><p>You can use the <tt>plot<\/tt> function to visualize a graph.<\/p><pre class=\"codeinput\">plot(G)\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/steve\/files\/graphs_intro_01.png\" alt=\"\"> <p>Use <tt>digraph<\/tt> to make a directed graph. Here's one that uses node numbers,node names, and edge weights.<\/p><pre class=\"codeinput\">s = [1 1 2 2 3 3 4 4 5 5];\r\nt = [2 5 3 4 4 5 3 1 1 6];\r\nnames = {<span class=\"string\">'alpha'<\/span>, <span class=\"string\">'beta'<\/span>, <span class=\"string\">'gamma'<\/span>, <span class=\"string\">'delta'<\/span>, <span class=\"string\">'epsilon'<\/span>, <span class=\"string\">'zeta'<\/span>};\r\nweight = randi(100, size(s));\r\nD = digraph(s, t, weight, names)\r\n<\/pre><pre class=\"codeoutput\">\r\nD = \r\n\r\n  digraph with properties:\r\n\r\n    Edges: [10x2 table]\r\n    Nodes: [6x1 table]\r\n\r\n<\/pre><p>The weight values are stored directly in the edge table.<\/p><pre class=\"codeinput\">D.Edges\r\n<\/pre><pre class=\"codeoutput\">\r\nans = \r\n\r\n           EndNodes           Weight\r\n    ______________________    ______\r\n\r\n    'alpha'      'beta'       24    \r\n    'alpha'      'epsilon'    36    \r\n    'beta'       'gamma'      83    \r\n    'beta'       'delta'       2    \r\n    'gamma'      'delta'       5    \r\n    'gamma'      'epsilon'    17    \r\n    'delta'      'alpha'      74    \r\n    'delta'      'gamma'      65    \r\n    'epsilon'    'alpha'      65    \r\n    'epsilon'    'zeta'       46    \r\n\r\n<\/pre><p>When you plot a directed graphs, arrows show the edge directions.<\/p><pre class=\"codeinput\">plot(D)\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/steve\/files\/graphs_intro_02.png\" alt=\"\"> <p>You can choose different plot layouts.<\/p><pre class=\"codeinput\">plot(D,<span class=\"string\">'Layout'<\/span>,<span class=\"string\">'layered'<\/span>)\r\ntitle(<span class=\"string\">'Layered graph plot'<\/span>)\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/steve\/files\/graphs_intro_03.png\" alt=\"\"> <pre class=\"codeinput\">plot(D,<span class=\"string\">'Layout'<\/span>,<span class=\"string\">'circle'<\/span>)\r\naxis <span class=\"string\">equal<\/span>\r\ntitle(<span class=\"string\">'Circular graph plot'<\/span>)\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/steve\/files\/graphs_intro_04.png\" alt=\"\"> <p>You can customize a <tt>GraphPlot<\/tt> directly. Call the <tt>plot<\/tt> function with an output argument to get the <tt>GraphPlot<\/tt> object.<\/p><pre class=\"codeinput\">p = plot(D)\r\n<\/pre><pre class=\"codeoutput\">\r\np = \r\n\r\n  GraphPlot with properties:\r\n\r\n     NodeColor: [0 0.4470 0.7410]\r\n    MarkerSize: 4\r\n        Marker: 'o'\r\n     EdgeColor: [0 0.4470 0.7410]\r\n     LineWidth: 0.5000\r\n     LineStyle: '-'\r\n     NodeLabel: {'alpha'  'beta'  'gamma'  'delta'  'epsilon'  'zeta'}\r\n     EdgeLabel: {}\r\n         XData: [-0.0350 0.5891 0.4312 0.9742 -0.5613 -1.3981]\r\n         YData: [0.4486 0.8689 -0.1321 0.3850 -0.4499 -1.1206]\r\n\r\n  Use GET to show all properties\r\n\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/steve\/files\/graphs_intro_05.png\" alt=\"\"> <p>Now modify some of the properties.<\/p><pre class=\"codeinput\">p.MarkerSize = 8;\r\np.Marker = <span class=\"string\">'x'<\/span>;\r\np.EdgeColor = <span class=\"string\">'red'<\/span>;\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/steve\/files\/graphs_intro_06.png\" alt=\"\"> <p>I really like the <tt>highlight<\/tt> function, which you can use to emphasize selected graph nodes and edges.<\/p><p>Here I highlight the shortest path between nodes <tt>'alpha'<\/tt> and <tt>'zeta'<\/tt>.<\/p><pre class=\"codeinput\">p = plot(D);\r\nshortPath = shortestpath(D, <span class=\"string\">'alpha'<\/span>, <span class=\"string\">'zeta'<\/span>)\r\nhighlight(p, shortPath)\r\n<\/pre><pre class=\"codeoutput\">\r\nshortPath = \r\n\r\n    'alpha'    'epsilon'    'zeta'\r\n\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/steve\/files\/graphs_intro_07.png\" alt=\"\"> <p>Many graph computations are available. For example, you can compute the pair-wise weighted distance between all nodes, or the out-degree of all nodes.<\/p><pre class=\"codeinput\">distances(D)\r\n<\/pre><pre class=\"codeoutput\">\r\nans =\r\n\r\n     0    24    91    26    36    82\r\n    76     0    67     2    84   130\r\n    79   103     0     5    17    63\r\n    74    98    65     0    82   128\r\n    65    89   156    91     0    46\r\n   Inf   Inf   Inf   Inf   Inf     0\r\n\r\n<\/pre><p>Poor node 6. You can't get anywhere else from there! That's because its out-degree is 0.<\/p><pre class=\"codeinput\">outdegree(D)\r\n<\/pre><pre class=\"codeoutput\">\r\nans =\r\n\r\n     2\r\n     2\r\n     2\r\n     2\r\n     2\r\n     0\r\n\r\n<\/pre><p>Let's look at a somewhat larger graph, based on the network of roads in the state of Minnesota. (If you want to play with this data yourself, you can get it from the <a href=\"http:\/\/www.cise.ufl.edu\/research\/sparse\/matrices\/Gleich\/minnesota.html\">UF Sparse Matrix Collection<\/a>.)<\/p><pre class=\"codeinput\">load(<span class=\"string\">'minnesota.mat'<\/span>)\r\nxy = Problem.aux.coord;\r\nminn_roads = graph(Problem.A);\r\nminn_roads.Edges.Weight = hypot(xy(minn_roads.Edges.EndNodes(:,1),1) - <span class=\"keyword\">...<\/span>\r\n   xy(minn_roads.Edges.EndNodes(:,2),1), <span class=\"keyword\">...<\/span>\r\n   xy(minn_roads.Edges.EndNodes(:,1),2) - <span class=\"keyword\">...<\/span>\r\n   xy(minn_roads.Edges.EndNodes(:,2),2));\r\nplot(minn_roads,<span class=\"string\">'XData'<\/span>,xy(:,1),<span class=\"string\">'YData'<\/span>,xy(:,2));\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/steve\/files\/graphs_intro_08.png\" alt=\"\"> <p>You can compute a graph's minimum spanning tree.<\/p><pre class=\"codeinput\">T = minspantree(minn_roads)\r\nplot(T,<span class=\"string\">'XData'<\/span>,xy(:,1),<span class=\"string\">'YData'<\/span>,xy(:,2));\r\n<\/pre><pre class=\"codeoutput\">\r\nT = \r\n\r\n  graph with properties:\r\n\r\n    Edges: [2639x2 table]\r\n    Nodes: [2642x0 table]\r\n\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/steve\/files\/graphs_intro_09.png\" alt=\"\"> <p>This example shows how to color the graph by the shortest path tree.<\/p><pre class=\"codeinput\">[tree, d] = shortestpathtree(minn_roads, 1561);\r\np = plot(minn_roads,<span class=\"string\">'XData'<\/span>,xy(:,1),<span class=\"string\">'YData'<\/span>,xy(:,2));\r\np.NodeCData = d;\r\ncolorbar\r\n<\/pre><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/steve\/files\/graphs_intro_10.png\" alt=\"\"> <p>Next time I'll start talking about graphs whose nodes are image pixels.<\/p><script language=\"JavaScript\"> <!-- \r\n    function grabCode_b19c50e38a2c4ed3aca90ec2bcd04f96() {\r\n        \/\/ Remember the title so we can use it in the new page\r\n        title = document.title;\r\n\r\n        \/\/ Break up these strings so that their presence\r\n        \/\/ in the Javascript doesn't mess up the search for\r\n        \/\/ the MATLAB code.\r\n        t1='b19c50e38a2c4ed3aca90ec2bcd04f96 ' + '##### ' + 'SOURCE BEGIN' + ' #####';\r\n        t2='##### ' + 'SOURCE END' + ' #####' + ' b19c50e38a2c4ed3aca90ec2bcd04f96';\r\n    \r\n        b=document.getElementsByTagName('body')[0];\r\n        i1=b.innerHTML.indexOf(t1)+t1.length;\r\n        i2=b.innerHTML.indexOf(t2);\r\n \r\n        code_string = b.innerHTML.substring(i1, i2);\r\n        code_string = code_string.replace(\/REPLACE_WITH_DASH_DASH\/g,'--');\r\n\r\n        \/\/ Use \/x3C\/g instead of the less-than character to avoid errors \r\n        \/\/ in the XML parser.\r\n        \/\/ Use '\\x26#60;' instead of '<' so that the XML parser\r\n        \/\/ doesn't go ahead and substitute the less-than character. \r\n        code_string = code_string.replace(\/\\x3C\/g, '\\x26#60;');\r\n\r\n        copyright = 'Copyright 2015 The MathWorks, Inc.';\r\n\r\n        w = window.open();\r\n        d = w.document;\r\n        d.write('<pre>\\n');\r\n        d.write(code_string);\r\n\r\n        \/\/ Add copyright line at the bottom if specified.\r\n        if (copyright.length > 0) {\r\n            d.writeln('');\r\n            d.writeln('%%');\r\n            if (copyright.length > 0) {\r\n                d.writeln('% _' + copyright + '_');\r\n            }\r\n        }\r\n\r\n        d.write('<\/pre>\\n');\r\n\r\n        d.title = title + ' (MATLAB code)';\r\n        d.close();\r\n    }   \r\n     --> <\/script><p style=\"text-align: right; font-size: xx-small; font-weight:lighter;   font-style: italic; color: gray\"><br><a href=\"javascript:grabCode_b19c50e38a2c4ed3aca90ec2bcd04f96()\"><span style=\"font-size: x-small;        font-style: italic;\">Get \r\n      the MATLAB code <noscript>(requires JavaScript)<\/noscript><\/span><\/a><br><br>\r\n      Published with MATLAB&reg; R2015b<br><\/p><\/div><!--\r\nb19c50e38a2c4ed3aca90ec2bcd04f96 ##### SOURCE BEGIN #####\r\n%% \r\n% I was inspired by ICIP 2015 and by the new graph functions in\r\n% MATLAB R2015b to write some functions to help experiment with\r\n% graph-based image processing algorithms. Earlier this week I\r\n% <https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/53-shift \r\n% submitted the code to the File Exchange>. Here's a screen shot:\r\n%\r\n% <<https:\/\/www.mathworks.com\/matlabcentral\/mlc-downloads\/downloads\/submissions\/53614\/versions\/1\/screenshot.png>>\r\n% \r\n% Over the next couple of weeks I want to show you how to get\r\n% started with these functions. Today starts with a general\r\n% introduction to graphs in MATLAB R2015b. I'll be picking on the\r\n% state of Minnesota.\r\n%\r\n% <<https:\/\/blogs.mathworks.com\/steve\/files\/graphs_intro_10.png>>\r\n\r\n%% \r\n% There are lots of ways to create a graph. A simple way is to\r\n% provide two lists of nodes. Each corresponding pair of nodes\r\n% corresponds to an edge. Nodes can be numbered or identified by\r\n% text labels.\r\nG = graph({'A', 'B', 'B'}, {'B', 'C', 'D'})\r\n\r\n%%\r\n% As shown above, a graph contains a table of nodes and a table of\r\n% edges.\r\n%\r\n% You can use the |plot| function to visualize a graph.\r\nplot(G)\r\n\r\n%% \r\n% Use |digraph| to make a directed graph. Here's one that uses node\r\n% numbers,node names, and edge weights.\r\ns = [1 1 2 2 3 3 4 4 5 5];\r\nt = [2 5 3 4 4 5 3 1 1 6];\r\nnames = {'alpha', 'beta', 'gamma', 'delta', 'epsilon', 'zeta'};\r\nweight = randi(100, size(s));\r\nD = digraph(s, t, weight, names)\r\n\r\n%%\r\n% The weight values are stored directly in the edge table.\r\nD.Edges\r\n\r\n%%\r\n% When you plot a directed graphs, arrows show the edge directions.\r\nplot(D)\r\n\r\n%% \r\n% You can choose different plot layouts.\r\nplot(D,'Layout','layered')\r\ntitle('Layered graph plot')\r\n\r\n%%\r\nplot(D,'Layout','circle')\r\naxis equal\r\ntitle('Circular graph plot')\r\n\r\n%%\r\n% You can customize a |GraphPlot| directly. Call the |plot| function\r\n% with an output argument to get the |GraphPlot| object.\r\n\r\np = plot(D)\r\n\r\n%%\r\n% Now modify some of the properties.\r\np.MarkerSize = 8;\r\np.Marker = 'x';\r\np.EdgeColor = 'red';\r\n\r\n%%\r\n% I really like the |highlight| function, which you can use to\r\n% emphasize selected graph nodes and edges.\r\n%\r\n% Here I highlight the shortest path between nodes |'alpha'| and\r\n% |'zeta'|.\r\np = plot(D);\r\nshortPath = shortestpath(D, 'alpha', 'zeta')\r\nhighlight(p, shortPath)\r\n\r\n%%\r\n% Many graph computations are available. For example, you can\r\n% compute the pair-wise weighted distance between all nodes, or the\r\n% out-degree of all nodes.\r\ndistances(D)\r\n\r\n%%\r\n% Poor node 6. You can't get anywhere else from there! That's\r\n% because its out-degree is 0.\r\noutdegree(D)\r\n\r\n%% \r\n% Let's look at a somewhat larger graph, based on the network of\r\n% roads in the state of Minnesota. (If you want to play with this\r\n% data yourself, you can get it from the\r\n% <http:\/\/www.cise.ufl.edu\/research\/sparse\/matrices\/Gleich\/minnesota.html\r\n% UF Sparse Matrix Collection>.)\r\n\r\nload('minnesota.mat')\r\nxy = Problem.aux.coord;\r\nminn_roads = graph(Problem.A);\r\nminn_roads.Edges.Weight = hypot(xy(minn_roads.Edges.EndNodes(:,1),1) - ...\r\n   xy(minn_roads.Edges.EndNodes(:,2),1), ...\r\n   xy(minn_roads.Edges.EndNodes(:,1),2) - ...\r\n   xy(minn_roads.Edges.EndNodes(:,2),2));\r\nplot(minn_roads,'XData',xy(:,1),'YData',xy(:,2));\r\n\r\n%% \r\n% You can compute a graph's minimum spanning tree.\r\nT = minspantree(minn_roads)\r\nplot(T,'XData',xy(:,1),'YData',xy(:,2));\r\n\r\n%% \r\n% This example shows how to color the graph by the shortest path\r\n% tree.\r\n[tree, d] = shortestpathtree(minn_roads, 1561);\r\np = plot(minn_roads,'XData',xy(:,1),'YData',xy(:,2));\r\np.NodeCData = d;\r\ncolorbar\r\n\r\n%%\r\n% Next time I'll start talking about graphs whose nodes are image\r\n% pixels.\r\n##### SOURCE END ##### b19c50e38a2c4ed3aca90ec2bcd04f96\r\n-->","protected":false},"excerpt":{"rendered":"<div class=\"overview-image\"><img src=\"https:\/\/blogs.mathworks.com\/steve\/files\/graphs_intro_10.png\" class=\"img-responsive attachment-post-thumbnail size-post-thumbnail wp-post-image\" alt=\"\" decoding=\"async\" loading=\"lazy\" \/><\/div><!--introduction--><p>I was inspired by ICIP 2015 and by the new graph functions in MATLAB R2015b to write some functions to help experiment with graph-based image processing algorithms. Earlier this week I <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/53-shift\">submitted the code to the File Exchange<\/a>. Here's a screen shot:... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/steve\/2015\/11\/18\/graphs-in-matlab-r2015b\/\">read more >><\/a><\/p>","protected":false},"author":42,"featured_media":1492,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[1],"tags":[50,1103,1131,1137,1125,1135,334,362,1141,1139,68,1129,1133,1143,52],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/1493"}],"collection":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/users\/42"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/comments?post=1493"}],"version-history":[{"count":1,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/1493\/revisions"}],"predecessor-version":[{"id":1494,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/posts\/1493\/revisions\/1494"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/media\/1492"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/media?parent=1493"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/categories?post=1493"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/steve\/wp-json\/wp\/v2\/tags?post=1493"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}