I currently have the following plot and would like the regression lines from the gg_smooth() layer to only appear upon highlighting a group. I've attached the code and the plot below, hopefully someone knows if this can be done!
d <- highlight_key(happy, ~Region)
p <-ggplot( d, aes(x = Prevalence.of.current.tobacco.use....of.adults., y = Happiness.Score, group = Region, color = Region, text = Country))
labs(y= "Happiness Score", x = "Tobacco Use (%)", title = "Smoking and Happiness")
geom_smooth(aes(group=as.factor(Region)), method = "lm", se=FALSE, size=0.5)
geom_point(aes(size = Economy..GDP.per.Capita.))
theme_bw()
scale_color_manual(values = rainbow(10, alpha=0.6))
scale_size_continuous(range = c(0, 10), name='')
stat_cor(aes(label = ..rr.label..), color = rainbow(10), geom = "label")
gg <- ggplotly( p, tooltip = "text")
highlight( gg, on = "plotly_click", off = "plotly_doubleclick", opacityDim = .05)
Now that I've closely established the plot you ended with, I have to hide the lines, change the legend (since it's only showing the lines), and then set the functionality up for making the lines visible when you change the highlight or if you escape the highlight.
Remove line visibility; change the legend to reflect the points instead.
# First, make the lines invisible (because no groups are highlighted)
# Remove the line legend; add the point legend
invisible(
lapply(1:length(gg$x$data),
function(j){
nm <- gg$x$data[[j]]$name
md <- gg$x$data[[j]]$mode
if(md == "lines") {
gg$x$data[[j]]$visible <<- FALSE
gg$x$data[[j]]$showlegend <<- FALSE
} else {
gg$x$data[[j]]$visible <<- TRUE
gg$x$data[[j]]$showlegend <<- TRUE
}
}
))
You could look at the plot at this point and see the lines were no longer visible and the legend has changed a bit.
To add visibility changes to the highlighting, you can use Plotly events. If you know anything about HTML or Javascript, this is the same thing as an event in a browser. This uses the package htmlwidgets
. I didn't call the library with the other libraries, I just appended it to the function.
Some additional information regarding the JS: The content with
/* */
is a comment in Javascript. I've added these so you might follow what's happening (if you wanted to). ThecurveNumber
in the JS is the trace number of the Plotly object. While it only has 20 traces before rendering; it has 22 afterward. While R numbers elements starting at 1, JS (like MOST languages) starts at 0.
gg %>% htmlwidgets::onRender(
"function(el, x){
v = [] /* establish outside of the events; used for both */
for (i = 0; i < 22; i ) { /*1st 11 are lines; 2nd 11 are points */
if(i < 12){
v[i] = false;
} else {
v[i] = true;
}
}
console.log(x);
el.on('plotly_click', function(d) {
cn = d.points[0].curveNumber - 10; /*if [8] is the lines, [18] is the points*/
v2 = JSON.parse(JSON.stringify(v)); /*create a deep copy*/
v2[cn] = true;
update = {visible: v2};
Plotly.restyle(el.id, update); /* in case 1 click to diff highlight */
});
el.on('plotly_doubleclick', function(d) {
console.log('out ', d);
update = {visible: v}
console.log('dbl click ' v);
Plotly.restyle(el.id, update);
});
}")
The rendered view:
A single click from rendered
A single click from a single click
A double click from a single click