{"id":1945,"date":"2024-12-10T10:19:36","date_gmt":"2024-12-10T15:19:36","guid":{"rendered":"https:\/\/blog.uvm.edu\/tbplante\/?p=1945"},"modified":"2024-12-11T09:50:15","modified_gmt":"2024-12-11T14:50:15","slug":"using-stata-and-graphwiz-to-make-social-network-graphs-and-hierarchical-graphs","status":"publish","type":"post","link":"https:\/\/blog.uvm.edu\/tbplante\/2024\/12\/10\/using-stata-and-graphwiz-to-make-social-network-graphs-and-hierarchical-graphs\/","title":{"rendered":"Using Stata and Graphviz to make social network graphs and hierarchical graphs"},"content":{"rendered":"\n<p>I recently had to make a figure that showed relationship between variables. I tried a few different software packages and ultimately decided that Graphviz is the easiest. Thanks to dreampuf for their Graphviz online program! I used this web-based implementation and didn&#8217;t have to install Graphviz on my computer. So for this, <strong>we&#8217;ll be using this online Graphviz package<\/strong>: <a href=\"https:\/\/dreampuf.github.io\/GraphvizOnline\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/dreampuf.github.io\/GraphvizOnline<\/a><\/p>\n\n\n\n<p>I wrote a basic Stata script that inputs data and then outputs Graphviz code that you can copy and paste right into the Graphviz website above. (<em>I strongly strongly strongly recommend saving your Graphviz code locally on your computer as a text file. On Windows I use <a href=\"https:\/\/notepad-plus-plus.org\/\" data-type=\"link\" data-id=\"https:\/\/notepad-plus-plus.org\/\" target=\"_blank\" rel=\"noreferrer noopener\">Notepad++<\/a><\/em>. <em>Don&#8217;t save this code in a word processor because it will do unpredictable things to the quotes.<\/em>) You can then tweak the settings of the outputted Graphviz code to your liking. See all sorts of settings in the left-sided menu here: <a href=\"https:\/\/graphviz.org\/docs\/nodes\/\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/graphviz.org\/docs\/nodes\/<\/a><\/p>\n\n\n\n<p>Originally I wanted this to be a network graph (&#8220;neato&#8221;) but ultimately liked how it looked best in the hierarchical graph (&#8220;dot&#8221;). You can change between graph types using the engine dropdown menu on the top right of the Graphviz online website. You can also change the file type to something that journals will use, like PNG, on the top right.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Code to output Graphviz code from your Stata database<\/h2>\n\n\n\n<p>Run the following in its entirety from a Stata do file.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>clear all \/\/ clear memory\n\/\/\n\/\/ Now input variables called 'start' and 'end#'.\n\/\/ 'start' is the originating node and 'end#' is\n\/\/ every node that 'start' connects to.\n\/\/ If you need additional 'end#' variables, just add them\n\/\/ using strL (capital L) then the next 'end#' number.\n\/\/ In this example, there's 1 'start' and 4 'end#'\n\/\/ so there are 5 total columns. \ninput strL start strL end1 strL end2 strL end3 strL end4\n\"ant\" \"bat\" \"cat\" \"dog\" \"fox\"\n\"bat\" \"ent\" \"\" \"\" \"\"\n\"cat\" \"ent\" \"fox\" \"\" \"\"\n\"dog\" \"ent\" \"fox\" \"\" \"\"\nend \/\/ end input\n\/\/ \n\/\/ The following code reshapes the data from wide\n\/\/ to long and drops all subsequent blank variables\n\/\/ from that rotation (if any). \ngen row = _n \/\/make row variable\nreshape long end, i(row) j(nodenum) \/\/ reshape\ndrop if end==\"\" \/\/ drop empty cells\nkeep start end \/\/ just need these variables\n\/\/\n\/\/ The following loop renders the current Stata\n\/\/ dataset as Graphviz code. Since this uses loops\n\/\/ and local macros, it needs to be run all at once \n\/\/ in a do file rather than line by line. \nlocal max = _N\nquietly {\n\t\/\/ Start of graphviz code:\n\tnoisily di \"\"\n\tnoisily di \"\"\n\tnoisily di \"\"\n\tnoisily di \"\"\n\tnoisily di \"\/\/ Copy everything that follows\"\n\tnoisily di \"\/\/ and paste it into here:\"\n\tnoisily di \"\/\/ https:\/\/dreampuf.github.io\/GraphvizOnline\"\n\tnoisily di \"digraph g {\"\n\t\/\/\n\t\/\/ This prints out the connection between\n\t\/\/ each 'start' node and all connected\n\t\/\/ 'end#' nodes one by one.\n\tforvalues n = 1\/`max' {\n\t\tnoisily di start&#091;`n'] \" -&gt; \" end&#091;`n'] \";\"\n\t}\n\t\/\/\n\t\/\/ Global graph attributes follows. \n\t\/\/ \"bb\" sets the size of the figure\n\t\/\/ from lower left x, y, then upper right x, y.\n\t\/\/ There are lots of other settings here: \n\t\/\/ https:\/\/graphviz.org\/docs\/graph\/\n\t\/\/ ...if adding more, just add between the final\n\t\/\/ comma and closing bracket. If adding several\n\t\/\/ additional settings here, separate each with \n\t\/\/ a comma. \n\t\/\/ Note that this has an opening and closing tick\n\t\/\/ so the quotes inside print like characters\n\t\/\/ and not actual stata code quotes.\n\tnoisily di `\"graph &#091;bb=\"0,0,100,1000\",];\"' \n\t\/\/\n\t\/\/ The next block generates code to render each\n\t\/\/ node. First, we need to reshape long(er) so that\n\t\/\/ all of the 'start' and 'end#' variables are all\n\t\/\/ in a single column, delete duplicates, and \n\t\/\/ sort them. \n\trename start thing1\n\trename end thing2\n\tgen row = _n\n\treshape long thing, i(row) j(nodenum) \n\tkeep thing\n\tduplicates drop\n\tsort thing\n\t\/\/\n\t\/\/ Now print out settings for each node. These\n\t\/\/ can be fine tuned. Lots of options for \n\t\/\/ node formatting here: \n\t\/\/ https:\/\/graphviz.org\/docs\/nodes\/\n\tlocal max = _N\n\tforvalues n= 1\/`max' {\n\t\tnoisily di thing&#091;`n'] `\" &#091;width=\"0.1\", height=\"0.1\", fontsize=\"8\", shape=box];\"'\n\t}\n\t\/\/ End of graphviz code: \n\tnoisily di \"}\"\n\tnoisily di \"\/\/ don't copy below this line\"\n\tnoisily di \"\"\n\tnoisily di \"\"\n\tnoisily di \"\"\n\tnoisily di \"\"\n}\n\/\/ that's it!\n<\/code><\/pre>\n\n\n\n<p>The above Stata code prints the following Graphviz code in the Stata output window. This code can be copied\/pasted to the Graphviz website linked above. (<em>Make sure to save a backup of this Graphviz code as a txt file on your computer!!<\/em>) Make sure your Stata screen is full size before running the above Stata code or it might insert some line breaks that you have to manually delete since the output width is (usually) determined by the window size. Also, if your node settings get long, it&#8217;ll also insert line breaks that you&#8217;ll have to manually delete.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\n\n\n\n\/\/ Copy everything that follows\n\/\/ and paste it into here:\n\/\/ https:\/\/dreampuf.github.io\/GraphvizOnline\ndigraph g {\nant -&gt; bat;\nant -&gt; cat;\nant -&gt; dog;\nant -&gt; fox;\nbat -&gt; ent;\ncat -&gt; ent;\ncat -&gt; fox;\ndog -&gt; ent;\ndog -&gt; fox;\ngraph &#091;bb=\"0,0,100,1000\",];\nant &#091;width=\"0.1\", height=\"0.1\", fontsize=\"8\", shape=box];\nbat &#091;width=\"0.1\", height=\"0.1\", fontsize=\"8\", shape=box];\ncat &#091;width=\"0.1\", height=\"0.1\", fontsize=\"8\", shape=box];\ndog &#091;width=\"0.1\", height=\"0.1\", fontsize=\"8\", shape=box];\nent &#091;width=\"0.1\", height=\"0.1\", fontsize=\"8\", shape=box];\nfox &#091;width=\"0.1\", height=\"0.1\", fontsize=\"8\", shape=box];\n}\n\/\/ don't copy below this line\n\n\n\n\n\n\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Example figures from outputted code above using the different Graphviz engines<\/h2>\n\n\n\n<p>Clicking the dropdown in the top right &#8220;engine&#8221; toggles between the figures below. You can learn more about these here: <a href=\"https:\/\/graphviz.org\/docs\/layouts\/\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/graphviz.org\/docs\/layouts\/<\/a><\/p>\n\n\n\n<p>Not shown below are &#8220;nop&#8221; and &#8220;nop2&#8221; which don&#8217;t render correctly for unclear reasons. Some of these will need to be tweaked to be publication quality, some of them frankly don&#8217;t work with this dataset. For this made up code, I think dot and neato look great!<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Dot (hierarchical or layered drawing of directed graphs, my favorite for this project):<\/h3>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"661\" height=\"682\" src=\"https:\/\/blog.uvm.edu\/tbplante\/files\/2024\/12\/image-8.png\" alt=\"\" class=\"wp-image-1979\" style=\"width:417px;height:auto\" srcset=\"https:\/\/blog.uvm.edu\/tbplante\/files\/2024\/12\/image-8.png 661w, https:\/\/blog.uvm.edu\/tbplante\/files\/2024\/12\/image-8-291x300.png 291w\" sizes=\"auto, (max-width: 661px) 100vw, 661px\" \/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Neato (a nice network graph, called &#8220;spring model&#8221; layout):<\/h3>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"687\" height=\"588\" src=\"https:\/\/blog.uvm.edu\/tbplante\/files\/2024\/12\/image-9.png\" alt=\"\" class=\"wp-image-1981\" style=\"width:482px;height:auto\" srcset=\"https:\/\/blog.uvm.edu\/tbplante\/files\/2024\/12\/image-9.png 687w, https:\/\/blog.uvm.edu\/tbplante\/files\/2024\/12\/image-9-300x257.png 300w\" sizes=\"auto, (max-width: 687px) 100vw, 687px\" \/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Circo, aka circular layout:<\/h3>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"931\" height=\"817\" src=\"https:\/\/blog.uvm.edu\/tbplante\/files\/2024\/12\/image-10.png\" alt=\"\" class=\"wp-image-1982\" style=\"width:485px;height:auto\" srcset=\"https:\/\/blog.uvm.edu\/tbplante\/files\/2024\/12\/image-10.png 931w, https:\/\/blog.uvm.edu\/tbplante\/files\/2024\/12\/image-10-300x263.png 300w, https:\/\/blog.uvm.edu\/tbplante\/files\/2024\/12\/image-10-768x674.png 768w\" sizes=\"auto, (max-width: 931px) 100vw, 931px\" \/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">fdp (force-directed placement):<\/h3>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"921\" height=\"685\" src=\"https:\/\/blog.uvm.edu\/tbplante\/files\/2024\/12\/image-11.png\" alt=\"\" class=\"wp-image-1983\" style=\"width:487px;height:auto\" srcset=\"https:\/\/blog.uvm.edu\/tbplante\/files\/2024\/12\/image-11.png 921w, https:\/\/blog.uvm.edu\/tbplante\/files\/2024\/12\/image-11-300x223.png 300w, https:\/\/blog.uvm.edu\/tbplante\/files\/2024\/12\/image-11-768x571.png 768w\" sizes=\"auto, (max-width: 921px) 100vw, 921px\" \/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">sfdp (scalable force-directed placement):<\/h3>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"925\" height=\"624\" src=\"https:\/\/blog.uvm.edu\/tbplante\/files\/2024\/12\/image-12.png\" alt=\"\" class=\"wp-image-1984\" style=\"width:459px;height:auto\" srcset=\"https:\/\/blog.uvm.edu\/tbplante\/files\/2024\/12\/image-12.png 925w, https:\/\/blog.uvm.edu\/tbplante\/files\/2024\/12\/image-12-300x202.png 300w, https:\/\/blog.uvm.edu\/tbplante\/files\/2024\/12\/image-12-768x518.png 768w\" sizes=\"auto, (max-width: 925px) 100vw, 925px\" \/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">twopi (radial layout):<\/h3>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"928\" height=\"906\" src=\"https:\/\/blog.uvm.edu\/tbplante\/files\/2024\/12\/image-13.png\" alt=\"\" class=\"wp-image-1985\" style=\"width:476px;height:auto\" srcset=\"https:\/\/blog.uvm.edu\/tbplante\/files\/2024\/12\/image-13.png 928w, https:\/\/blog.uvm.edu\/tbplante\/files\/2024\/12\/image-13-300x293.png 300w, https:\/\/blog.uvm.edu\/tbplante\/files\/2024\/12\/image-13-768x750.png 768w\" sizes=\"auto, (max-width: 928px) 100vw, 928px\" \/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">osage (clustered graphs):<\/h3>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"903\" height=\"456\" src=\"https:\/\/blog.uvm.edu\/tbplante\/files\/2024\/12\/image-14.png\" alt=\"\" class=\"wp-image-1986\" style=\"width:377px;height:auto\" srcset=\"https:\/\/blog.uvm.edu\/tbplante\/files\/2024\/12\/image-14.png 903w, https:\/\/blog.uvm.edu\/tbplante\/files\/2024\/12\/image-14-300x151.png 300w, https:\/\/blog.uvm.edu\/tbplante\/files\/2024\/12\/image-14-768x388.png 768w\" sizes=\"auto, (max-width: 903px) 100vw, 903px\" \/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Patchwork (clustered graph using squarified treemap):<\/h3>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"889\" height=\"900\" src=\"https:\/\/blog.uvm.edu\/tbplante\/files\/2024\/12\/image-15.png\" alt=\"\" class=\"wp-image-1987\" style=\"width:357px;height:auto\" srcset=\"https:\/\/blog.uvm.edu\/tbplante\/files\/2024\/12\/image-15.png 889w, https:\/\/blog.uvm.edu\/tbplante\/files\/2024\/12\/image-15-296x300.png 296w, https:\/\/blog.uvm.edu\/tbplante\/files\/2024\/12\/image-15-768x778.png 768w\" sizes=\"auto, (max-width: 889px) 100vw, 889px\" \/><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>I recently had to make a figure that showed relationship between variables. I tried a few different software packages and ultimately decided that Graphviz is the easiest. Thanks to dreampuf for their Graphviz online program! I used this web-based implementation and didn&#8217;t have to install Graphviz on my computer. So for this, we&#8217;ll be using &hellip; <a href=\"https:\/\/blog.uvm.edu\/tbplante\/2024\/12\/10\/using-stata-and-graphwiz-to-make-social-network-graphs-and-hierarchical-graphs\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Using Stata and Graphviz to make social network graphs and hierarchical graphs<\/span><\/a><\/p>\n","protected":false},"author":4473,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[477491],"tags":[703510,703513,703514,703511,703512,502556],"class_list":["post-1945","post","type-post","status-publish","format-standard","hentry","category-stata-code","tag-graphviz","tag-hierarchical-graph","tag-layered-graph","tag-network-graph","tag-social-network-graph","tag-stata"],"_links":{"self":[{"href":"https:\/\/blog.uvm.edu\/tbplante\/wp-json\/wp\/v2\/posts\/1945","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.uvm.edu\/tbplante\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.uvm.edu\/tbplante\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.uvm.edu\/tbplante\/wp-json\/wp\/v2\/users\/4473"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.uvm.edu\/tbplante\/wp-json\/wp\/v2\/comments?post=1945"}],"version-history":[{"count":19,"href":"https:\/\/blog.uvm.edu\/tbplante\/wp-json\/wp\/v2\/posts\/1945\/revisions"}],"predecessor-version":[{"id":1988,"href":"https:\/\/blog.uvm.edu\/tbplante\/wp-json\/wp\/v2\/posts\/1945\/revisions\/1988"}],"wp:attachment":[{"href":"https:\/\/blog.uvm.edu\/tbplante\/wp-json\/wp\/v2\/media?parent=1945"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.uvm.edu\/tbplante\/wp-json\/wp\/v2\/categories?post=1945"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.uvm.edu\/tbplante\/wp-json\/wp\/v2\/tags?post=1945"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}