Plotly with loop or purr

I have a data frame which plots as per below code. But I need this to be reacive/dynamic (basically a loop kind). For example, now we have only 2019, 2020 so that is fine. In case if we have 2017, 2018, 2019, 2020, 2021 and so on. It should take automatically and also there is _cap values(2019_cap) here. If it is _cap values, then mode should be lines+markers or else lines . Can we achieve this

asd <- data.frame(week = c(1,1,2,2), year = c("2019","2020","2019","2020"), val = c(1,2,3,4), cap = c(3,4,6,7))
asd_plot <- tidyr::pivot_wider(asd, names_from = year, values_from = c(val, cap), names_glue = "{year}_{.value}")
asd_plot <- as.data.frame(asd_plot)
fig <- plot_ly(asd_plot , x = ~week, y = ~`2019_val`, type = 'scatter', mode = 'lines', name = '2019') %>%
  add_trace(asd_plot , x = ~week, y = ~`2020_val`, type = 'scatter',  mode = 'lines', name = '2020') %>%
  add_trace(asd_plot , x = ~week, y = ~`2019_cap`, type = 'scatter',  mode = 'lines+markers', name = '2021') %>% 
  add_trace(asd_plot , x = ~week, y = ~`2020_cap`, type = 'scatter',  mode = 'lines+markers', name = '2021')
fig

Hi there,

I am going to have to spend some more time to see how your data works because it is not in an ideal shape to work from. Just to show you that you can setup a loop for plotly you will need to setup the initial plot object plot_ly outside the loop and from there you can add all the add_trace you want. I just added a random sample to show how you would setup a condition for a different line type.

library(plotly)
library(dplyr)

mean <- -0.0007200342
sd   <- 0.3403711
N=10
T=1
Delta = T/N

W = c(0,cumsum( sqrt(Delta) * rnorm(N, mean=mean, sd=sd)))
t <- seq(0,T, length=N+1)



p<-plot_ly(y=W, x=t)

for(i in 1:5){
  
  
  
  W <- c(0,cumsum( sqrt(Delta) * rnorm(N, mean=mean, sd=sd)))
  
  
  if(sample(c(0:1),1, TRUE) == 1){
    p <- add_trace(p, y=W, type = 'scatter', mode = 'lines')
    
  } else {
    p <- add_trace(p, y=W, type = 'scatter', mode = 'lines+markers')  
    
  }
  

  
}

p

Created on 2021-10-29 by the reprex package (v2.0.0)

Hello,

See below how I would approach this. First of all you need the dataframe in a more tidy format. Have a look at how I created df. You can build something similar for yours. Just note that if you have more than 2 values associated with a year and the same line type you will get zig zag lines so pair of points need to be unique.

In terms of the plot you will see that we figure out a distinct_count so we know how many years there are. We also use that as a filter for the dataframe so we only get portions of the data to plot . From that point we df_temp to determine if needs to be lines+markers or lines based on if it is a Cap or Val.

Finally, after adding all of them we plot the plot. I hope this works for you.

library(plotly)
library(dplyr)


df <- 
data.frame(
  stringsAsFactors = FALSE,
              year = c(2021, 2021, 2019, 2019, 2021, 2021, 2020, 2020),
                 x = c(1, 2, 1, 2, 1, 2, 1, 2),
                 y = c(3, 6, 1, 3, 4, 7, 2, 4),
         line_type = c("Cap", "Cap", "Val", "Val", "Val", "Val", "Val", "Val")
)

df
#>   year x y line_type
#> 1 2021 1 3       Cap
#> 2 2021 2 6       Cap
#> 3 2019 1 1       Val
#> 4 2019 2 3       Val
#> 5 2021 1 4       Val
#> 6 2021 2 7       Val
#> 7 2020 1 2       Val
#> 8 2020 2 4       Val


distinct_count <- df %>% select(year) %>% distinct() %>% unlist()


p<-plot_ly()


for(i in 1:length(distinct_count)){
  
 
  df_temp <- df %>% filter(year == distinct_count[i])
  
  if("Cap" %in% df_temp$line_type){
    df_temp_cap <- df_temp %>% filter(line_type == "Cap")
    p <- add_trace(p, x = df_temp_cap$x, y= df_temp_cap$y, type = 'scatter', mode = 'lines+markers', name = paste0(df_temp_cap$year[1]))
  }
  
  
  if("Val" %in% df_temp$line_type){
    df_temp_val <- df_temp %>% filter(line_type == "Val")
    p <- add_trace(p, x = df_temp_val$x, y= df_temp_val$y, type = 'scatter', mode = 'lines', name = paste0(df_temp_val$year[1]))
  }
  
  
}

p

Created on 2021-10-29 by the reprex package (v2.0.0)

2 Likes

@vinayprakash808 , do let me know if this solved your problem :slight_smile:

Great thanks a lot the help

Great :slight_smile: Just mark it as the solution

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.