Reputation: 436
I am creating a plot with several time series, plotting the mean value and two quantiles in the process and highlighting the region between the quantiles. Then I have a unified hoverinfo showing me all points at one point in time. I do not want this hoverinfo to display the dummy trace that is only there for the highlighting. I tried both hoverinfo = skip
and hoverinfo = none
, but that only hides any text info, not the trace itself in the hoverinfo.
Here is the code I have (without most "beautification parameters" such as axis width and the likes...):
###creating dummy data
test_data <- data.frame(matrix(0,nrow = 27,ncol = 4))
colnames(test_data) <- c("x","y","value","date")
test_data$x <- c(-1,-1,-1,0,0,0,1,1,1,-1,-1,-1,0,0,0,1,1,1,-1,-1,-1,0,0,0,1,1,1)
test_data$y <- c(-1,0,1,-1,0,1,-1,0,1,-1,0,1,-1,0,1,-1,0,1,-1,0,1,-1,0,1,-1,0,1)
test_data$value <- rnorm(27,mean = 5,sd = 1)
date_vec <- c(rep(as.Date("2022-01-01"),9),rep(as.Date("2022-01-02"),9),rep(as.Date("2022-01-03"),9))
test_data$date <- date_vec
x_levels <- unique(test_data$x)
y_levels <- unique(test_data$y)
avg <- data.frame(matrix(0,nrow = 3,ncol = 1))
colnames(avg) <- c("value")
avg$date <- unique(date_vec)
Q75 <- data.frame(matrix(0,nrow = 3,ncol = 1))
colnames(Q75) <- c("value")
Q75$date <- unique(date_vec)
Q25 <- data.frame(matrix(0,nrow = 3,ncol = 1))
colnames(Q25) <- c("value")
Q25$date <- unique(date_vec)
for (i in 1:length(unique(date_vec))){
avg$value[i] <- mean(test_data$value[test_data$date == unique(date_vec)[i]])
Q75$value[i] <- quantile(test_data$value[test_data$date == unique(date_vec)[i]],0.75)
Q25$value[i] <- quantile(test_data$value[test_data$date == unique(date_vec)[i]],0.25)
}
##creating plot
fig <- plot_ly()
fig <- fig %>% layout(hovermode = 'x unified')
for(i in 1:length(x_levels)){
for(j in 1:length(y_levels)){
fig <- fig %>% add_trace(data = test_data, type = 'scatter', mode = 'lines+markers',
x = test_data$date[test_data$x == x_levels[i] & test_data$y == y_levels[j]],
y = test_data$value[test_data$x == x_levels[i] & test_data$y == y_levels[j]],
showlegend = FALSE, line = list(color = 'grey'), marker = list(color = 'grey'),
hoverinfo = 'text', text = paste0("some text dependent on x and y"))
}}
fig <- fig %>% add_trace(data = Q25, type = 'scatter', mode = 'lines', name = '25%-quantile', x = Q25$date,
y = Q25$value, showlegend = TRUE, line = list(color = 'darkred', dash = 'dot'),
hoverinfo = 'text', text = paste0("some text dependent on Q25"))
fig <- fig %>% add_trace(data = avg, type = 'scatter', mode = 'lines', name = 'mean value', x = avg$date,
y = avg$value, showlegend = TRUE, line = list(color = 'darkred', dahs = 'dash'),
hoverinfo = 'text', text = paste0("some text depenent on avg"))
fig <- fig %>% add_trace(data = Q75, type = 'scatter', mode = 'lines', name = '75%-quantile', x = Q75$date,
y = Q75$value, showlegend = TRUE, line = list(color = 'darkred', dash = 'dot'),
hoverinfo = 'text', text = paste0("some text dependent on Q75"))
#### This is the dummy trace in question:
fig <- fig %>% add_trace(x = Q25$date, y = Q25$value, type = 'scatter', mode = 'lines', fill = 'tonexty',
fillcolor = 'rgba(139,0,0,0.2)', line = list(color = 'darkred', width = 0.1), showlegend = FALSE,
hoverinfo = 'skip')
print(fig)
Is this a bug? Am I missing something obvious? Is there a better way to make the highlighting that does not create an additional hoverinfo? Thanks in advance!
Upvotes: 1
Views: 520
Reputation: 18754
Alright, this answer is not ideal—but it works.
There is good news, though. Plotly developers are already working on a solution. They're in the testing phase, which is where I got the idea for this answer. You can read about what Plotly's doing here.
First, I set a seed because you have random data. I used set.seed(3509)
. There were no changes to the data or fig
.
When you hover over any point on your graph, your fill color will disappear. The tooltip does not show the trace that shouldn't be there anyway.
The fill color will return as soon as you move on or when the tooltip goes away.
This is the Javascript to call this hover event.
# the notation [12] is the curvenumber; it represnts a single trace
hoverer = "function(el, x) {
el.on('plotly_hover', function(d){
dt = {'fill': 'none'};
Plotly.restyle(el.id, dt, [12]);
});
el.on('plotly_unhover', function(d){
ft = {'fill':'tonexty'};
Plotly.restyle(el.id, ft, [12]);
});
}"
To visualize your plot with this event:
fig %>% htmlwidgets::onRender(hoverer)
Upvotes: 1