R Plotly Add Trace within Loop - r
I have an issue with using loops to add trace in plotly, though I have no idea what the cause is.
If I try to make a plot using the method for P below, only the data for last column (HORSE) is shown. Rabbit and Dog still show up, but both display values for Horse.
If, however, I use the P1 method the graph works perfectly. I would really like to be able to do this within a loop as the length of columns varies.
df <- data.frame(AGE = c(0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5),
YEAR = c(2010,2011,2012,2013,2014,2015,2016,2017,2010,2011,2012,2013,2014,2015,2016,2017,2010,2011,2012,2013,2014,2015,2016,2017,2010,2011,2012,2013,2014,2015,2016,2017,2010,2011,2012,2013,2014,2015,2016,2017,2010,2011,2012,2013,2014,2015,2016,2017),
RABBIT = c(0,5,2,6,8,5,8,4,3,6,2,7,5,5,9,9,1,4,4,6,5,3,7,7,6,8,2,6,9,1,9,1,1,2,10,1,10,10,4,2,4,8,7,0,3,4,5,7),
DOG = c(2,5,0,8,2,5,9,5,10,5,10,3,8,9,2,7,5,1,1,4,6,7,7,0,6,5,7,2,2,9,4,2,6,0,7,1,7,6,9,9,9,5,5,9,0,9,10,2),
HORSE = c(7,1,9,10,6,6,5,1,4,5,0,3,0,3,2,4,3,6,1,9,6,4,3,1,7,8,4,1,8,6,5,9,2,0,5,5,6,1,1,7,4,9,5,0,8,1,5,7)
)
L <- c("RABBIT","DOG","HORSE")
P <- plot_ly(data = df)
for(i in 1:length(L)){
P<-add_trace(P, y=~df[[L[i]]], x=~df$AGE, frame =~df$YEAR, type="scatter", mode="lines", name = L[i])
}
P1 <- plot_ly(data = df)
P1 <- add_trace(P1, y=~df[[L[1]]], x=~df$AGE, frame =~df$YEAR, type="scatter", mode="lines", name = L[1])
P1 <- add_trace(P1, y=~df[[L[2]]], x=~df$AGE, frame =~df$YEAR, type="scatter", mode="lines", name = L[2])
P1 <- add_trace(P1, y=~df[[L[3]]], x=~df$AGE, frame =~df$YEAR, type="scatter", mode="lines", name = L[3])
P
P1
You can use this solution:
P <- plot_ly(data = df)
for(k in 1:length(L)) {
dfk <- data.frame(y=df[[L[k]]], AGE=df$AGE, YEAR=df$YEAR)
P <- add_trace(P, y=~y, x=~AGE, frame =~YEAR, data=dfk,
type="scatter", mode="lines", name = L[k])
}
Related
Plotly: How to set background color per data
I want to set two different colors as the plot background: one color per data like this Here are my plots so far:
The following suggestion is a minimal reproducible example to show you that it can be done. Albeit not so easily and elegantly as you may have hoped. To my knowledge, there does not yet exist a way to alternate backround colors without doing so through shapes. The following setup at least captures some of the features of your demonstrated setup, in that it is a mix of a line and a bar chart, and that it produces multiple subplots in one go. Plot: Code: library(dplyr) library(plotly) df = data.frame(x=c(1,2,3,4,5,6,7,8,9,10,11,12), y1=c(4,2,4,2,6,7,8,7,9,10,9,12), y2=c(3,4,5,6,3,1,5,6,3,2,7,8)) list(df$x) x_start <- df$x[seq(1, length(df$x), 2)] x_stops <- df$x[seq(2, length(df$x), 2)] p1 <- plot_ly(x=df$x, y=df$y1, mode='lines', line=list(color='green'), name = 'line') p2 <- plot_ly(df) %>% add_bars(x=~x, y=~y2, name='bar', width=0.4) # set up shapes shape=list(type='rect', line = list(color = 'rgba(0,0,0,0)'), fillcolor="rgba(147,112,219,0.1)", xref='x', yref='y') shape_offset = 0.5 shapes <- list() for (i in seq_along(x_start)){ print(i) shape[["x0"]] <- x_start[i] + shape_offset shape[["x1"]] <- x_stops[i] + shape_offset shape[["y0"]] <- 0 shape[["y1"]] <- 16 shapes <- c(shapes, list(shape)) } p1 <- layout(p1, shapes=shapes, xaxis = list(showgrid=FALSE)) p2 <- layout(p2, shapes=shapes) p <- subplot(p1, p2, nrows = 2, margin=0.05) p I hope this will be useful to you. If you'd like we can discuss further details when you've had a chance to look at it. Edit 1: Here's a suggestion that takes the max of y into consideration when the background shapes are built. This can be made flexible with regards to the number of subplots if you're interested. Plot 2: Code 2: library(dplyr) library(plotly) df = data.frame(x=c(1,2,3,4,5,6,7,8,9,10,11,12), y1=c(4,2,4,2,6,7,8,7,9,10,9,12), y2=c(3,4,5,6,3,1,5,6,3,2,7,8)) list(df$x) x_start <- df$x[seq(1, length(df$x), 2)] x_stops <- df$x[seq(2, length(df$x), 2)] p1 <- plot_ly(x=df$x, y=df$y1, mode='lines', line=list(color='green'), name = 'line') p2 <- plot_ly(df) %>% add_bars(x=~x, y=~y2, name='bar', width=0.4) # set up plot 1 shapes shape=list(type='rect', line = list(color = 'rgba(0,0,0,0)'), fillcolor="rgba(147,112,219,0.1)", xref='x', yref='y') shape_offset = 0.5 shapes <- list() for (i in seq_along(x_start)){ print(i) shape[["x0"]] <- x_start[i] + shape_offset shape[["x1"]] <- x_stops[i] + shape_offset shape[["y0"]] <- 0 shape[["y1"]] <- max(df$y1) shapes <- c(shapes, list(shape)) #print() } # set up plot 2 shapes shape2=list(type='rect', line = list(color = 'rgba(0,0,0,0)'), fillcolor="rgba(147,112,219,0.1)", xref='x', yref='y') shape2_offset = 0.5 shapes2 <- list() for (i in seq_along(x_start)){ print(i) shape2[["x0"]] <- x_start[i] + shape2_offset shape2[["x1"]] <- x_stops[i] + shape2_offset shape2[["y0"]] <- 0 shape2[["y1"]] <- max(df$y2) shapes2 <- c(shapes2, list(shape2)) #print() } p1 <- layout(p1, shapes=shapes, xaxis = list(showgrid=FALSE)) p2 <- layout(p2, shapes=shapes2) p <- subplot(p1, p2, nrows = 2, margin=0.05) p
How to make many plotly charts each one in its own Viewer window?
I'm making some visualization using R Studio. I have a list of dataframes: tickers_df <- read.csv('tickers.csv') v_df <- split(tickers_df, tickers_df$pair_code) Now I want to make a plot for each dataframe within v_df in its own Viewer window. I'm doing: for (pair_df in v_df) { col_name <- names(pair_df)[4:9] colors <- c('green', 'darkgreen', 'red', 'darkred', 'blue', 'darkblue') df_layout <- data.frame(col_name, colors) p <- plot_ly() for (i in 1:nrow(df_layout)) { col_name <- as.character(df_layout[i, 1]) p <- add_trace( p, x = pair_df$step, y = pair_df[, col_name], name = col_name, type = 'scatter', mode = "lines", line = list(color = df_layout[i, 2], width = 1) ) p <- layout(p, title = pair_df$pair_code[[1]]) } p } But this code doesn't work as expected - it shows no charts at all. How can I draw many plotly charts within a loop? And btw what is the meaning of last line with only p variable? Like in this example: p <- plot_ly( x = df$time.1, y = df$total_profit, line = list(color = 'darkred')) p #what is this standing for?
R Plotly - Plotting Multiple Regression Lines
How do I add multiple regression lines to the same plot in plotly? I want to graph the scatter plot, as well as a regression line for each CATEGORY The scatter plot plots fine, however the graph lines are not graphed correctly (as compared to excel outputs, see below) df <- as.data.frame(1:19) df$CATEGORY <- c("C","C","A","A","A","B","B","A","B","B","A","C","B","B","A","B","C","B","B") df$x <- c(126,40,12,42,17,150,54,35,21,71,52,115,52,40,22,73,98,35,196) df$y <- c(92,62,4,23,60,60,49,41,50,76,52,24,9,78,71,25,21,22,25) df[,1] <- NULL fv <- df %>% filter(!is.na(x)) %>% lm(x ~ y + y*CATEGORY,.) %>% fitted.values() p <- plot_ly(data = df, x = ~x, y = ~y, color = ~CATEGORY, type = "scatter", mode = "markers" ) %>% add_trace(x = ~y, y = ~fv, mode = "lines") p Apologies for not adding in all the information beforehand, and thanks for adding the suggestion of "y*CATEGORY" to fix the parallel line issue. Excel Output https://i.imgur.com/2QMacSC.png R Output https://i.imgur.com/LNypvDn.png
Try this: library(plotly) df <- as.data.frame(1:19) df$CATEGORY <- c("C","C","A","A","A","B","B","A","B","B","A","C","B","B","A","B","C","B","B") df$x <- c(126,40,12,42,17,150,54,35,21,71,52,115,52,40,22,73,98,35,196) df$y <- c(92,62,4,23,60,60,49,41,50,76,52,24,9,78,71,25,21,22,25) df[,1] <- NULL df$fv <- df %>% filter(!is.na(x)) %>% lm(y ~ x*CATEGORY,.) %>% fitted.values() p <- plot_ly(data = df, x = ~x, y = ~y, color = ~CATEGORY, type = "scatter", mode = "markers" ) %>% add_trace(x = ~x, y = ~fv, mode = "lines") p
R plotly Issues with hovering text in a trace loop
Following this post and this answer I have an additional question: library(plotly) # Create data dat=data.frame(group = factor(rep(LETTERS[1:4], each=10)), my_x = rep(1:10, 4), my_y = rnorm(40)) str(dat) # Let's do a first plot p<-plot_ly(dat) # Add a trace for each group using a loop for(i in 1:length(levels(dat$group))){ subs <- subset(dat, group == levels(dat$group)[i]) p<-add_trace(p = p, data = subs, y=~my_y, x=~my_x , name=levels(dat$group)[i], type="scatter", mode="markers+lines", hoverinfo="text", text=~paste0(levels(dat$group)[i], ": x=", round(my_x, 2), "y=", round(my_y, 2))) } p Can anybody tell me why it is that when I hover over the data points, each of the labels shows the correct x and y values, however, they are all labelled as 'D:', while the legend shows the lines resemble A, B, C & D. I would like the hover text to be labeled correctly.
It could be an issue with the use of ~ in text. Try by creating the 'text' using the 'subs' data separately and then pass it on the add_trace p <- plot_ly() lvls <- levels(dat$group) for(i in seq_along(lvls)){ subs <- droplevels(subset(dat, group == lvls[i])) text1 <- with(subs, paste0(lvls[i], ": x=", round(my_x, 2), "y=", round(my_y, 2))) p <- add_trace(p, data = subs, x = ~my_x, y = ~my_y, name = lvls[i], type = 'scatter', mode = 'markers+lines', hoverinfo='text', text=text1) } p -output
Add multiple lines to a plot_ly graph with add_trace
I found an example to add lines to a plot_ly plot by using the add_trace command. How can I add a list of lines to plot without using add_trace multiple times? I tried a for loop to add the traces but this doesn't work as expected. my_lines <- list( list(x=1:10, y=2:11, color='red'), list(x=1:10, y=0:9, color='blue'), list(x=1:10, y=3:12, color='green') ) p <- plot_ly() p for(line in my_lines) { p <- add_trace(p, y=line[['y']], x=line[['x']], marker=list(color=line[['color']])) } p But this for example works as expected. p <- plot_ly() p <- add_trace(p, y=my_lines[[1]][['y']], x=my_lines[[1]][['x']], marker=list(color=my_lines[[1]][['color']])) p <- add_trace(p, y=my_lines[[2]][['y']], x=my_lines[[2]][['x']], marker=list(color=my_lines[[2]][['color']])) p <- add_trace(p, y=my_lines[[3]][['y']], x=my_lines[[3]][['x']], marker=list(color=my_lines[[3]][['color']])) p
I believe with the release of plotly 4.0 calling any of the add_* family of functions forces evaluation so there is no need to call evaluate = T anymore So, something like this should work fine: devtools::install_github("ropensci/plotly") library(plotly) p <- plot_ly() for(i in 1:5){ p <- add_trace(p, x = 1:10, y = rnorm(10), mode = "lines") } p
You need to set evaluate = TRUE to force evalutation / avoid lazy evaluation p <- plot_ly() p for(line in my_lines) { p <- add_trace(p, y=line[['y']], x=line[['x']], marker=list(color=line[['color']]), evaluate = TRUE) } p
You can transform your inputs into a long-form data frame first, then plot using the split argument. library(plotly) library(reshape2) my_lines = data.frame(x = 1:10, red = 2:11, blue = 0:9, green = 3:12) my_lines_long = reshape2::melt(my_lines, id.vars = "x") fig = plotly::plot_ly(my_lines_long, x = ~x, y = ~value, split = ~variable, marker=list(color=~variable)) fig