CrustyNoodle
CrustyNoodle

Reputation: 389

R Plotly inconsistent subplot size

I'm trying to plot an array of box plots however subplot produces plots of different sizes. I really need all the plots to be the same size.

Here is some example code which I'll explain a bit below:

library(plotly)

df1 <- data.frame(label = sample(c("a", "b", "c","d", "e", "f"), 1000, replace = TRUE),
                 value = rnorm(1000,1))

df2 <- data.frame(label = sample(c("a", "b", "c", "d", "e", "f"), 1000, replace = TRUE),
                  value = rnorm(1000,2))


create_plot <- function(showlegend = F) {
  plot_ly( type = "box",
           showlegend = showlegend
           ) %>%
  add_trace(data = df1,
            x = ~label,
            y = ~value,
            offsetgroup = 0,
            legendgroup = 0,
            name = "Type 1") %>%
  add_trace(data = df2,
            x = ~label,
            y = ~value,
            offsetgroup = 1,
            legendgroup = 1,
            name = "Type 2") %>%
  layout(plot,
         boxmode = "group",
         annotations = list(
           x = 0.5,
           y = 1.05,
           text = "Plot Title",
           xref = "paper",
           yref = "paper",
           xanchor = "center",  # center of text
           yanchor = "center",  # center of text
          showarrow = FALSE
         )
  )
}

fig1 <- create_plot(showlegend = T)
fig2 <- create_plot()
    
#subplot(fig, fig1, fig1, fig1, fig1,
subplot(fig1, fig2, fig2, fig2, fig2, fig2, fig2, fig2,
        nrows = 4,
        # heights = c(0.2, 0.3, 0.3, 0.2),
        margin = c(0.07, 0.0, 0.05, 0.1) # c(left, right, top, bottom )
        ) %>%
  layout(
    bargroupgap = 0.01,
    plot_bgcolor='#e5ecf6'
    
  )

Code explanation:

This code produces the following output for me:

The subplot

As you can see the middle two rows of plots have the lowest height and the last row plots are larger than any of the other rows. You will also see that the plot titles end up in different locations depending on the row. When plotted individually, the plot turns out perfectly.

I have tried all sorts of settings in subplot like the margin settings and height settings but they all seem to be very plot size and number specific where as I would like my subplot to be more independent of the size and shape of the rendered output.

Any thoughts?

Upvotes: 3

Views: 1604

Answers (1)

Bev Dodds
Bev Dodds

Reputation: 51

I'm having exactly the same issue with the margins, not the titles (see modified code which fixes them, by setting yanchor = "bottom").

I too have played around with the margins (not so much the heights) and find that the top and bottom row of plots look taller than the centre rows (I have 5 in my code). Is it because the margins are added together for the 'middle' rows and so the plots have less space to occupy?

I've tried balancing the margins in your code but it doesn't fix the problem.

Leaving the margins as the default doesn't work well because the titles then seem to be too close to the plot above. I'm having to settle for the 'least worst' display option, which isn't great.

library(plotly)

df1 <- data.frame(label = sample(c("a", "b", "c","d", "e", "f"), 1000, replace = TRUE),
                  value = rnorm(1000,1))

df2 <- data.frame(label = sample(c("a", "b", "c", "d", "e", "f"), 1000, replace = TRUE),
                  value = rnorm(1000,2))    

create_plot <- function(showlegend = F) {
  plot_ly( type = "box",
           showlegend = showlegend
  ) %>%
    add_trace(data = df1,
              x = ~label,
              y = ~value,
              offsetgroup = 0,
              legendgroup = 0,
              name = "Type 1") %>%
    add_trace(data = df2,
              x = ~label,
              y = ~value,
              offsetgroup = 1,
              legendgroup = 1,
              name = "Type 2") %>% 
    layout(boxmode = "group",
           bargroupgap = 0.01,
           plot_bgcolor='#e5ecf6',
           annotations = list(
             x = 0.5,
             y = 1.05,
             text = "Plot Title",
             xref = "paper",
             yref = "paper",
             xanchor = "center",  # center of text
             yanchor = "bottom",  # bottom of text
             showarrow = FALSE
           )
    )
}    

fig1 <- create_plot(showlegend = T)
fig2 <- create_plot()

#subplot(fig, fig1, fig1, fig1, fig1,
subplot(fig1, fig2, fig2, fig2, fig2, fig2, fig2, fig2,
        nrows = 4,
        # heights = c(0.2, 0.3, 0.3, 0.2),
        margin = c(0.07, 0.0, 0.05, 0.01) # c(left, right, top, bottom ) least worst option?
) 

Upvotes: 5

Related Questions