Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Half manual layout #75

Closed
schochastics opened this issue Jan 15, 2024 · 7 comments
Closed

Half manual layout #75

schochastics opened this issue Jan 15, 2024 · 7 comments

Comments

@schochastics
Copy link
Owner

see thomasp85/ggraph#139

@schochastics
Copy link
Owner Author

@llrs it is implemented now as layout_with_fixed_coords().
Could you check if it works for your purpose and if the API is clear?

@llrs
Copy link

llrs commented Jan 17, 2024

The current API requires to set a matrix for all the nodes, would it be possible to specify only some nodes?
The idea behind it was to fix in space some nodes so that the visualization could be clear for them and the other nodes could organize around those selected.

Sorry, I didn't dedicate much time to check this package, the original question was from ~4 years ago, but how would one use it with {tidygraph}? I wanted to see the effect on plotting but I am not sure how to compare that:

library(igraph)
library(ggraph)
library(graphlayouts)
set.seed(12)
g <- sample_bipartite(10, 5, "gnp", 0.5)
fxy <- cbind(c(rep(0, 10), rep(1, 5)), NA)
xy <- layout_with_fixed_coords(g, fxy)

ggraph(g, layout = "stress") + geom_node_point() + theme_graph() + geom_edge_link0()
ggraph(g, layout = xy) + geom_node_point() + theme_graph() + geom_edge_link0()
## Error in base::nchar(wide_chars$test, type = "width") : 
##   promise already under evaluation: recursive default argument reference or earlier problems?
## In addition: Warning message:
## In base::nchar(wide_chars$test, type = "width") :
##   internal error -3 in R_decompress1

@schochastics
Copy link
Owner Author

schochastics commented Jan 17, 2024

Apologies, I should have given you a better example.

library(igraph)
library(ggraph)
library(graphlayouts)
set.seed(12)
g <- sample_bipartite(10, 5, "gnp", 0.5)
fxy <- cbind(c(rep(0, 10), rep(1, 5)), NA)
xy <- layout_with_fixed_coords(g, fxy)

ggraph(g, layout = "manual",x=xy[,1],y=xy[,2])  + geom_edge_link0() + geom_node_point() + theme_graph()

the algorithm only calculates the layout for the NAs in the matrix. the rest is kept fixed and the algorithm takes the fixed positions into account and optimizes the NA positions in accordance to them.

@llrs
Copy link

llrs commented Jan 17, 2024

Thanks for providing an example. I tried with a couple of variations of it and it seems to work well.
In terms of API, reading the documentation I see it only implements the stress layout.
Is it possible to select other layouts like "focus" or "centrality"?

Probably this is out of scope of this package but how should I know which position should I leave as NA? If it is easy then this approach might be useful if it is not, a helper might be needed to work with real examples with named nodes and attributes.

@schochastics
Copy link
Owner Author

schochastics commented Jan 17, 2024

This will only ever work with the stress layout. Everything else is too complex or not possible.

In terms of API. The expectation is that if people use the algorithm they know which nodes they want to fix where. So if you know that node 5 should be on (0,0), you put coords[5,]=c(0,0). Does that make sense?

@llrs
Copy link

llrs commented Jan 18, 2024

Yes and no. My expectations is that all the nodes that have value above 5 and in category Z to be in the center of the circle: all the others should be around them as best seen fit for the layout chosen. With tidygraph you can have other values besides the nodes and edges in the graph, I wish to be able to use them to make it easier to select which to keep fixed/manual or not.

With the current API, AFAIK, I should first create a matrix that has the same number of rows than the graph, make sure that it matches other properties each node have and then only those that match some conditions remove it, while keeping this in sync in case there are other changes.
Regardless of any further changes, this is already a great improvement. Thanks!

@schochastics
Copy link
Owner Author

Thanks for the detailed answer. I think for now I will leave the API as is and think about ways to improve in the future.
A suggestion for what you talked about (if I understand correctly):

# g is a graph object with a node attribute type

xy <- matrix(NA,vcount(g),2)
xy[V(g)$type == "Z",] <- c(0,0)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants