'Add dynamic vertical line trace to plotly animated horizontal bar plot
I have a horizontal animated bar plot using the plotly package. I want to add a vertical line to show the median of the bar values and I want this to change value along with the frames of the bars.
Simplified example:
data <- data_frame(Year=c(1995, 1995, 1995, 1996, 1996, 1996, 1997, 1997, 1997, 1998, 1998, 1998),
Highest_Degree=c("Associate's", "Bachelor's", "PhD",
"Associate's", "Bachelor's", "PhD",
"Associate's", "Bachelor's", "PhD",
"Associate's", "Bachelor's", "PhD"),
Salary=c(35200, 45270, 79670,
41950, 56330, 99410,
42780, 55930, 100000,
42860, 56080, 100000)
)
#plot
plot_ly(data, x=~Salary, y=~Highest_Degree, frame=~Year, type = 'bar') %>%
layout(yaxis=list(title=" "), xaxis=list(title="Median Salary (USD)"),
title=list(text=paste("Median Salary by Education Level 1995-1998")))
##to get medians list
medians <- data %>%
select(c(Year, Salary)) %>%
group_by(Year) %>%
summarise(Median=median(Salary))
Image example, except it needs to change with the rest of the animation: 
UPDATE: I added the overall medians to my original data frame and added a horizontal line with a trace (image below), but the line doesn't span the entire height of the plot. Is there a way to do this with 'shapes' in layout when the y axis is not numeric so that it spans the entire plot?

Solution 1:[1]
It might be easiest to start by building the plotly plot and manually modifying the frames' layouts. After that, I used vectorization to change the frames, so I wanted to ensure that the medians were in order by year. With such a small dataset, it's probably not necessary to do this by code, but I figured this is just a small snapshot of what you're working with.
# build to see frames
p2 <- plotly_build(p1)
# modify frames
# first, make sure the data is in order by year (order by frame)
medians <- arrange(medians, Year)
lapply(1:nrow(medians), # for each frame
function(i){
vline = list(
type = "line",
y0 = 0,
y1 = 1,
yref = "paper",
x0 = unlist(medians[i, ]$Median), # median for that frame
x1 = unlist(medians[i, ]$Median),
line = list(color = "black", dash = "dot") # you can mod here!
)
p2$x$frames[[i]]$layout <<- list(shapes = list(vline)) # change plot
})
After that, you can just call p2 to plot it.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Kat |

