<p>On January, 10 2016 David Bowie left this earthly realm. Last month I decided to create a <a href="http://pacha.hk/bowie_2.html">network</a> and here is how to do that.</p>
<h1>Required packages</h1>
<p>You need <code>jsonlite</code>, <code>igraph</code>, <code>network</code>, <code>plyr</code> and R base.</p>
<h1>Other tools</h1>
<p><a href="http://d3plus.org/">D3Plus</a> by Alex Simoes and Dave Landry. Also Google Sheets.</p>
<p>My data is <a href="https://docs.google.com/spreadsheets/d/19Qf-9I8hU98CtXrc3xP6Jg_5DiFj2Zz9ALi7cICNI0M/edit#gid=0">here</a>.</p>
<h1>Loading packages</h1>
<div><pre><span></span><span># 1: define the libraries to use</span>
libraries <span>&lt;-</span> <span>c</span><span>(</span><span>&quot;jsonlite&quot;</span><span>,</span><span>&quot;igraph&quot;</span><span>,</span><span>&quot;network&quot;</span><span>,</span> <span>&quot;data.table&quot;</span><span>,</span> <span>&quot;plyr&quot;</span><span>)</span>

<span># 2: this is the function to download and or load libraries on the fly</span>
download_and_or_load <span>&lt;-</span> <span>function</span><span>(</span>pkg<span>){</span>
  new.pkg <span>&lt;-</span> pkg<span>[</span><span>!</span><span>(</span>pkg <span>%in%</span> installed.packages<span>()[,</span> <span>&quot;Package&quot;</span><span>])]</span>
  <span>if</span> <span>(</span><span>length</span><span>(</span>new.pkg<span>))</span>
    install.packages<span>(</span>new.pkg<span>,</span> dependencies <span>=</span> <span>TRUE</span><span>)</span>
  <span>sapply</span><span>(</span>pkg<span>,</span> <span>require</span><span>,</span> character.only <span>=</span> <span>TRUE</span><span>)</span>
<span>}</span>

<span># 3: use the function from step 2</span>
download_and_or_load<span>(</span>libraries<span>)</span>
</pre></div>
<h1>Building the network</h1>
<p>D3Plus needs three files: data, edges and nodes to visualize networks.</p>
<h2>Data</h2>
<p>This is the easy part. I downloaded the sheet named &quot;data&quot; from my spredsheet in CSV format. Then I convert the CSV to JSON with these lines:</p>
<div><pre><span></span>data <span>&lt;-</span> read.csv<span>(</span><span>&quot;data.csv&quot;</span><span>)</span>
data <span>&lt;-</span> toJSON<span>(</span>data<span>,</span> pretty <span>=</span> <span>TRUE</span><span>)</span>
<span>write</span><span>(</span>data<span>,</span> file <span>=</span> <span>&quot;bowie_data.json&quot;</span><span>)</span>
</pre></div>
<h2>Edges</h2>
<p>Here is a bit trickier.</p>
<p>I downloaded the sheet named &quot;collaborations&quot; from my spredsheet in CSV format. In this matrix <span>\(M\)</span> this is the meaning of the entries:
</p>
<div>$$
m_{ij} = \begin{cases}
1 &amp;\text{if } \text{artist } i \text{ and artist } j \text{ did collaborate to each other}\cr
0 &amp;\text{othewise}
\end{cases}
$$</div>
<p>Then arrange the matrix to fix row names and column names:</p>
<div><pre><span></span>bowie_collaborations <span>&lt;-</span> read.csv<span>(</span><span>&quot;collaborations.csv&quot;</span><span>)</span>
<span>rownames</span><span>(</span>bowie_collaborations<span>)</span> <span>&lt;-</span> bowie_collaborations<span>[,</span><span>1</span><span>]</span>
bowie_collaborations <span>&lt;-</span> bowie_collaborations<span>[,</span><span>-1</span><span>]</span>
<span>colnames</span><span>(</span>bowie_collaborations<span>)</span> <span>&lt;-</span> <span>rownames</span><span>(</span>bowie_collaborations<span>)</span>
</pre></div>
<p>With the matrix ready I can create the network. You can try different layouts explained in <code>igraph</code> documentation. This is the code to create the network and display a static version of it:</p>
<div><pre><span></span>bowie_gr <span>&lt;-</span> <span>matrix</span><span>(</span><span>unlist</span><span>(</span>bowie_collaborations<span>),</span> ncol <span>=</span> <span>nrow</span><span>(</span>bowie_collaborations<span>),</span> byrow <span>=</span> <span>TRUE</span><span>)</span>
<span>rownames</span><span>(</span>bowie_gr<span>)</span> <span>&lt;-</span> <span>rownames</span><span>(</span>bowie_collaborations<span>)</span>
<span>colnames</span><span>(</span>bowie_gr<span>)</span> <span>&lt;-</span> <span>colnames</span><span>(</span>bowie_collaborations<span>)</span>

