graphlayouts/ 0000755 0001762 0000144 00000000000 14164606432 013002 5 ustar ligges users graphlayouts/NAMESPACE 0000644 0001762 0000144 00000001637 14162663334 014232 0 ustar ligges users # Generated by roxygen2: do not edit by hand
export(annotate_circle)
export(draw_circle)
export(layout_as_backbone)
export(layout_as_dynamic)
export(layout_as_multilevel)
export(layout_igraph_backbone)
export(layout_igraph_centrality)
export(layout_igraph_constrained_stress)
export(layout_igraph_eigen)
export(layout_igraph_focus)
export(layout_igraph_multilevel)
export(layout_igraph_pmds)
export(layout_igraph_sparse_stress)
export(layout_igraph_stress)
export(layout_igraph_umap)
export(layout_mirror)
export(layout_rotate)
export(layout_with_centrality)
export(layout_with_constrained_stress)
export(layout_with_constrained_stress3D)
export(layout_with_eigen)
export(layout_with_focus)
export(layout_with_pmds)
export(layout_with_sparse_stress)
export(layout_with_stress)
export(layout_with_stress3D)
export(layout_with_umap)
export(reorder_edges)
importFrom(Rcpp,sourceCpp)
useDynLib(graphlayouts, .registration = TRUE)
graphlayouts/LICENSE 0000644 0001762 0000144 00000000052 13447644144 014011 0 ustar ligges users YEAR: 2019
COPYRIGHT HOLDER: David Schoch
graphlayouts/README.md 0000644 0001762 0000144 00000022421 14162151502 014251 0 ustar ligges users
# graphlayouts
[](https://github.com/schochastics/graphlayouts/actions)
[](https://cran.r-project.org/package=graphlayouts)
[](https://CRAN.R-project.org/package=graphlayouts)
This package implements some graph layout algorithms that are not
available in `igraph`.
**A detailed introductory tutorial for graphlayouts and ggraph can be
found [here](http://mr.schochastics.net/netVizR.html).**
The package implements the following algorithms:
- Stress majorization
([Paper](https://graphviz.gitlab.io/_pages/Documentation/GKN04.pdf))
- Quadrilateral backbone layout
([Paper](https://jgaa.info/accepted/2015/NocajOrtmannBrandes2015.19.2.pdf))
- flexible radial layouts
([Paper](https://jgaa.info/accepted/2011/BrandesPich2011.15.1.pdf))
- sparse stress ([Paper](https://arxiv.org/abs/1608.08909))
- pivot MDS
([Paper](https://kops.uni-konstanz.de/bitstream/handle/123456789/5741/bp_empmdsld_06.pdf?sequence=1&isAllowed=y))
- dynamic layout for longitudinal data
([Paper](https://kops.uni-konstanz.de/bitstream/handle/123456789/20924/Brandes_209246.pdf?sequence=2))
- spectral layouts (adjacency/Laplacian)
- a simple multilevel layout
- a layout algorithm using UMAP
## Install
``` r
# dev version
remotes::install_github("schochastics/graphlayouts")
#CRAN
install.packages("graphlayouts")
```
## Stress Majorization: Connected Network
*This example is a bit of a special case since it exploits some weird
issues in igraph.*
``` r
library(igraph)
library(ggraph)
library(graphlayouts)
set.seed(666)
pa <- sample_pa(1000,1,1,directed = F)
ggraph(pa,layout = "nicely")+
geom_edge_link0(width=0.2,colour="grey")+
geom_node_point(col="black",size=0.3)+
theme_graph()
```
``` r
ggraph(pa,layout="stress")+
geom_edge_link0(width=0.2,colour="grey")+
geom_node_point(col="black",size=0.3)+
theme_graph()
```
## Stress Majorization: Unconnected Network
Stress majorization also works for networks with several components. It
relies on a bin packing algorithm to efficiently put the components in a
rectangle, rather than a circle.
``` r
set.seed(666)
g <- disjoint_union(
sample_pa(10,directed = F),
sample_pa(20,directed = F),
sample_pa(30,directed = F),
sample_pa(40,directed = F),
sample_pa(50,directed = F),
sample_pa(60,directed = F),
sample_pa(80,directed = F)
)
ggraph(g,layout = "nicely") +
geom_edge_link0() +
geom_node_point() +
theme_graph()
```
``` r
ggraph(g, layout = "stress",bbox = 40) +
geom_edge_link0() +
geom_node_point() +
theme_graph()
```
## Backbone Layout
Backbone layouts are helpful for drawing hairballs.
``` r
set.seed(665)
#create network with a group structure
g <- sample_islands(9,40,0.4,15)
g <- simplify(g)
V(g)$grp <- as.character(rep(1:9,each=40))
ggraph(g,layout = "stress")+
geom_edge_link0(colour=rgb(0,0,0,0.5),width=0.1)+
geom_node_point(aes(col=grp))+
scale_color_brewer(palette = "Set1")+
theme_graph()+
theme(legend.position = "none")
```
The backbone layout helps to uncover potential group structures based on
edge embeddedness and puts more emphasis on this structure in the
layout.
``` r
bb <- layout_as_backbone(g,keep=0.4)
E(g)$col <- F
E(g)$col[bb$backbone] <- T
ggraph(g,layout="manual",x=bb$xy[,1],y=bb$xy[,2])+
geom_edge_link0(aes(col=col),width=0.1)+
geom_node_point(aes(col=grp))+
scale_color_brewer(palette = "Set1")+
scale_edge_color_manual(values=c(rgb(0,0,0,0.3),rgb(0,0,0,1)))+
theme_graph()+
theme(legend.position = "none")
```
## Radial Layout with Focal Node
The function `layout_with_focus()` creates a radial layout around a
focal node. All nodes with the same distance from the focal node are on
the same circle.
``` r
library(igraphdata)
library(patchwork)
data("karate")
p1 <- ggraph(karate,layout = "focus",focus = 1) +
draw_circle(use = "focus",max.circle = 3)+
geom_edge_link0(edge_color="black",edge_width=0.3)+
geom_node_point(aes(fill=as.factor(Faction)),size=2,shape=21)+
scale_fill_manual(values=c("#8B2323", "#EEAD0E"))+
theme_graph()+
theme(legend.position = "none")+
coord_fixed()+
labs(title= "Focus on Mr. Hi")
p2 <- ggraph(karate,layout = "focus",focus = 34) +
draw_circle(use = "focus",max.circle = 4)+
geom_edge_link0(edge_color="black",edge_width=0.3)+
geom_node_point(aes(fill=as.factor(Faction)),size=2,shape=21)+
scale_fill_manual(values=c("#8B2323", "#EEAD0E"))+
theme_graph()+
theme(legend.position = "none")+
coord_fixed()+
labs(title= "Focus on John A.")
p1+p2
```
## Radial Centrality Layout
The function `layout_with_centrality` creates a radial layout around the
node with the highest centrality value. The further outside a node is,
the more peripheral it is.
``` r
library(igraphdata)
library(patchwork)
data("karate")
bc <- betweenness(karate)
p1 <- ggraph(karate,layout = "centrality", centrality = bc, tseq = seq(0,1,0.15)) +
draw_circle(use = "cent") +
annotate_circle(bc,format="",pos="bottom") +
geom_edge_link0(edge_color="black",edge_width=0.3)+
geom_node_point(aes(fill=as.factor(Faction)),size=2,shape=21)+
scale_fill_manual(values=c("#8B2323", "#EEAD0E"))+
theme_graph()+
theme(legend.position = "none")+
coord_fixed()+
labs(title="betweenness centrality")
cc <- closeness(karate)
p2 <- ggraph(karate,layout = "centrality", centrality = cc, tseq = seq(0,1,0.2)) +
draw_circle(use = "cent") +
annotate_circle(cc,format="scientific",pos="bottom") +
geom_edge_link0(edge_color="black",edge_width=0.3)+
geom_node_point(aes(fill=as.factor(Faction)),size=2,shape=21)+
scale_fill_manual(values=c("#8B2323", "#EEAD0E"))+
theme_graph()+
theme(legend.position = "none")+
coord_fixed()+
labs(title="closeness centrality")
p1+p2
```
## Large graphs
`graphlayouts` implements two algorithms for visualizing large networks
(\<100k nodes). `layout_with_pmds()` is similar to `layout_with_mds()`
but performs the multidimensional scaling only with a small number of
pivot nodes. Usually, 50-100 are enough to obtain similar results to the
full MDS.
`layout_with_sparse_stress()` performs stress majorization only with a
small number of pivots (\~50-100). The runtime performance is inferior
to pivotMDS but the quality is far superior.
A comparison of runtimes and layout quality can be found in the
[wiki](https://github.com/schochastics/graphlayouts/wiki/)
**tl;dr**: both layout algorithms appear to be faster than the fastest
igraph algorithm `layout_with_drl()`.
Below are two examples of layouts generated for large graphs using
`layout_with_sparse_stress()`
A retweet network with 18k nodes and 61k edges
A co-citation network with 12k nodes and 68k edges
## dynamic layouts
`layout_as_dynamic()` allows you to visualize snapshots of longitudinal
network data. Nodes are anchored with a reference layout and only moved
slightly in each wave depending on deleted/added edges. In this way, it
is easy to track down specific nodes throughout time. Use `patchwork` to
put the individual plots next to each other.
``` r
library(patchwork)
#gList is a list of longitudinal networks.
xy <- layout_as_dynamic(gList,alpha = 0.2)
pList <- vector("list",length(gList))
for(i in 1:length(gList)){
pList[[i]] <- ggraph(gList[[i]],layout="manual",x=xy[[i]][,1],y=xy[[i]][,2])+
geom_edge_link0(edge_width=0.6,edge_colour="grey66")+
geom_node_point(shape=21,aes(fill=smoking),size=3)+
geom_node_text(aes(label=1:50),repel = T)+
scale_fill_manual(values=c("forestgreen","grey25","firebrick"),guide=ifelse(i!=2,FALSE,"legend"))+
theme_graph()+
theme(legend.position="bottom")+
labs(title=paste0("Wave ",i))
}
Reduce("+",pList)+
plot_annotation(title="Friendship network",theme = theme(title = element_text(family="Arial Narrow",face = "bold",size=16)))
```
## Layout manipulation
The functions `layout_mirror()` and `layout_rotate()` can be used to
manipulate an existing layout
graphlayouts/data/ 0000755 0001762 0000144 00000000000 13650032646 013712 5 ustar ligges users graphlayouts/data/multilvl_ex.rda 0000644 0001762 0000144 00000021553 13650032646 016754 0 ustar ligges users BZh91AY&SYI }LDUWDT\DDDDDDDDdE4 0@ @HD ( @*$ H" ( U@Ɂ1 ==&MCM @h4@4 d *T~oO)*4 z 4 4 @ U=CMEH d MM C@ FFi&&h`# 2`&0 # d !B M
4CM40F0M M2 * L
j~
1SI=OĞOSOB!O&
6SM2@dh='ꙩ
k,C%D#Y#DF`"X"ЪHRUu"."(Wk.OQ
]rAETE]X.ut`UD`BXB.dYeX,YdeE,!ad,B,B,Y,ʊ*"ȊnE)vtT\*,0EYw.CbL
FJYWYb]eB"]d.YA,`+vCYeD"J˪UoYfhTY.+"d`E,e5]aʲEXĺ5]t,Ru)a.]DYg!()OԲ6.łYt]
!ƅ,b(ɉE?܋Ҋ2P"?Rꥋ]B,e(ʪbWY"噂QuR#QFQ0`Y&lYT1QQFłQQD`VXҢ@f`ͥUUu]eͫ]+%\-,˩,X,C$bYyQ)KC6&-)ś%hYdEج`LX5!"UYtdȫ0"ȋBYY].dl31`ˬ3b͛6g]v6lX6,2dɓK1]c&Hؘ
(ɋ`Y#'5٣LرEf2]ȌٳdЋ43"Fl5f=Vl_QœCbXY15.6{{&VYi̻[sc7K7ވ͵śCZmM-ω'»kM
퍭1vL\lldb[VXlq76CKcɓK&m55~675,M뵬ŋkk{6L743d͵fɩv8W,ͭc?+S{&Ɨ,43fŵfٷ1Yv
ML
lp.]KC
k68Zo]cb4,ũk6
i]B[ZZ-Q]vkj]467vMVjdű3p6758ۗ8YjY4iimp!n6#{&vp782ioYͽq1nodŹKS'sƶƖcj,ԌMLZۚn?C{ci?ŭmkYڻj5#=q4{{[K渚kq8%Qbz-Mu:}u=
.f'bq=Giw68.O#riy`:.wm,}Gkzd[}q4{&k69^SE]CYnvf͓c;ot;ڜ畓;<.sCSub;lzcIDEfn[-^Fc`uv;\p#if}v#ccdw;"+[ֻ[mkfbr7Z7סkv]NcCkkSjhu=
K5Zkjt=nns[,kv<:zWcKv.r<mfnr6wWw8λw75:NqwMRsYyiq}tqvng1ػQj99dhuzyiv6Kw]#{ysv#&dxkgy_mw*t&vep=nv=WY>%fFe_cj2G#xnfӶ-dm4T.ø_^vn6뉾[avȴu..4ʙӰqiV&Mn7W˶o15EdqZb\TUFEY)-noCSMfK4dԱZ`Fh}
fd.ͭf
ɛdͪ1|m3YbbZե3`.ؚhbY?CSj,Ħhk"5'r.eژY
l2`ͭdb+΅47Y" .mG!e?u8ZFHɃ`j`T#!`5\˾U!tVߕD+c&/TS'DR?:B*3`!ڲOIscf/18\k`5IܳEWY^Uz;]jlY_1UOUh{*Kz|Ǡ5?xYW!<
+ʊV敇EY[UU,<5lB"8`S7"_H:[\ŁtI\7?Ye!O8YFifOsB^VM`ȳ٬0C/>7(́F
,.ɥU^TYVև@5?g3BXqDwEs{yo!V'[|5=->
Oym#26q?)~uOX~*WIxY|szOY<SOzj/9^RqyD1g6Odɓ&OpPiɲܵ*?ɛ??QJ*U(z*)UUUURBPJ̟kR"WȈEYU0WV,\ĈE1"!ȄYtBdBBQLQQYDT"!Q,%P""PDA
GTًJG>g7XZUJUU!((+jXJwraFjUQJ+
ZU*UDQQ DQDQQZ*QDTr;T
!ETB"UUQDRBDAUQ"!U]
DA*""GhШDRT.,?UR!B!vE"DU"d*EDD"""UbB!DAB@G>D|FMO_'ItG몫@*ez6M
a&jkWV~kOWw~4?zU,g?Gqs랺U*yx^.KQm:]-3z9`>Cs{8Yʦ]]]v]jNSގӠ;Ut:b:E`Y1d/O~cTQ,E,be*?q+mfo?C`
/b3nY<+]=yiYMf3:ҵC"LDd)dI^d2$d2C!r1up+F,
l0b̥{,:γu]gZ38gYuWAfZ
[s>.--0-*ZR`0U`VVr:Mjo+++NYYZEeeYk6I${%伕Y~i/b +-ͫͭͭ-mk!K"RȲ,/uYeYeYe,NU6-]u[[[[[Z_sڻkEDDDDDDDDg
*&Mu]mp8ZZȈ>G;wz2dr)N@mmG#r뮻r9-mh۲ȏȈoUP&]vj0bɵu]1)QJڻ]v֦֖e诚{
=|/R_I|vǘ+hsP3]eVdY
MnC%jl|OԳ?+Y~S*#T~?#TGߐ?">WU>Gs'+w!>S|W|ȯ!};{Ws9ϼU~+UH`TBET "DB 좘">UBAUVB)ED* Q"*"DBB"* "D(UDU !QHB"*"")QBT!!*"TBD"""!DUED!dYPDEBE"DR"*DED*")DTEBTDBQ**(*U!QQ"E"PDBEED!H"*"B"""B"UTE
TEBHR"B)!UQE"*!(RB!QDB" E*UUDTTDE"!HB"ETBB"DJ"DDUDRJEDTB!"REUR"R(A!TDUTDR*TAQ*TEPE"!Q
RUD@D""DRHD*)D("*DD"Q!Q
EDQU")TE"*Q
AQ
D* "(" AUTEU")HE"
@D)EDUTEB"BUT*!TEUDU4HYHE*UUUQ""UQ
UHRD
E(* DDDPD)HUDU TB
*UTBHU"*H"R""!UH"UDRTB"UeQUq9c2b'rSʯ)GQ^s9^W#Ťi4d#5B
D)]JtjXZo^Xaai5^a*TT******NQQQQw㺝! R
DEUB
D)B
D)u&q&L¨mY#:o":luγus+p]S6i`Œ3g=U}d}w߬`,")eu>'čOvOvCpĹa}Kz(\o%g2y;sW/]?37³K~$Gu3oi?/i='}}TzWzOJzOI='^ozOI='zOJ'zOIgzCp=='@(p'BK.QGx;zWyWyήssfs9*Yhf*==atGҥ^/;I ֒INiwSI:t'';s ɉG*QeUSCKAŰW09c9c9c9LXb){b,
{1]}Fذ}כּ]{}Qi+i+m*V3Q17y+}*e"eSyp7O~n7՛'a:͇Y7YWZγ:S9NW)Jՙt=erXzY,XX
OY]geYlh)?LQQYv«eK6Vdت`в},M[hd]J>>5
>G(`sjYCJf՟aFgSVjbm7>wj]#c+#K.YoS=}e|iw|}7|
>|*|&|'|'|'|'|'yj|.7cfaŊ,Vu":uG!uJ9NSr24ZhRoJKjT%PZPP+9|oF