Closed tusharmajhi9 closed 4 years ago
preventing node/edge overlap is unfortunately not that easy, especially for such a large graph. You may be better off using a tree layout, since your graph is actually a tree.
ggraph(df.g,"dendrogram",circular=TRUE)+
geom_edge_elbow0(edge_colour="grey66",edge_width=0.3)+
geom_node_point(shape = 21,fill = "grey25",size = 1)+
theme_graph()+
coord_fixed()
The node in the center is 1383. Advantage is that you do not have any overlapping edges. Disadvantage is that the nodes are no longer on concentric circles.
I have already been playing around with non-equidistant circles and this will probably be implemented in the next version.
Thanks a lot! Really appreciate your quick reply. This is really helpful and solves the purpose. Your package is great!
Hi, I'm having the same issue, though with a much smaller graph (~30 nodes). Do you still have plans to implement a possible solution in the near future, like you mentioned above?
I am planing to implement some overlap removal algorithm soon(ish). So the feature will hopeful come eventually
It's a bit of a hack, but I've put this function together which does well at preventing node overlaps in my case. I haven't tested how well it scales though. It leverages the ability to supply a custom layout function to ggraph and uses force field simulation to repel the coordinates of overlapping nodes.
repelled_focus_layout <- function(graph, focus, weights = NULL,
draw.circle = FALSE, circle_col = "#08306B",
rep.fact = 20, rep.dist.lmt = 0.4, attr.fact = 0.2,
adj.max = 0.1, adj.lmt = 0.5, iter.max = 10000) {
# Create initial focus layout
g <- ggraph::ggraph(graph, layout = "focus", focus = focus, weights = weights) +
ggplot2::coord_fixed()
if (draw.circle == TRUE) {
g <- g + graphlayouts::draw_circle(use = "focus", max.circle = max(igraph::distances(graph, v = focus, weights = NA)), col = circle_col) # Will automatically determine correct number of circles to draw.
}
# Extract plotting coordinates from plot object
focus_coords <- g$data[focus, c("x", "y")] # Separate out coordinates of focus node to ensure that they are not changed.
other_coords <- g$data[-focus, c("x", "y")]
# Modify coordinates so that overlapping nodes are repelled
repelled_coords <- FField::FFieldPtRep(coords = other_coords,
rep.fact = rep.fact, # Repulsion force factor.
rep.dist.lmt = rep.dist.lmt, # Repulsion distance limit.
attr.fact = attr.fact, # Attraction force factor.
adj.max = adj.max, # Maximum position adjustment at each iteration
adj.lmt = adj.lmt, # Position adjustment limit at which the simulation stops.
iter.max = iter.max) # The maximum number of iterations beyond which simulation will end and a warning will be reported.
# Add coordinates of focus node back in
repelled_coords <- as.data.frame(miscTools::insertRow(as.matrix(repelled_coords), focus, as.numeric(focus_coords))) # Using insertRow rather than rbind to ensure coordinates are added back in the right position.
rownames(repelled_coords) <- 1:nrow(repelled_coords) # Fix row indexing.
return(repelled_coords)
}
Then the dataframe output by the function can be supplied as the layout argument in a ggraph call:
focus_repel <- repelled_focus_layout(graph, focus = 1)
ggraph(graph, layout = focus_repel)
Here's the effect:
The arguments to the force field function can be played around with on a case-by-case basis to get a good result, though the only argument I had to change from its default value was rep.dist.lmt.
This looks promising! but there needs to be a constrained on the radius of nodes. They shouldn't be moved from their concentric circle. Still, this is a good start, thanks for that
Thanks! Yes, as I said this was just a bit of a hack to get it working for me. I just thought I'd leave it here in case it's useful for other people coming across this issue in the meantime until a proper solution is developed.
The rep.dist.lmt can be reduced so that there's only a minimal deviation of nodes from their original starting positions on the circles. I just specified a larger value so that I could better see the edges between nodes on the same circle. This is with rep.dist.lmt = 0.2:
I suppose the spacing between the circles could also be increased so that the nodes can be repelled slightly away from their circles but it's still clear what distance "band" they are in? In fact, maybe concentric bands could be plotted rather than concentric circles to provide a zone for each set of nodes that they can spread out in so you can better see them and their edges, rather than being on a single line.
Hi,
I am trying to plot a Radial Layout with Focal Node with my data that contains ~3000 Nodes. How do I make sure that none of the nodes and edges overlap and are spaced out clearly even if I increase the node size. I was wondering if the radii of the concentric circles could be controlled in order to prevent overlapping of nodes, but I am also looking have non-overlapping edges.
Below id my code and attached is the .RData:
layout<-layout_with_focus(df.g,v = 1383) max(distances(df.g,1383))
ggraph(df.g,layout = "focus",focus = 1383)+ draw_circle(use = "focus", max.circle = max(distances(df.g,1383)))+ geom_edge_link()+ geom_node_point(shape = 21,fill = "grey25",size = 1)+ theme_graph()+ coord_fixed()
graph_rdata.zip