How to adjust legend title position in ggplotly in r? [duplicate] - r

In the following example how can i add a title to the legend in plot_ly for R ?
mtcars %>% plot_ly(x = ~disp, y = ~mpg, color = ~factor(cyl), size = ~wt) %>% add_markers(
hoverinfo = "text",
text = ~paste("Displacement = ", disp, "\nMiles Per Gallon = ", mpg) ) %>% layout(title ="Custom Hover Text")
thanks

This functionality has since been included within the layout function in the legend option. There's a sub-option called title within which you can supply a list that includes the text.
mtcars %>%
plot_ly(x = ~disp, y = ~mpg, color = ~factor(cyl), size = ~wt) %>%
add_markers(hoverinfo = "text",
text = ~paste("Displacement = ", disp, "\nMiles Per Gallon = ", mpg) ) %>%
layout(title = "Custom Hover Text",
legend = list(title = list(text = "<b>Cylinders</b>"))) # TITLE HERE

The only way I know is to use an annotation and add it to the plot. Like this:
legendtitle <- list(yref='paper',xref="paper",y=1.05,x=1.1, text="Cylinders",showarrow=F)
mtcars %>% plot_ly(x = ~disp, y = ~mpg, color = ~factor(cyl), size = ~wt) %>%
add_markers( hoverinfo = "text",
text = ~paste("Displacement=",disp, "\nMiles Per Gallon = ", mpg)) %>%
layout(title ="Custom Hover Text", annotations=legendtitle )
Yielding:
It is a bit tricky to place the legend title though, not sure if this placement would always work.
Another way would be to use ggplot and ggplotly of course, and let ggplot figure it out.

Related

R plotly histogram hover text

This is my code. Just a simple historgram. But what I wanted to do is to customize the hover text so that when I hover, it will display all species included in that histogram bar. Can you help me?
iris %>%
plot_ly(x=~Sepal.Length, color=~Sepal.Width, text=~Species) %>%
add_histogram()
Here's the output. But when I hover it seems the text is only displaying the first species in the table.
plotly_hist
I'm not sure whether this is possible. Probably you are demanding too much from plotly. After trying some options I think there are two ways to go if you want the different Species to show up in the tooltip:
First option is to use a stacked histogram using hovermode = "unified" like so:
library(plotly)
fig <- plot_ly()
fig <- fig %>% add_trace(data = filter(iris, Species == "setosa"),
x = ~Sepal.Length,
color = ~Species,
text = ~Species,
type='histogram',
bingroup=1, showlegend = FALSE)
fig <- fig %>% add_trace(data = filter(iris, Species == "versicolor"),
x = ~Sepal.Length,
color = ~Species,
text = ~Species,
type='histogram',
bingroup=1, showlegend = FALSE)
fig <- fig %>% add_trace(data = filter(iris, Species == "virginica"),
x = ~Sepal.Length,
color = ~Species,
text = ~Species,
type='histogram',
bingroup=1, showlegend = FALSE)
fig <- fig %>% layout(
hovermode="unified",
barmode="stack",
bargap=0.1)
fig
The second option would be to make the computations yourself, i.e. binning and summarising and to make a bar chart of the counts.
iris %>%
mutate(Sepal.Length.Cut = cut(Sepal.Length, breaks = seq(4, 8, .5), right = FALSE)) %>%
group_by(Sepal.Length.Cut, Species) %>%
summarise(n = n(), Sepal.Width = sum(Sepal.Width)) %>%
tidyr::unite("text", Species, n, sep = ": ", remove = FALSE) %>%
summarise(n = sum(n), Sepal.Width = sum(Sepal.Width) / n, text = paste(unique(text), collapse = "\n")) %>%
plot_ly(x = ~Sepal.Length.Cut, y = ~n, text = ~text) %>%
add_bars(marker = list(colorscale = "Rainbow"), hovertemplate = "%{y}<br>%{text}")
Edit A third option would be to use ggplotly(). This way it is an easy task to add annotations displayling the total numbers per bin. This way we can make use of the stats layers in ggplot2 which will do all the computations. To the best of my knowledge that couldn't be done that easily using "pure" plotly.
library(plotly)
ggplot(iris, aes(Sepal.Length, fill = Species)) +
stat_bin(breaks = seq(4, 8, .5), closed = "left") +
stat_bin(breaks = seq(4, 8, .5), closed = "left", geom = "text", mapping = aes(Sepal.Length, label = ..count..), inherit.aes = FALSE, vjust = -.5) +
theme_light()
ggplotly()

