The outward position does almost what I want in my network (left labels to the left, right to the right).
However I want to modify it slightly to avoid overlap with nodes. I try searching in the gtable (ggplot_build
, ggplot_gtable
) what to modify without success. In the gtable, the position of the labels appears just as outwards
, not as a number I can modify.
Even if I change outwards
for other option, I see just a symbolic value of justification not a real position value.
Minimal example:
#
# matrix
#
myvec<-structure(list(lengths = c(1L, 2L, 27L, 1L, 6L, 1L, 15L, 1L,
23L, 1L, 4L, 2L, 77L, 1L, 1L, 1L, 22L, 2L, 21L, 1L, 3L, 1L, 30L,
2L, 38L, 1L, 40L, 2L, 22L, 1L, 12L, 1L, 8L, 1L, 12L, 1L, 9L,
1L, 9L, 1L, 28L, 2L, 12L, 1L, 31L, 1L, 12L, 1L, 5L, 1L, 15L,
1L, 10L, 1L, 25L, 1L, 16L, 1L, 27L, 1L, 25L, 1L, 31L, 2L, 20L
), values = c(0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0)), class = "rle")
mymat <- structure(unlist(mapply(rep, myvec$values, myvec$lengths) ),
.Dim = c(26L, 26L), .Dimnames = list(NULL, NULL) )
colnames(mymat) <- paste("name", 1:ncol(mymat))
row.names(mymat) <- paste("name", 1:nrow(mymat))
#
# network
#
library(network)
net1 <- network(mymat,
matrix.type = "adjacency",
ignore.eval = FALSE
,directed=T
)
#
# Custom position of nodes
#
finalxy<-structure(c(-2, 0, 0, 6, 2, 6, 4, 6, 2, -6, -4, 0, 4, 0, 8, 8,
-4, -2, -2, 8, 10, 2, 0, -4, -2, 4, 4, 2, 4, 4, 0, 2, -2, -2,
2, -2, -2, 0, -4, -2, -4, -2, 0, 0, -2, 0, 0, -2, -4, -4, -4,
4), .Dim = c(26L, 2L) )
net1 %v% "xpos" = finalxy[, 1]
net1 %v% "ypos" = finalxy[, 2]
#
# edges
#
library(ggnetwork)
library(dplyr)
networkdata <- sapply(net1$mel, function(x)
c('id_inl' = x$inl, 'id_outl' = x$outl, 'weight' = x$atl$weights)) %>%
t %>% as_tibble()
posxyOrig<-finalxy[networkdata$id_outl,]
posxyTarg<-finalxy[networkdata$id_inl,]
colnames(posxyOrig)<-c("xorig","yorig")
colnames(posxyTarg)<-c("xtarg","ytarg")
posData1<-cbind(networkdata,posxyOrig,posxyTarg )
#
# modify arrows (edges) to avoid overlap
#
posData1$xtarg <- ifelse(posData1$xorig>posData1$xtarg,
posData1$xtarg+.2,
ifelse(posData1$xorig==posData1$xtarg,
posData1$xtarg,
posData1$xtarg-.2
)
)
posData1$ytarg <- ifelse(posData1$yorig>posData1$ytarg,
posData1$ytarg+.2,
ifelse(posData1$yorig==posData1$ytarg,
posData1$ytarg,
posData1$ytarg-.2
)
)
#
# plot
#
ggplot(net1 )+
geom_edges(data=posData1, aes(x = xorig, y = yorig, xend = xtarg, yend = ytarg),
arrow = arrow(length = unit(10, "pt"), type = "closed")
) +
geom_nodes(aes(x=xpos, y=ypos ), size = 4) +
geom_nodelabel(aes(x=xpos, y=ypos, label = vertex.names ),
hjust="outward",
vjust="outward"
,fontface = "italic", size=3
) + theme_blank()
EDIT
# related to https://stackoverflow.com/questions/56028991/override-horizontal-positioning-with-ggrepel
ggplot(ggnetwork(net1) )+
geom_edges(data=posData1, aes(x = xorig, y = yorig, xend = xtarg, yend = ytarg),
arrow = arrow(length = unit(10, "pt"), type = "closed")
) +
geom_nodes(aes(x=xpos, y=ypos ), size = 4) +
geom_nodelabel_repel(aes(x=xpos, y=ypos, label = vertex.names ),
hjust="outward",
vjust="outward"
,fontface = "italic", size=3
) + theme_blank()
Solution: Use ggrepel, change outward for inward
Related: https://github.com/slowkow/ggrepel/issues/191