How do I stop igraph from normalizing my layout to a (-1,-1) to (1,1) bounding box?

I can’t figure out how to stop igraph (in R) from normalizing the layout of my graph, even if I specify the layout as a matrix or the vertices have x, y attributes. Here’s example code

n <- 11
# make an elliptical arrangement of x,y coordinates
a <- seq(0, 2 * pi, length.out = n + 1)[-1]
x <- 5 * cos(a)
y <- 3 * sin(a)
L <- matrix(c(x, y), ncol = 2)

G <- make_full_graph(n) |> 
  set_vertex_attr("x", value = x) |>
  set_vertex_attr("y", value = y)

plot(G, layout = L)

I would hope that the graph drawing would be elliptical with aspect ratio 5:3 but it remains stubbornly circular.

The same thing happens if I specify no layout or use layout_nicely which the help says will apply vertex x and y attributes if they exist. I don’t know if it is applying the coordinates or not, but it appears to be normalizing them, and I can see this if I do plot(G, layout = L, axes = T) when it shows that my graph has been drawn not at the specified coordinates, but to fit inside a (-1, -1) to (1, 1) bounding box.

Same thing happens if I do ... layout = runif(2*n, -100, 100) |> matrix(ncol = 2) when I get a drawing in the (-1, -1) to (1, 1) bounding box. I get randomly located vertices, but they’re scaled to the bounding box again.

How can I stop this behaviour? (My use case is where x, y coordinates might be geographic and I’d like to be able to draw the graph as either a map or as a graph drawing).

I’m not really an R user, and I’m not experienced with plotting in R, so all I can say is that based on looking at the sources, passing rescale = FALSE to plot prevents this rescaling (but doesn’t adapt the plot range).

Perhaps someone else can help more.

1 Like

This helps, although… it seems that the plot continues to impose (-1, 1) (-1, 1) limits on the x and y axes. So if my vertices lie outside this window then they don’t show up in the plot at all!

par(mfrow = c(1, 2))
plot(G, rescale = FALSE, axes = TRUE, asp = 1)
plot(G, xlim = range(V(G)$x), ylim = range(V(G)$y), 
     rescale = FALSE, axes = TRUE, asp = 1)

gives me

The plot on the left still has the (-1 1) axis limits, I assume because of this line in the code, where xlim = c(-1, 1), ylim = c(-1, 1) is enforced. My xlim = range(V(G)$x), ylim = range(V(G)$y) overrides that, and I get what I was initially hoping for (the plot on the right).

Seems like I should probably report this as a bug/issue, unless there is another parameter that can set the limits based on vertex x and y attributes as is stated in documentation

Have posted as an issue in the repo: plot rescales and normalizes graph even if it has vertex x and y attributes · Issue #1492 · igraph/rigraph · GitHub