How to set different text and hoverinfo text

I am working with the plotly package, and I cannot find a way to display different things on the chart itself and in the hoverinfo.
Here is an example of a barchart:
library(plotly)
library(dplyr)
data(iris)
df <- iris %>%
group_by(Species) %>%
summarise(n = n(),
avg = mean(Sepal.Length))
p1 <- plot_ly(data = df,
x = ~Species,
y = ~n,
type = "bar",
text = ~paste("Species :", Species,
"<br> Avg :", avg),
textposition = "auto",
hoverinfo = "text")
From this code I get this:
And I would like to display the frequency (n) value in each bar instead of the same thing as the hoverinfo.
I have been looking at this thread but the solution described is too complicated for me and I think there must be an easier way to solve this issue.
Something like this?
p1 <- plot_ly(data = df,
x = ~Species,
y = ~n,
type = "bar",
text = ~n,
textposition = "auto",
hoverinfo = "text",
hovertext = paste("Species :", df$Species,
"<br> Avg :", df$avg))

Separate symbol and color in plotly legend

I want to achieve the same result as this ggplot code with plotly:
mtcars %>% add_rownames('car') %>%
ggplot(aes(x = mpg,
y = disp,
color = as.factor(gear),
shape = as.factor(cyl))) +
geom_point()
which results in:
My plotly code is:
library(dplyr)
mtcars %>% add_rownames('car') %>%
plot_ly(x = ~mpg,
y = ~disp,
text = ~car,
color = ~as.factor(gear),
symbol = ~as.factor(cyl),
mode = 'markers')
which enumerates all possible combinations of colors and shapes in the legend.
Is there a way to have a similar legend to the ggplot?
UPDATE: To overcome some of the issues mentioned for my previous solution (see below) and to increase the usability of the legend, one can simply add the column name to the legend description and then assign the legendgroups to each category.
mtcars %>% rownames_to_column('car') %>%
plot_ly() %>%
#Plot symbols for cyl
add_trace(type = "scatter",
x = ~mpg,
y = ~disp,
text = ~car,
symbol = ~paste0(cyl," cyl."),
mode = 'markers',
marker = list(color = "grey", size = 15)) %>%
#Overlay color for gears
add_trace(type = "scatter",
x = ~mpg,
y = ~disp,
text = ~car,
color = ~paste0(gear, " gears"),
mode = 'markers')
This is the previous solution, which is visually closer to the ggplot2 equivalent:
Based on the answer of dww in this thread, we can manually create the groups for cylinders and gears. Subsequently, with the answer of Artem Sokolov this thread, we can add the legend titles as annotations.
mtcars %>% rownames_to_column('car') %>%
plot_ly() %>%
#Plot symbols for cyl
add_trace(type = "scatter",
x = ~mpg,
y = ~disp,
text = ~car,
symbol = ~as.factor(cyl),
mode = 'markers',
legendgroup="cyl",
marker = list(color = "grey", size = 15)) %>%
#Overlay color for gears
add_trace(type = "scatter",
x = ~mpg,
y = ~disp,
text = ~car,
color = ~as.factor(gear),
mode = 'markers',
legendgroup="gear") %>%
#Add Legend Titles (manual)
add_annotations( text="Cylinders:", xref="paper", yref="paper",
x=1.02, xanchor="left",
y=0.9, yanchor="bottom", # Same y as legend below
legendtitle=TRUE, showarrow=FALSE ) %>%
add_annotations( text="Gears:", xref="paper", yref="paper",
x=1.02, xanchor="left",
y=0.7, yanchor="bottom", # Y depends on the height of the plot
legendtitle=TRUE, showarrow=FALSE ) %>%
#Increase distance between groups in Legend
layout(legend=list(tracegroupgap =30, y=0.9, yanchor="top"))
Unsolved issues:
Groups have to be created manually
Groups are just overlayed (color over shape). This means that only the whole group can be dis-/activated in the legend (e.g., it is not possible to only show only the entries with 4 cylinders)
The position of the second legend title (annotation) depends on the height of the plot!

