Viewing hover info for overlapping scatter points in Plotly R - r

I was surpised I was not able to google this solution, so I thought i'd put up a post. Surely others have the same issue...
The issue I have is that when two or more scatter points overlap (i.e. same x and y), the hover information only shows the info of the top point.
Example:
df <- data.frame(ID=1:6, x=c(5:9, 7), y=c(1:5, 3)+10, info=paste('Hover information: ',c(LETTERS[c(1:6)])))
df
plot_ly(df) %>%
add_trace(x = ~x,
y = ~y,
type = 'scatter',
mode = 'markers',
marker = list(color = 1:6,
symbol = 1:6,
size = 25),
hoverinfo = "text",
text = df$info)
It is possible to make BOTH hoverinfo for the middle point to show up? Possibly as:
Hover information: C
Hover information: F

You can try to use add_markers() and jitter, e.g:
plot_ly(df) %>%
add_markers(x = ~jitter(x, 1),
y = ~jitter(y, 1),
type = 'scatter',
mode = 'markers',
marker = list(color = 1:6,
symbol = 1:6,
size = 25),
hoverinfo = "text",
text = ~info)
But to get multiple information as you designed, maybe you need to modify your dataframe (but you will lose the colour code):
df$info <- as.character(df$info)
df$combined_info[1] <- df$info[1]
for(i in 2:nrow(df)){
df$combined_info[i] <- df$info[i]
for(j in 2:i-1){
if((df$x[j] == df$x[i]) && (df$y[j] == df$y[i])){
df$combined_info[i] <- paste0(df$combined_info[j], "<br>",
df$info[i])
}
}
}
And then you can use the original plotly code, while changing the "text" argument:
plot_ly(df) %>%
add_trace(x = ~x,
...
text = ~combined_info)

Related

R Plotly how to link text to bubbles in order to remove it when click on legend

With plotly on R, I have a bubble scatter plot and I want to add black text on each bubble. I also have my bubbles colored following a column of my data frame (Type: Yes or No). On my legend, when I click on "Yes" it will remove the bubbles linked to "Yes" but the text is staying, even if I added a 'legendgroup=~Type' in both traces.
How can I remove the text linked to the bubble when the user click on the legend ?
It is possible but only if I set 'color = ~Type' in my text trace, but I want to keep the text in black.
Example :
df <- data.frame(Projet=c("A", "B", "C"), x=c(0.2, 0.4, 0.6), y=c(0.6, 0.5, 0.1), Size=c(2,5,8), Type=c("Yes", "Yes", "No"))
fig <- plot_ly(df, x = ~ x, y = ~y) %>%
add_trace(color = ~Type, size = ~Size,
type = 'scatter', mode = 'markers',
sizes = c(20, 80),
marker = list(symbol = 'circle', sizemode = 'diameter',line = list(width = 2, color = 'gray60')),
hovertext = ~paste('Projet:', Projet, '<br>Size (kE):', Size),
hoverinfo="text", legendgroup=~Type) %>%
add_trace(type="scatter", mode="text", text=~Projet, showlegend=F, legendgroup=~Type)
fig
Which gives :
And if I click on "Yes" in the legend :
=> I want to remove the "A" and "B" text in this case
Thanks !
When I looked at your Plotly object, you assigned three group names to the parameter legendgroup. The reason it worked in your initial call add_trace is that Plotly will split a trace by color. In your call for text, everything is the same color, so it didn't automatically split the trace.
In your call for the text, you need to add split to split the trace.
Check it out
library(plotly)
df <- data.frame(Project = c("A", "B", "C"), x = c(0.2, 0.4, 0.6),
y = c(0.6, 0.5, 0.1), Size = c(2,5,8),
Type = c("Yes", "Yes", "No"))
fig <- plot_ly(df, x = ~ x, y = ~y) %>%
add_trace(color = ~Type, size = ~Size,
type = 'scatter', mode = 'markers',
sizes = c(20, 80),
marker = list(symbol = 'circle', sizemode = 'diameter',
line = list(width = 2, color = 'gray60')),
hovertext = ~paste('Project:', Project, '<br>Size (kE):', Size),
hoverinfo = "text", legendgroup = ~Type) %>%
add_trace(type = "scatter", mode = "text", text = ~Project,
showlegend = F, legendgroup = ~Type, split = ~Type) # <- I'm new!
fig

