1

I am trying to plot scatter data on top of a box plot using Plotly. For this case I need to specify the quantiles manually. When I run the reprex below I get this error

Error in eval(expr, data, expr_env) : object 'lower_fence' not found

I would like the scatter data to have the same colour scheme as the box plot but the problem happens whether or not I add the colouring scheme. Essentially I am just trying to add in the outlier points that you get in a normal box plot where the quantiles are computed by plotly.

Any ideas how I can do this?

library(plotly)

# create presomputed quantiles
stats_df <- data.frame(
  site = c("site 2", "site 1", "site 3", "site 4"),
  site_type = c("b_type", "b_type", "a_type", "c_type"),
  lower_fence = c(1, 1.5, 2,  2.5),
  q1 = c(2, 3, 4, 5),
  median = c(6, 6.5, 7, 7.5),
  q3 = c(7, 8, 9, 10),
  upper_fence = c(11, 12, 13, 14)
)

# create box plot
fig <- plot_ly(
  data = stats_df,
  x = ~factor(site),
  color = ~ factor(site_type),
  colors = c("purple", "yellow", "red"),
  type="box",
  lowerfence = ~ lower_fence,
  q1 = ~ q1,
  median = ~ median,
  q3 = ~ q3,
  upperfence = ~ upper_fence)


# create scatter data
filtered_df_sub <- stats_df <- data.frame(
  site = c("site 2", "site 1", "site 3", "site 4"),
  site_type = c("b_type", "b_type", "a_type", "c_type"),
  value = c(1,2,3,4)
)

# add scatter points
fig <- fig %>% 
  add_trace(
    data = filtered_df_sub,
    x = ~factor(site),  # Use the same x variable for consistency
    y = ~value,  # Original values for scatter points
    color = ~ factor(site_type),
    colors = c("purple", "yellow", "red"),
    type = "scatter",
    mode = "markers",
    showlegend = FALSE  # Hide legend for scatter points if desired
  )

# add axis labels
fig <- fig %>%
        layout(title = "Box Plot with Precomputed Statistics",
               yaxis = list(title = "Value"),
               xaxis = list(title = "Sites"))

fig

2 Answers 2

1

This is not a bug - it is expected behaviour.

You can simply set inherit = FALSE for your add_trace call. This prevents plotly from inheriting attributes from the initial plot_ly() call. E.g. lowerfence = ~ lower_fence which is not part of the data you are providing to add_trace.

library(plotly)

# create presomputed quantiles
stats_df <- data.frame(
  site = c("site 2", "site 1", "site 3", "site 4"),
  site_type = c("b_type", "b_type", "a_type", "c_type"),
  lower_fence = c(1, 1.5, 2,  2.5),
  q1 = c(2, 3, 4, 5),
  median = c(6, 6.5, 7, 7.5),
  q3 = c(7, 8, 9, 10),
  upper_fence = c(11, 12, 13, 14)
)

# create box plot
fig <- plot_ly(
  data = stats_df,
  x = ~factor(site),
  color = ~ factor(site_type),
  colors = c("purple", "yellow", "red"),
  type="box",
  lowerfence = ~ lower_fence,
  q1 = ~ q1,
  median = ~ median,
  q3 = ~ q3,
  upperfence = ~ upper_fence)


# create scatter data
filtered_df_sub <- stats_df <- data.frame(
  site = c("site 2", "site 1", "site 3", "site 4"),
  site_type = c("b_type", "b_type", "a_type", "c_type"),
  value = c(1,2,3,4)
)

# add scatter points
fig <- fig %>% 
  add_trace(
    data = filtered_df_sub,
    x = ~factor(site),  # Use the same x variable for consistency
    y = ~value,  # Original values for scatter points
    color = ~ factor(site_type),
    colors = c("purple", "yellow", "red"),
    type = "scatter",
    mode = "markers",
    showlegend = FALSE,  # Hide legend for scatter points if desired
    inherit = FALSE
  )

# add axis labels
fig <- fig %>%
  layout(title = "Box Plot with Precomputed Statistics",
         yaxis = list(title = "Value"),
         xaxis = list(title = "Sites"))

fig
Sign up to request clarification or add additional context in comments.

Comments

0

The plot will work if you pass the box plot values directly to the arguments rather than using the column names. That is, set lowerfence = stats_df$Lower_fence, etc. See the example of Box Plot with Precomputed Quartiles at the Plotly website The code below does throw a warning about a scatter object not having attributes such as lowerfence, etc.

library(plotly)

# create presomputed quantiles
stats_df <- data.frame(
  site = c("site 2", "site 1", "site 3", "site 4"),
  site_type = c("b_type", "b_type", "a_type", "c_type"),
  lower_fence = c(1, 1.5, 2,  2.5),
  q1 = c(2, 3, 4, 5),
  median = c(6, 6.5, 7, 7.5),
  q3 = c(7, 8, 9, 10),
  upper_fence = c(11, 12, 13, 14)
)

# create box plot
fig <- plot_ly(
  #data = stats_df,
  x = factor(stats_df$site),
  color = factor(stats_df$site_type),
  colors = c("purple", "yellow", "red"),
  type="box",
  lowerfence = stats_df$lower_fence,
  q1 = stats_df$q1,
  median = stats_df$median,
  q3 = stats_df$q3,
  upperfence = stats_df$upper_fence)


# create scatter data
filtered_df_sub <-  data.frame(
  site = c("site 2", "site 1", "site 3", "site 4"),
  site_type = c("b_type", "b_type", "a_type", "c_type"),
  value = c(1,2,3,4)
)

# add scatter points
fig <- fig %>% 
  add_trace(
    data = filtered_df_sub,
    x = ~factor(site),  # Use the same x variable for consistency
    y = ~value,  # Original values for scatter points
    color = ~ factor(site_type),
    colors = c("purple", "yellow", "red"),
    type = "scatter",
    mode = "markers",
    showlegend = FALSE  # Hide legend for scatter points if desired
  )

# add axis labels
fig <- fig %>%
  layout(title = "Box Plot with Precomputed Statistics",
         yaxis = list(title = "Value"),
         xaxis = list(title = "Sites"))

fig

2 Comments

Great, thanks @FJCC, that works But yes you're right, it does throw up a (quite verbose) warning. Is that just a bug in plotly? I have a few places in my code (shiny app) where I get plotly warnings e.g. this one. for seemingly no valid reason. Does this just come with the territory of plotly as far as you're aware?
Sorry, I don't know how to fix the warnings. I found similar questions unanswered on a plotly forum and this open issue on GitHub: github.com/plotly/plotly.R/issues/994

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.