plotly.R icon indicating copy to clipboard operation
plotly.R copied to clipboard

plotly::subplot with >= 3 rows/cols results in different sized plots for inner/boundary plots

Open avsdev-cw opened this issue 4 years ago • 2 comments

As per title, when making a subplot with >= 3 rows or columns with a margin (default is 0.02 but the issue is easier to see with more plots/bigger margins)

library(magrittr)
p <- plotly::plot_ly(mtcars, x = ~cyl, y = ~mpg, color = ~rownames(.data), type = "bar") %>% plotly::layout(showlegend = FALSE)
plotly::subplot(p, p, p, p, p, p, p, p, p, nrows = 3, margin = 0.1)

image

There is a PR (#622) which aims to fix it, but the PR also does some extra things like make the margins fixed rather than scaled. I think it's possible to provide a much quicker & simpler fix as an alternative, given that this has been known about since 2016.

I think in a nutshell its due to the function get_domains & it's for loops: https://github.com/plotly/plotly.R/blob/4bb1e44c5e27898bdf7ac45422564fa5200fb5f5/R/subplots.R#L385-L401 It's those if's that are the problem, can they be removed without causing too much trouble?

avsdev-cw avatar Oct 27 '21 13:10 avsdev-cw

@avsdev-cw Trying to look into this - you are right, this is not working great. I do no think that removing the if statements is a good idea, as the margins should be respected, but instead the margins need to contribute properly to all the subplots so that they are laid out evenly while honoring the margin constraints from the user.

I can make it even worse with this code:

library(magrittr)
p <- plotly::plot_ly(mtcars, x = ~cyl, y = ~mpg, color = ~rownames(.data), type = "bar") %>% plotly::layout(showlegend = FALSE)
plotly::subplot(p, p, p, p, p, p, p, p, p, nrows = 3, margin = c(0.1, 0.2, 0.1, 0.2))

What I would expect instead is "collapsing" of margins similar to how HTML does it, so that the margins between plots would be 0.2, the margin on the left 0.1 and the very right one 0.2. And I would expect the plots to have identical sizes.

That said, if margins collapse but left and right side lays flat against the edge of the picture, then it makes zero sense to specify separate left and right margin, because the gaps between the plots would be max(left, right) and nothing special happens on the very left or the very right... that does not sound right to me either. It is also unclear whether width of the plot should correspond to the entire area including margin, or just to the "plotted on" area without margins (I believe we are talking about distinction between margin and padding as in HTML). I can see many ways of solving this, I think we need to look at how other packages do this and adjust so that the function is useable and covers scenarios people care about the most in an easy-to-use way.

romanzenka avatar Feb 21 '25 23:02 romanzenka

@romanzenka Thanks for the reply. It's been quite a long time so I can't actually remember if I adhered to the truthful or falseful side of the inline "if" statements. It may be worth replicating the tests with either side to see which one works best.

avsdev-cw avatar Feb 24 '25 09:02 avsdev-cw