Add title to the plotly legend

In the following example how can i add a title to the legend in plot_ly for R ?
mtcars %>% plot_ly(x = ~disp, y = ~mpg, color = ~factor(cyl), size = ~wt) %>% add_markers(
hoverinfo = "text",
text = ~paste("Displacement = ", disp, "\nMiles Per Gallon = ", mpg) ) %>% layout(title ="Custom Hover Text")
thanks
This functionality has since been included within the layout function in the legend option. There's a sub-option called title within which you can supply a list that includes the text.
mtcars %>%
plot_ly(x = ~disp, y = ~mpg, color = ~factor(cyl), size = ~wt) %>%
add_markers(hoverinfo = "text",
text = ~paste("Displacement = ", disp, "\nMiles Per Gallon = ", mpg) ) %>%
layout(title = "Custom Hover Text",
legend = list(title = list(text = "<b>Cylinders</b>"))) # TITLE HERE
The only way I know is to use an annotation and add it to the plot. Like this:
legendtitle <- list(yref='paper',xref="paper",y=1.05,x=1.1, text="Cylinders",showarrow=F)
mtcars %>% plot_ly(x = ~disp, y = ~mpg, color = ~factor(cyl), size = ~wt) %>%
add_markers( hoverinfo = "text",
text = ~paste("Displacement=",disp, "\nMiles Per Gallon = ", mpg)) %>%
layout(title ="Custom Hover Text", annotations=legendtitle )
Yielding:
It is a bit tricky to place the legend title though, not sure if this placement would always work.
Another way would be to use ggplot and ggplotly of course, and let ggplot figure it out.

How can I remove the size line in the hoverinfo of a Plotly chart in R?

I've found the following page instructing how to create custom hover text for plotly charts in R.
https://plot.ly/r/text-and-annotations/#custom-hover-text
This seems to do exactly what I want, however when I copy the code (see below) into RStudio and run it locally I get an extra line in in my hoverinfo, showing the size variable.
Screenshot of the chart in RStudio:
How can I remove this "wt (size): 1.835" line in hoverinfo?
library(plotly)
p <- mtcars %>%
plot_ly(x = disp, y = mpg, mode = "markers", color = cyl, size = wt,
hoverinfo = "text",
text = paste("Displacement = ", mtcars$disp, "Miles Per Gallon = ", mtcars$mpg)) %>%
layout(title ="Custom Hover Text")
p
I can achieve what you want, but it's ugly, and really a bit of a hack. I'm not overly proud of this but here we go.
# Your plot
library(plotly)
p <- mtcars %>%
plot_ly(x = disp, y = mpg, mode = "markers", color = cyl, size = wt,
hoverinfo = "text",
text = paste("Displacement = ", mtcars$disp, "Miles Per Gallon = ", mtcars$mpg)) %>%
layout(title ="Custom Hover Text")
p
# Get the list for the plot
pp <- plotly_build(p)
# Pick up the hover text
hvrtext <- pp$data[[1]]$text
# Split by line break and wt
hvrtext_fixed <- strsplit(hvrtext, split = '<br>wt')
# Get the first element of each split
hvrtext_fixed <- lapply(hvrtext_fixed, function(x) x[1])
# Convert back to vector
hvrtext_fixed <- as.character(hvrtext_fixed)
# Assign as hovertext in the plot
pp$data[[1]]$text <- hvrtext_fixed
# Plot
pp
I came here looking for same solution and the above one worked after some haggle but I ultimately found the right method later. Here it is:
Put your 'Size' variable inside marker=list()
So instead of
plot_ly(x = disp, y = mpg, mode = "markers", color = cyl, size = wt,
hoverinfo = "text",
text = paste("Displacement = ", mtcars$disp, "Miles Per Gallon = ", mtcars$mpg))
You can use
plot_ly(x = disp, y = mpg, mode = "markers", color = cyl, marker=list(size=wt),
hoverinfo = "text",
text = paste("Displacement = ", mtcars$disp, "Miles Per Gallon = ", mtcars$mpg))
That worked for me.

Resources