Skip to content

Commit

Permalink
added dynamic layouts (#23)
Browse files Browse the repository at this point in the history
  • Loading branch information
schochastics committed Aug 18, 2019
1 parent c214171 commit 6b0b227
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 0 deletions.
1 change: 1 addition & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
export(annotate_circle)
export(draw_circle)
export(layout_as_backbone)
export(layout_as_dynamic)
export(layout_igraph_backbone)
export(layout_igraph_centrality)
export(layout_igraph_eigen)
Expand Down
89 changes: 89 additions & 0 deletions R/dynamic_graphs.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
#' Dynamic graph layout
#' @description Layout a series of networks.
#' @name dynamic_layout
#' @param gList list of igraph object
#' @param alpha weighting of reference layout. See details.
#' @param iter number of iterations during stress optimization
#' @param tol stopping criterion for stress optimization
#' @details The reference layout is calculated based on the union of all graphs. The parameter alpha controls the influence of the reference layout.
#' For alpha=1, only the reference layout is used and all graphs have the same layout. For alpha=0, the stress layout of each individual graph is used. Values inbetween interpolate between the two layouts.
#' @return coordinates to be used layouting the graphs
#' @references Brandes, U. and IndleKofer, N. and Mader, M. (2012). Visualization methods for longitudinal social networks and stochastic actor-oriented modeling. *Social Networks* 34 (3) 291-308
#' @export
#'

layout_as_dynamic <- function(gList,alpha=0.5,iter=500,tol=0.0001){
#prepare reference layout
g <- Reduce("%u%",gList)
n <- igraph::vcount(g)
DList <- lapply(gList,igraph::distances)
DList <- adjust_dist(DList)
Dmean <- Reduce('+', DList)/length(DList)
Dvar <- Reduce('+',lapply(DList, function(x) (x-Dmean)^2))/length(DList)
W <- 1/Dmean^2+1/(1+Dvar)
diag(W) <- 0

#calculate reference layout
rmat <- matrix(stats::runif(n*2,-0.1,0.1),n,2)
xinit <- igraph::layout_with_mds(g) + rmat
xref <- stress_major(xinit,W,Dmean,iter,tol)

xycoords <-vector("list",length(gList))
for(i in 1:length(gList)){
D <- DList[[i]]
W <- 1/D^2
diag(W) <- 0
if(i==1){
xycoords[[i]] <- stress_major(xref,W,D,iter,tol)
} else{
xycoords[[i]] <- stress_major(xycoords[[i-1]],W,D,iter,tol)
}
xycoords[[i]] <- (1-alpha)*xycoords[[i]]+alpha*xref
}
xycoords
}

adjust_dist <- function(DList){
n <- nrow(DList[[1]])
for(i in 1:n){
for(j in 1:n){
for(k in 1:length(DList)){
if(is.infinite(DList[[k]][i,j])){
lastD <- Inf
for(l in seq((k-1),1)){
if(l==0){
next()
}
if(!is.infinite(DList[[l]][i,j])){
lastD <- DList[[l]][i,j]
tlast <- l
break()
}
}
nextD <- Inf
for(l in seq((k+1),length(DList))){
if(l>length(DList)){
break()
}
if(!is.infinite(DList[[l]][i,j])){
nextD <- DList[[l]][i,j]
tnext <- l
break()
}
}
if(!is.infinite(lastD) & !is.infinite(nextD)){
beta <- (k-tlast)/(tnext-tlast)
DList[[k]][i,j] <- (1-beta)*lastD+beta*nextD+1
} else if(is.infinite(lastD) & !is.infinite(nextD)){
DList[[k]][i,j] <- nextD+1
} else if(!is.infinite(lastD) & is.infinite(nextD)){
DList[[k]][i,j] <- lastD+1
} else{
DList[[k]][i,j] <- sqrt(n)
}
}
}
}
}
DList
}
31 changes: 31 additions & 0 deletions man/dynamic_layout.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 6b0b227

Please sign in to comment.