bowie_gr <span>&lt;-</span> <span>which</span><span>(</span>bowie_gr <span>></span> <span>0</span><span>,</span> arr.ind<span>=</span><span>TRUE</span><span>)</span>
bowie_gr.graph <span>&lt;-</span> minimum.spanning.tree<span>(</span>graph.data.frame<span>(</span>bowie_gr<span>,</span> directed<span>=</span><span>F</span><span>))</span>
bowie_gr.names <span>&lt;-</span> <span>colnames</span><span>(</span>bowie_collaborations<span>)[</span><span>as.numeric</span><span>(</span>V<span>(</span>bowie_gr.graph<span>)</span><span>$</span>name<span>)]</span>
bowie_gr.graph <span>&lt;-</span> simplify<span>(</span>bowie_gr.graph<span>,</span> remove.multiple <span>=</span> <span>T</span><span>,</span> remove.loops <span>=</span> <span>T</span><span>)</span> 

<span>set.seed</span><span>(</span><span>1234</span><span>)</span>
bowie_gr.layout <span>&lt;-</span> layout_with_fr<span>(</span>bowie_gr.graph<span>)</span>
plot<span>(</span>bowie_gr.graph<span>,</span> edge.arrow.size<span>=</span><span>.3</span><span>,</span> vertex.label<span>=</span>bowie_gr.names<span>,</span> layout<span>=</span>bowie_gr.layout<span>)</span>
</pre></div>
<p></p>
<p>Now I do save the edges (names and ids) and the network layout:</p>
<div><pre><span></span>write.graph<span>(</span>bowie_gr.graph<span>,</span> <span>&quot;exported_edges_bowie.csv&quot;</span><span>,</span> format<span>=</span><span>c</span><span>(</span><span>&quot;pajek&quot;</span><span>))</span>
write.csv<span>(</span>bowie_gr.names<span>,</span> <span>&quot;exported_names_bowie.csv&quot;</span><span>)</span>
write.csv<span>(</span>bowie_gr.layout<span>,</span> <span>&quot;exported_coordinates_bowie.csv&quot;</span><span>)</span>
</pre></div>
<p>Finally I rearrange the edges to display names instead of numeric ids and save the result in JSON format:</p>
<div><pre><span></span>network_names <span>&lt;-</span> read.csv<span>(</span><span>&quot;exported_names_bowie.csv&quot;</span><span>)</span>
setnames<span>(</span>network_names<span>,</span> <span>colnames</span><span>(</span>network_names<span>),</span> <span>c</span><span>(</span><span>&quot;source_num&quot;</span><span>,</span><span>&quot;source&quot;</span><span>))</span>
network_names<span>$</span>target_num <span>&lt;-</span> network_names<span>$</span>source_num
network_names<span>$</span>target <span>&lt;-</span> network_names<span>$</span><span>source</span>

network_edges <span>&lt;-</span> read.csv<span>(</span><span>&quot;exported_edges_bowie.csv&quot;</span><span>,</span> sep <span>=</span> <span>&quot; &quot;</span><span>)</span>
network_edges <span>&lt;-</span> network_edges<span>[</span><span>-1</span><span>,]</span>
setnames<span>(</span>network_edges<span>,</span> <span>colnames</span><span>(</span>network_edges<span>),</span> <span>c</span><span>(</span><span>&quot;source_num&quot;</span><span>,</span><span>&quot;target_num&quot;</span><span>))</span>
network_edges <span>&lt;-</span> join<span>(</span>network_edges<span>,</span> network_names<span>[,</span><span>c</span><span>(</span><span>&quot;source&quot;</span><span>,</span><span>&quot;source_num&quot;</span><span>)],</span> by <span>=</span> <span>&quot;source_num&quot;</span><span>)</span>
network_edges <span>&lt;-</span> join<span>(</span>network_edges<span>,</span> network_names<span>[,</span><span>c</span><span>(</span><span>&quot;target&quot;</span><span>,</span><span>&quot;target_num&quot;</span><span>)],</span> by <span>=</span> <span>&quot;target_num&quot;</span><span>)</span>
network_edges <span>&lt;-</span> network_edges<span>[,</span><span>c</span><span>(</span><span>&quot;source&quot;</span><span>,</span><span>&quot;target&quot;</span><span>)]</span>
<span>source</span> <span>&lt;-</span> <span>as.data.frame</span><span>(</span>network_edges<span>$</span><span>source</span><span>)</span>
<span>colnames</span><span>(</span><span>source</span><span>)</span> <span>&lt;-</span> <span>&quot;source&quot;</span>
target <span>&lt;-</span> <span>as.data.frame</span><span>(</span>network_edges<span>$</span>target<span>)</span>
<span>colnames</span><span>(</span>target<span>)</span> <span>&lt;-</span> <span>&quot;target&quot;</span>

