<p>I am absolutely thrilled to announce that <code>ggraph</code> has finally been released<br>
on CRAN. <code>ggraph</code> is my most ambitious package to date and its very early<br>
genesis has been described in a <a target="_blank" rel="nofollow" href="http://www.data-imaginist.com/2016/Becoming-the-intern/">prior post</a>.<br>
If any mention of <code>ggraph</code> is completely new to you, then in short terms <code>ggraph</code><br>
is an extension of the <code>ggplot2</code> API to support relational data such as networks<br>
and trees. I feel fairly confident in saying that <code>ggraph</code> is the most<br>
powerful way to create static network based visualizations in R. Leading up to<br>
the release, the three main concepts of <code>ggraph</code> has been described in detail in<br>
their own blog posts<br>
(<a target="_blank" rel="nofollow" href="http://www.data-imaginist.com/2017/ggraph-introduction-layouts/">layouts</a>,<br>
<a target="_blank" rel="nofollow" href="http://www.data-imaginist.com/2017/ggraph-introduction-nodes/">nodes</a>, and<br>
<a target="_blank" rel="nofollow" href="http://www.data-imaginist.com/2017/ggraph-introduction-edges/">edges</a>) so this<br>
will not be reiterated here. Instead I’ll talk a bit about the philosophy behind<br>
the package as well as show of some of the features that do not fall into any of<br>
the three main concepts.</p>
<h2>The Philosophy</h2>
<p>There is no shortage of software for creating network visualizations and there<br>
is no shortage of said visualizations themselves. Often though, the<br>
visualizations are more impressive than informative and it is easy to feel that<br>
their main task is to show that we are really dealing with some complex data.<br>
All of this has led to a certain disdain for classic network visualizations<br>
perfectly encapsulated in the nickname <em>hairballs</em>. It does not have to be like<br>
this! The greatness of <code>ggplot2</code> lies in how it allows users to quickly iterate<br>
over visualization approaches, thus better ensuring that the best visualization<br>
approach is reached. If this was extended to relational data it is my belief<br>
that users would be more likely to try to make plots that are more meaningful.<br>
After all we all want interpretability, right? Consider having to try out 7<br>
different network visualization packages with different APIs versus just mixing<br>
and matching layouts and geoms in an iterative process — I know which way I<br>
prefer.</p>
<p>The goal of <code>ggraph</code> is thus clear — provide everything related to<br>
visualizations of relational data in a <code>ggplot2</code>-like API to lessen the<br>
cognitive load on experimenting with different visual representations. I’m not<br>
there yet, but I feel the current version represents a solid foundation where<br>
most users will not feel many limitations — on the contrary I believe most<br>
users will feel like the chains have come off and they are set free.</p>
<h3>Future focus</h3>
<p>As I pointed out, <code>ggraph</code> is far from done. I’ll try to keep my development<br>
focus in the open by putting things on the road-map as<br>
<a target="_blank" rel="nofollow" href="https://github.com/thomasp85/ggraph/issues">GitHub issues</a>. Honorable mentions<br>
include matrix, d3-force and sankey layout, expanded support for edge endings<br>
(more choices than <code>grid::arrow()</code> provides), edge routing (avoid node<br>
collision), and textbox nodes. I welcome all suggestions as the world of network<br>
visualizations is moving fast and I cannot keep on top of everything.</p>
<h2>Features besides layouts, nodes, and edges</h2>
<p>Understanding the node and edge geoms along with how layouts are defined will<br>
get you a long way towards visualizing networks. Still, <code>ggraph</code> has more to<br>
offer, some of which will be discussed here:</p>
<h3>theme_graph()</h3>
<p>Consider the following plot:</p>
<figure>
<pre><code data-lang="r"><span>library</span><span>(</span><span>ggraph</span><span>)</span><span>
</span><span>library</span><span>(</span><span>igraph</span><span>)</span><span>
</span><span>graph</span><span> </span><span>&lt;-</span><span> </span><span>graph_from_data_frame</span><span>(</span><span>highschool</span><span>)</span><span>
</span><span>p</span><span> </span><span>&lt;-</span><span> </span><span>ggraph</span><span>(</span><span>graph</span><span>,</span><span> </span><span>layout</span><span> </span><span>=</span><span> </span><span>'kk'</span><span>)</span><span> </span><span>+</span><span> </span><span>geom_edge_link</span><span>(</span><span>aes</span><span>(</span><span>colour</span><span> </span><span>=</span><span> </span><span>factor</span><span>(</span><span>year</span><span>)))</span><span> </span><span>+</span><span> </span><span>geom_node_point</span><span>()</span><span> </span><span>+</span><span> </span><span>ggtitle</span><span>(</span><span>'An example'</span><span>)</span><span>
</span><span>p</span></code></pre>
</figure>
<p><img alt="center" src="https://i0.wp.com/www.data-imaginist.com/assets/images/2017-02-23-Announcing-ggraph/unnamed-chunk-2-1.png?w=456" data-recalc-dims="1"></p>
<p>While the <code>ggplot2</code> heritage clearly shows due to the grey background with white<br>
grid lines, the whole concept of x and y axes is often redundant in network<br>
visualizations and are just a distraction. <code>ggraph</code> provides its own theme<br>
optimized for network visualizations called <code>theme_graph()</code>, that facilitates<br>
clean and beautiful visualizations:</p>
<figure>
<pre><code data-lang="r"><span>p</span><span> </span><span>+</span><span> </span><span>theme_graph</span><span>()</span></code></pre>
</figure>
<p><img alt="center" src="https://i1.wp.com/www.data-imaginist.com/assets/images/2017-02-23-Announcing-ggraph/unnamed-chunk-3-1.png?w=456" data-recalc-dims="1"></p>
<p><code>theme_graph()</code>, besides removing axes, grids, and border, changes the font to<br>
<em>Arial Narrow</em> (this can be overridden). Furthermore, it makes it easy to change<br>
the coloring of the plot:</p>
<figure>
<pre><code data-lang="r"><span>p</span><span> </span><span>+</span><span> </span><span>theme_graph</span><span>(</span><span>background</span><span> </span><span>=</span><span> </span><span>'grey20'</span><span>,</span><span> </span><span>text_colour</span><span> </span><span>=</span><span> </span><span>'white'</span><span>)</span></code></pre>
</figure>
<p><img alt="center" src="https://i1.wp.com/www.data-imaginist.com/assets/images/2017-02-23-Announcing-ggraph/unnamed-chunk-4-1.png?w=456" data-recalc-dims="1"></p>
<p>Adding the same theme to every plot is tedious and <code>ggraph</code> provides a way to<br>
avoid this. Using <code>set_graph_style()</code> the <code>theme_graph()</code> is set as default. As<br>
an extra benefit all text-based geoms gets their defaults updated so the text<br>
automatically uses the same style as the theme.</p>
<figure>
<pre><code data-lang="r"><span>set_graph_style</span><span>()</span><span>
</span><span>p</span></code></pre>
</figure>
<p><img alt="center" src="https://i0.wp.com/www.data-imaginist.com/assets/images/2017-02-23-Announcing-ggraph/unnamed-chunk-5-1.png?w=456" data-recalc-dims="1"></p>
<h3>Facetting</h3>
<p>A powerful but underutilized way of gaining insight into networks is by using<br>
small multiples. This technique can reduce edge over-plotting in a very<br>
meaningful way by spreading nodes and edges out based on their attributes. The<br>
benefits of small multiples are not unique to relational data, as the popularity<br>
of <code>ggplot2</code>s facetting functionality shows. The base facetting functions<br>
provided by <code>ggplot2</code> is a bad fit for networks though, as we are working with<br>
two very distinct types of data. If you facet on a node attribute, all edges<br>
would be plotted in all panels, despite the terminal nodes not being present<br>
which is not what you expect. Because of this <code>ggraph</code> comes with its own set<br>
of facetting functions tailored to network data:</p>
<h4>facet_nodes() and facet_edges()</h4>
<p>These two functions are equivalent to <code>facet_wrap()</code> in functionality, but they<br>
only address node and edge data respectively. When using <code>facet_nodes()</code> edges<br>
are only drawn in a panel if both terminal nodes are present there. When using<br>
<code>facet_edges()</code> nodes are always drawn in all panels even if the node data<br>
contains an attribute named the same as the one used for the edge facetting.</p>
<figure>
<pre><code data-lang="r"><span># Assign each node to a random class
</span><span>V</span><span>(</span><span>graph</span><span>)</span><span>$</span><span>class</span><span> </span><span>&lt;-</span><span> </span><span>sample</span><span>(</span><span>letters</span><span>[</span><span>1</span><span>:</span><span>4</span><span>],</span><span> </span><span>gorder</span><span>(</span><span>graph</span><span>),</span><span> </span><span>TRUE</span><span>)</span><span>
</span><span># Make year a character
</span><span>E</span><span>(</span><span>graph</span><span>)</span><span>$</span><span>year</span><span> </span><span>&lt;-</span><span> </span><span>as.character</span><span>(</span><span>E</span><span>(</span><span>graph</span><span>)</span><span>$</span><span>year</span><span>)</span><span>
</span><span>p</span><span> </span><span>&lt;-</span><span> </span><span>ggraph</span><span>(</span><span>graph</span><span>,</span><span> </span><span>layout</span><span> </span><span>=</span><span> </span><span>'kk'</span><span>)</span><span> </span><span>+</span><span> </span><span>geom_edge_fan</span><span>(</span><span>aes</span><span>(</span><span>alpha</span><span> </span><span>=</span><span> </span><span>..index..</span><span>,</span><span> </span><span>colour</span><span> </span><span>=</span><span> </span><span>year</span><span>))</span><span> </span><span>+</span><span> </span><span>geom_node_point</span><span>(</span><span>aes</span><span>(</span><span>shape</span><span> </span><span>=</span><span> </span><span>class</span><span>))</span><span> </span><span>+</span><span> </span><span>scale_edge_alpha</span><span>(</span><span>guide</span><span> </span><span>=</span><span> </span><span>'none'</span><span>)</span><span>
</span><span>p</span><span> </span><span>+</span><span> </span><span>facet_edges</span><span>(</span><span>~</span><span>year</span><span>)</span></code></pre>
</figure>
<p><img alt="center" src="https://i0.wp.com/www.data-imaginist.com/assets/images/2017-02-23-Announcing-ggraph/unnamed-chunk-6-1.png?w=456" data-recalc-dims="1"></p>
<p>Often, when working with small multiples it is nice to have some visual<br>
separation between each plot — setting a foreground color in <code>theme_graph()</code><br>
will add strip background and border (you can also use the <code>th_foreground()</code><br>
helper for this):</p>
<figure>
<pre><code data-lang="r"><span>p</span><span> </span><span>+</span><span> </span><span>facet_nodes</span><span>(</span><span>~</span><span>class</span><span>)</span><span> </span><span>+</span><span> </span><span>th_foreground</span><span>(</span><span>foreground</span><span> </span><span>=</span><span> </span><span>'grey80'</span><span>,</span><span> </span><span>border</span><span> </span><span>=</span><span> </span><span>TRUE</span><span>)</span></code></pre>
</figure>
<p><img alt="center" src="https://i0.wp.com/www.data-imaginist.com/assets/images/2017-02-23-Announcing-ggraph/unnamed-chunk-7-1.png?w=456" data-recalc-dims="1"></p>
<figure>
<pre><code data-lang="r"><span># Lets not have to add this everytime
</span><span>set_graph_style</span><span>(</span><span>foreground</span><span> </span><span>=</span><span> </span><span>'grey80'</span><span>)</span></code></pre>
</figure>
<h4>facet_graph</h4>
<p>Facetting on two variables simultaneously is very powerful and something that<br>
is supported in <code>ggplot2</code> with <code>facet_grid()</code>. In <code>ggraph</code> the same is possible<br>
using <code>facet_graph()</code> that takes the behavior of <code>facet_nodes()</code> and<br>
<code>facet_edges()</code> and combines them:</p>
<figure>
<pre><code data-lang="r"><span>p</span><span> </span><span>+</span><span> </span><span>facet_graph</span><span>(</span><span>year</span><span> </span><span>~</span><span> </span><span>class</span><span>)</span></code></pre>
</figure>
<p><img alt="center" src="https://i2.wp.com/www.data-imaginist.com/assets/images/2017-02-23-Announcing-ggraph/unnamed-chunk-8-1.png?w=456" data-recalc-dims="1"></p>
<p>As with <code>facet_grid()</code> marginal plots are supported as well:</p>
<figure>
<pre><code data-lang="r"><span>p</span><span> </span><span>+</span><span> </span><span>facet_graph</span><span>(</span><span>year</span><span> </span><span>~</span><span> </span><span>class</span><span>,</span><span> </span><span>margins</span><span> </span><span>=</span><span> </span><span>TRUE</span><span>)</span></code></pre>
</figure>
<p><img alt="center" src="https://i2.wp.com/www.data-imaginist.com/assets/images/2017-02-23-Announcing-ggraph/unnamed-chunk-9-1.png?w=456" data-recalc-dims="1"></p>
<p>While the default is to put facet the rows on edges and the columns on nodes,<br>
this is free to change using the <code>row_type</code> and <code>col_type</code> arguments. There is<br>
nothing stopping you from facetting on the same type in each dimension either:</p>
<figure>
<pre><code data-lang="r"><span># Facet edge by the class of their start node as well as year
</span><span>p</span><span> </span><span>+</span><span> </span><span>facet_graph</span><span>(</span><span>year</span><span> </span><span>~</span><span> </span><span>node1.class</span><span>,</span><span> </span><span>col_type</span><span> </span><span>=</span><span> </span><span>'edge'</span><span>)</span></code></pre>
</figure>
<p><img alt="center" src="https://i2.wp.com/www.data-imaginist.com/assets/images/2017-02-23-Announcing-ggraph/unnamed-chunk-10-1.png?w=456" data-recalc-dims="1"></p>
<p>I hope I have convinced you that facetting in the context of relational data is<br>
both very easy, as well as extremely powerful. Avoiding the hairball is one of<br>
the prime goal of network visualizations and using small multiples is a<br>
fantastic way of cutting down on the number of nodes and edges while still<br>
getting the full picture.</p>
<img height="1" alt="" width="1" src="http://feeds.feedburner.com/~r/RBloggers/~4/yGYO_UuvGxw">