2

Here is a toy example I have got stuck on

library(plotly)
library(dplyr)

# construct data.frame
df <- tibble(x=c(3,2,3,5,5,5,2),y=c("a","a","a","b","b","b","b"))

# construct data.frame of last y values
  latest <- df %>% 
   group_by(y) %>% 
   slice(n())

# plot for one value of y (NB not sure why value for 3 appears?)
  p <- plot_ly() %>% 
   add_histogram(data=subset(df,y=="b"),x= ~x) %>%   
  add_histogram(data=subset(latest,y=="b"),x= ~x,marker=list(color="red")) %>%
  layout(barmode="overlay",showlegend=FALSE,title= ~y)
  p

enter image description here

How can i set these up as subplots, one for each unique value of y? In the real world example, I would have 20 different y's so would ideally loop or apply the code. In addition, it would be good to set standard x scales of say c(1:10) and have, for example, 2 rows

TIA

2
  • 1
    add_histogram()?? Commented Aug 31, 2016 at 22:15
  • Sorry this may only in development version 4 and up - though add-trace still functions . You will , however, also need x= ~x for the plot to work if you 'upgrade' Commented Sep 1, 2016 at 23:36

1 Answer 1

2
+100
  1. build a list containing each of the plots
  2. set the bin sizes manually for the histograms, otherwise the automatic selection will choose different bins for each of the traces within a plot (making it look strange as in you example where the bars of each trace are different widths)
  3. use subplot to put it all together
  4. add titles to individual subplots using a list of annotations, as explained here

Like this:

N = nlevels(factor(df$y))
plot_list = vector("list", N)
lab_list = vector("list", N)

for (i in 1:N) {
  this_y = levels(factor(df$y))[i]
  p <- plot_ly() %>% 
    add_trace(type="histogram", data=subset(df,y==this_y), x=x, marker=list(color="blue"),
              autobinx=F, xbins=list(start=0.5, end=6.5, size=1)) %>%   
    add_trace(type="histogram", data=subset(latest,y==this_y), x = x, marker=list(color="red"), 
              autobinx=F, xbins=list(start=0.5, end=6.5, size=1)) %>%
    layout(barmode="overlay", showlegend=FALSE)
  plot_list[[i]] = p

  titlex = 0.5
  titley = c(1.05, 0.45)[i]
  lab_list[[i]] = list(x=titlex, y=titley, text=this_y, 
                       showarrow=F, xref='paper', yref='paper', font=list(size=18))
}

subplot(plot_list, nrows = 2) %>%
  layout(annotations = lab_list)

enter image description here

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

6 Comments

Thanks. I am getting close to what I need now. The issue is labeling each individual plot. With title=this_y, only the last value i.e. b gets shown at top(I think it is truncated out in your image). There is not a title shown for each subplot If i add shareX=TRUE to the subplot function I get the correct this_y showing up along the x axis BUT only for the botttom row. In the toy example it would just show b (nothing on the top subplot) . In my real life example, with 4 columns all of the bottom row have the correct this_y showing
thanks. I get the general gist but am happy to wait on your answer in a few days time
I've added in the titles using annotations
Thanks will check it later. Sorry had not realized i had to click bounty button . Well merited
I tried this solution, and I am getting :Error in add_trace(., type = "histogram", data = subset(df, y == this_y), : object 'x' not found > > subplot(plot_list, nrows = 2) %>% + layout(annotations = lab_list) Error in names(object) <- nm : attempt to set an attribute on NULL
|

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.