network_edges <span>&lt;-</span> <span>data.frame</span><span>(</span><span>matrix</span><span>(</span>ncol <span>=</span> <span>1</span><span>,</span> nrow <span>=</span> <span>nrow</span><span>(</span>network_edges<span>)))</span>
network_edges<span>$</span><span>source</span> <span>&lt;-</span> <span>source</span>
network_edges<span>$</span>target <span>&lt;-</span> target
<span>colnames</span><span>(</span>network_edges<span>$</span><span>source</span><span>)</span> <span>&lt;-</span> <span>&quot;Artist&quot;</span>
<span>colnames</span><span>(</span>network_edges<span>$</span>target<span>)</span> <span>&lt;-</span> <span>&quot;Artist&quot;</span>

network_edges_json <span>=</span> toJSON<span>(</span>network_edges<span>,</span> pretty <span>=</span> <span>TRUE</span><span>)</span>
<span>write</span><span>(</span>network_edges_json<span>,</span> <span>&quot;bowie_edges.json&quot;</span><span>)</span>
</pre></div>
<h2>Nodes</h2>
<p>This is easier than the edges part. The code to save the nodes in JSON format with names instead of numeric ids is:</p>
<div><pre><span></span>network_nodes <span>&lt;-</span> read.csv<span>(</span><span>&quot;exported_coordinates_bowie.csv&quot;</span><span>)</span>
setnames<span>(</span>network_nodes<span>,</span> <span>colnames</span><span>(</span>network_nodes<span>),</span> <span>c</span><span>(</span><span>&quot;target_num&quot;</span><span>,</span><span>&quot;x&quot;</span><span>,</span><span>&quot;y&quot;</span><span>))</span>
network_nodes <span>&lt;-</span> join<span>(</span>network_nodes<span>,</span> network_names<span>[,</span><span>c</span><span>(</span><span>&quot;target&quot;</span><span>,</span><span>&quot;target_num&quot;</span><span>)],</span> by <span>=</span> <span>&quot;target_num&quot;</span><span>)</span>
network_nodes <span>&lt;-</span> network_nodes<span>[,</span><span>c</span><span>(</span><span>&quot;target&quot;</span><span>,</span><span>&quot;x&quot;</span><span>,</span><span>&quot;y&quot;</span><span>)]</span>
setnames<span>(</span>network_nodes<span>,</span> <span>colnames</span><span>(</span>network_nodes<span>),</span> <span>c</span><span>(</span><span>&quot;Artist&quot;</span><span>,</span><span>&quot;x&quot;</span><span>,</span><span>&quot;y&quot;</span><span>))</span>

network_nodes_json <span>&lt;-</span> toJSON<span>(</span>network_nodes<span>,</span> pretty<span>=</span><span>TRUE</span><span>)</span>
<span>write</span><span>(</span>network_nodes_json<span>,</span> <span>&quot;bowie_nodes.json&quot;</span><span>)</span>
</pre></div>
<h2>Put your files in a D3Plus network template</h2>
<p>In my case I decided to use <a href="https://bl.ocks.org/">bl.ocks.org</a> to show my network. Use this template and edit the links to data, edges and nodes to make it to work.</p>
<div><pre><span></span><span>&lt;!doctype html></span>
  <span>&lt;meta</span> <span>charset=</span><span>&quot;utf-8&quot;</span><span>></span>
  <span>&lt;script</span> <span>src=</span><span>&quot;https://d3plus.org/js/d3.js&quot;</span><span>>&lt;/script></span>
  <span>&lt;script</span> <span>src=</span><span>&quot;https://d3plus.org/js/d3plus.js&quot;</span><span>>&lt;/script></span>
          <span>&lt;div</span> <span>id=</span><span>&quot;network&quot;</span><span>>&lt;/div></span>
          <span>&lt;script></span>
          var visualization = d3plus.viz()
          .container(&quot;#network&quot;)
          .data(&quot;bowie_data.json&quot;)
          .edges(&quot;bowie_edges.json&quot;)
          .nodes(&quot;bowie_nodes.json&quot;)
          .type(&quot;network&quot;)
          .resize(true)
          .id([&quot;Genre&quot;,&quot;Artist&quot;])
          .font({&quot;family&quot;: &quot;Lato&quot;})
          .size(1)
          .depth(1)
          .color(&quot;Color&quot;)
          .title(&quot;David Bowie Collaborations&quot;)
          .tooltip({&quot;value&quot;: [&quot;Genre&quot;,&quot;Collaboration&quot;],&quot;size&quot;: false})
          .legend({&quot;size&quot;: 32})
          .draw()
          <span>&lt;/script></span>
<span>&lt;link</span> <span>href=</span><span>&quot;https://fonts.googleapis.com/css?family=Lato:400,700&quot;</span> <span>rel=</span><span>&quot;stylesheet&quot;</span> <span>type=</span><span>&quot;text/css&quot;</span><span>></span>
</pre></div>
<p>You can also use Roboto, another Google Font or just any typography you want.</p>
<h1>Final result</h1>
<p>After some edges editing in Atom (just aesthetic changes to put some edges closer to similar artists) the result is <a href="https://bl.ocks.org/pachamaltese/cb8c7086631f3b84a3f3d398823ea6fa">here</a>.</p>