Create a filled area line plot with annotated scatters using plotly

I want to create a filled area plot with line and scatters like in the screenshot attached but I do not know how could add scatters for every year of x-axis and also annotate its value. My code is:
library(plotly)
data <- t(USPersonalExpenditure)
data <- data.frame("year"=rownames(data), data)
fig <- plot_ly(data, x = ~year, y = ~Food.and.Tobacco, name = 'Food and Tobacco', type = 'scatter', mode = 'line', stackgroup = 'one', fillcolor = '#F5FF8D')
fig
The mode lines+markers+text allows you to define a line plot with markers and add some text.
I changed the type of year from factor to numeric, because I had to expand the xaxis for readabilty of the annotations.
library(plotly)
data <- t(USPersonalExpenditure)
data <- data.frame("year" = as.numeric(rownames(data)), data)
plot_ly(data,
x = ~year,
y = ~Food.and.Tobacco,
text = ~Food.and.Tobacco) %>%
add_trace(
type = 'scatter',
mode = 'lines+markers+text',
fill = 'tozeroy',
fillcolor = '#F5FF8D',
marker = list(color = 'black'),
line = list(color = 'black'),
textposition = "top center",
hovertemplate = paste0("<b>%{x}</b>
Cummulative Food and Tobacco: %{y}
<extra></extra>"),
hoveron = 'points') %>%
layout(xaxis = list(
range= list(min(data$year) - 1, max(data$year) + 1)))

Plotly R setting the title of a continuous color legend

I'm trying to plot a 3D scatter using Plotly and R. Other than x, y and z I also would like to set the color of each point depending on a fourth variable.
I manage to set the plot correctly (the use of name = ~res is to show the value of res while hovering), but I am not able to change the name of the colorbar.
This is a mock code of what I've done:
library(tidyverse)
library(plotly)
a = seq(1,10,1)
b = seq(100,1000,100)
c = seq(1,4.9,0.4)
data = tibble(a,b,c)
data <- data %>% mutate(res = a+b+c)
layout_details <- list(xaxis = list(title = 'a [-]'),
yaxis = list(title = 'b [-]'),
zaxis = list(title = 'c [-]'),
coloraxis=list(colorbar=list(title=list(text='Here are the results'))))
p = plot_ly(data, x = ~a, y = ~b, z = ~c, color = ~res, type = 'scatter3d',
mode = 'markers', name = ~res, showlegend = FALSE, scene = 'scene1')
p <- p %>% layout(scene1 = layout_details)
p
I've noticed that a quite similar question was asked (R plotly to legend title value ignored for continuous color scatter plot), but without any answers.
Does anyone know how to solve this?
Thanks
You can define your colorbar inside the marker argument.
The name argument is interfering with the colorbar therefore I moved res from the name argument to the hovertemplate and the customdata.
Code
p = plot_ly(data, x = ~a, y = ~b, z = ~c,
name = "",
scene = 'scene1',
type = 'scatter3d',
mode = 'markers',
customdata = as.list(data$res),
hovertemplate = paste('x: %{x}',
'y: %{y}',
'z: %{z}',
'name: %{customdata}',
sep = "\n"),
marker = list(color = ~res,
colorbar = list(title = "Here are the results"),
colorscale='Viridis',
showscale = TRUE))
p <- p %>% layout(scene1 = layout_details)
p
Plot

plotly fill color transparency in R shiny

In R and plotly. How can I tried to use alpha to control the transparency of a grouped scatter plot.
I followed the example in Plotly's fillcolor defaults to half-transparency, want no-transparency:
df <- data.frame(x = rep(LETTERS[1:5], 3),
y = rexp(15, rate = 0.5),
z = c(rep("Adam", 5), rep("Arthur", 5), rep("Ford", 5)))
df <- arrange(df, desc(z))
plot_ly(df, x = ~x, y = ~y, color = ~z, type = 'scatter', stackgroup = 'one',
groupnorm = 'percent', colors = gg_color(Nv), alpha = 1, alpha_stroke = 1)
But the fill colours are transparent and alpha does not seem to do anything.
The solution given in Plotly's fillcolor defaults to half-transparency, want no-transparency works:
library(htmlwidgets)
library(htmltools)
fillOpacity = function(., alpha = 0.5) {
css = sprintf("<style> .js-fill { fill-opacity: %s !important; } </style>", alpha)
prependContent(., HTML(css))
}
plot_ly(df, x = ~x, y = ~y, color = ~z, type = 'scatter', stackgroup = 'one',
groupnorm = 'percent', colors = gg_color(Nv), alpha = 1, alpha_stroke = 1) %>%
fillOpacity(alpha = 1)
Works:
However, in Shiny this gives the following warning and the opacity is lost
Warning in renderWidget(instance) :
Ignoring prepended content; prependContent can't be used in a Shiny render call
Is there a way to fix this?
Note: The second figure is a snip in windows, because when clicking on the download png plotly button, the second graph still downloads the graph as transparent. The two issues are probably related.
I looked here https://plotly.com/python/filled-area-plots/ and used fill='tonexty'. Now the alpha = 1 works and controls the transparency of the fill.
ply = plot_ly(df, x = ~x, y = ~y, color = ~z, type = 'scatter', stackgroup = 'one',
groupnorm = 'percent', alpha = 1, alpha_stroke = 1, mode = 'marker', opacity=1, fill='tonexty');ply
gives:
I still think this is an oversight in the API. when stackgroup = 'one', groupnorm = 'percent' the fill is automatically fill='tonexty'. there shouldn't be a need to add it in order to manipulate the opacity. Also, alpha = 1 becoming active only because works fill='tonexty' has been added is confusing.

Set hoverinfo text in plotly scatterplot

I create a basic scatterplot with plotly like the one below. The issue is that while I set specifically the text inside the hoverinfo the numeric values are displayed one more time- (20,56) -before the actual text- Team Pts:20 Fantasy Pts: 56 -that I wish to display. How can I delete them?
pts<-c(10,20,30)
npts<-c(24,56,78)
ex<-data.frame(pts,npts)
library(plotly)
p <- plot_ly(data = ex, x = ~pts, y = ~npts,
marker = list(size = 10,
color = 'white',
line = list(color = 'rgba(152, 0, 0, .8)',
width = 2))) %>%
add_trace(
text = ~paste("Team Pts: ", pts, '</br>Fantasy Pts:', npts),
hoverInfo='text'
)
p
One way of doing this is to add the text to each data point, by adding in a variable to the hovertemplate parameter.
I don't have a way to test this at the moment, but it should look something like this:
add_trace(
x = ~pts,
y = ~npts,
hovertemplate = paste('<i>Team points</i>: %{x}',
'<br><b>Fantasy Pts</b>: %{y}</br>',
)
)
You just misspelled the argument hoverInfo, which should be hoverinfo, so your plot used the default hoverinfo = "all". Also, replace </br> by <br> to display the hover text on two lines:
library(plotly)
ex <- data.frame(
pts = c(10, 20, 30),
npts = c(24, 56, 78)
)
plot_ly(data = ex,
type = "scatter",
mode = "markers",
x = ~pts,
y = ~npts,
text = ~paste("Team Pts: ", pts, '<br>Fantasy Pts:', npts),
hoverinfo = "text"
)

Resources