rigraph icon indicating copy to clipboard operation
rigraph copied to clipboard

fix: add warning if layout doesnt match number of vertices

Open schochastics opened this issue 8 months ago • 5 comments

Trying to tackle https://github.com/igraph/rigraph/issues/219. The overarching issue is that if the layout is saved as a graph attribute (g$layout), independent on how it is done, there is no checks implemented if the layout matrix can actually serve as a layout (that is, if it has the correct number of rows). This leads to weird behaviour of the plot function.

This PR could be the starting point for a refactoring. Currently, it only adds a warning if the layout does not match the graph. @szhorvat could this be a good start?

devtools::load_all("~/git/R_packages/rigraph/")
#> ℹ Loading igraph
g <- make_ring(10)
g$layout <- layout_in_circle(g)
plot(induced_subgraph(g,c(1:9)))
#> Warning: The layout has 10 rows, but the graph has 9 vertices. Unintended results may
#> occur.


g <- make_full_graph(10)
g$layout <- layout_in_circle(g)[1:5,]
plot(g)
#> Warning: The layout has 5 rows, but the graph has 10 vertices. Unintended results may
#> occur.


g$layout <- rbind(layout_in_circle(g), cbind(runif(5),runif(5)))
plot(g)
#> Warning: The layout has 15 rows, but the graph has 10 vertices. Unintended results may
#> occur.

Created on 2025-06-24 with reprex v2.1.1

schochastics avatar Jun 24 '25 09:06 schochastics

I think a complete fix is only possible in the C core. We need support for attributes with vector values. I proposed this here for 1.0:

https://github.com/igraph/igraph/issues/2744

But realistically, @ntamas and I just don't have the capacity to get this done for the 1.0 release, which is due in September.

My suggestion is to not put too much effort into this on the R side until it can be fixed in the C core. Perhaps discourage using $layout and suggest $x, $y instead ...

@ntamas Are there any hooks in the attribute handler that would allow updating such attributes upon vertex deletion/addition? I don't think there are any. Note that $layout is a graph attribute, which is the problem here.

szhorvat avatar Jun 24 '25 11:06 szhorvat

Thanks. I will augment the warning to suggest using x and y and that should be good enough for now

schochastics avatar Jun 24 '25 14:06 schochastics

Are there any hooks in the attribute handler that would allow updating such attributes upon vertex deletion/addition?

No, not until we implement some kind of a generic event emitter / listener system that would allow third-party code to hook into anything that happens with a graph.

ntamas avatar Jun 24 '25 17:06 ntamas

An error would be better here. We discussed before that this should be a vertex attribute, AFAIR this isn't something that the C core currently supports.

krlmlr avatar Jun 26 '25 09:06 krlmlr

The R core could support it, though, with https://github.com/igraph/rigraph/pull/1894. What would it take to make the following code produce the right results?

library(igraph, warn.conflicts = FALSE)

g <- make_full_graph(10)
V(g)$layout <- layout_in_circle(g)
plot(g)

Created on 2025-06-26 with reprex v2.1.1

krlmlr avatar Jun 26 '25 09:06 krlmlr

Cant remember all discussions here: Should I turn the warning into an error message and then merge?

schochastics avatar Jul 05 '25 08:07 schochastics

My question in https://github.com/igraph/rigraph/pull/1880#issuecomment-3007834034 is still relevant.

krlmlr avatar Jul 05 '25 09:07 krlmlr

I'll investigate but I think this would be a big change.

  1. Matrix attributes are not supported for vertices and 2) The plot code assumes layout either to be a matrix graph attribute or x and y vertex attributes

schochastics avatar Jul 05 '25 09:07 schochastics

  1. The code shows it’s possible to store them? 2. We own the plotting code?

krlmlr avatar Jul 05 '25 09:07 krlmlr

Specifically, this works with #1894:

library(igraph, warn.conflicts = FALSE)

g <- make_full_graph(10)
V(g)$layout <- layout_in_circle(g)
V(g)$layout
#>            [,1]          [,2]
#>  [1,]  1.000000  0.000000e+00
#>  [2,]  0.809017  5.877853e-01
#>  [3,]  0.309017  9.510565e-01
#>  [4,] -0.309017  9.510565e-01
#>  [5,] -0.809017  5.877853e-01
#>  [6,] -1.000000  1.224647e-16
#>  [7,] -0.809017 -5.877853e-01
#>  [8,] -0.309017 -9.510565e-01
#>  [9,]  0.309017 -9.510565e-01
#> [10,]  0.809017 -5.877853e-01

Created on 2025-07-05 with reprex v2.1.1

krlmlr avatar Jul 05 '25 10:07 krlmlr

Then let's make it happen. I could adapt the plot code to also check for a vertex layout attribute

schochastics avatar Jul 05 '25 11:07 schochastics

There are some issue with this approach. Since vector attributes are not supported in C yet, it will not be possible to export these to the standard formats such as GML.

In the long term it would be good to do this, but I'm wondering if it's a better approach to wait until the C core supports it, or at least wait until upgrading to C/igraph 1.0. I have an issue open for this here: https://github.com/igraph/igraph/issues/2744 Realistically, we probably won't have the capacity to make it happen for 1.0, but I'd like to be optimistic and take another look ...

szhorvat avatar Jul 05 '25 13:07 szhorvat

(To be clear, IMO this is absolutely the right way to do it. My concern is making this an R-specific feature, especially before we had the opportunity to take a good look at it in C and determine what interface is feasible.)

szhorvat avatar Jul 05 '25 13:07 szhorvat

We also need to check subsetting and subset assignment for such attributes. In the other PR.

krlmlr avatar Jul 05 '25 13:07 krlmlr

We could also make V(g)$layout <- … result in setting the x and y vertex attributes. Or perhaps create a layout setting function.

I need to review the attribute code to give a better assessment.

krlmlr avatar Jul 05 '25 13:07 krlmlr

How I envisioned this working was exactly V(g)$layout <- matrix, and internally, in C, such an attribute would be stored precisely as a matrix. Some of the concerns I have, that I think we need to think through, are:

  • Issue with columns-major vs row-major storage in C. @krlmlr, can you confirm that R uses column-major (just like igraph)?
  • How well this fits various file formats?
  • We had some discussions with @ntamas about proposing a new format, but now that the NASCOL forum is dead (CC @vtraag) this'll be harder to push through.

And of course the biggest issue: Implementing this feature with the very limited capacity we have ...

szhorvat avatar Jul 05 '25 13:07 szhorvat

How about going with @krlmlr's design, and setting the layout fixed-length vector attribute, just as you proposed, but also providing a feature (i.e. a conveniene function) to convert between the layout and x/y formats? This would make it easy for people to convert to a format that is easily exportable with the current features.

szhorvat avatar Jul 05 '25 14:07 szhorvat

Would this be a separate PR? I feel like the scope of this PR is only to provide a warning/error for layouts as graph attributes. A separate PR would be to allow layout as node attribute + conversion? Happy to put this all into this PR though if that is fine

schochastics avatar Jul 07 '25 10:07 schochastics

Let's turn this into an error then, and address the other topics later.

krlmlr avatar Jul 07 '25 11:07 krlmlr

@krlmlr ok to merge if everything passes?

schochastics avatar Jul 07 '25 12:07 schochastics

Thanks, merging.

krlmlr avatar Jul 07 '25 12:07 krlmlr