Add hoverinfo text on an added average line of plotly scatterplot - r

I create a basic plotly scatter plot with a line of average added. Is it possible to add hoverinfo text like: "Average : <Average Value>" ? Another solution would be the text to be permanently displayed over the line but I think that this might be more complex.
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_segments(x = 0, xend = max(ex$pts), y = mean(ex$npts), yend =mean(ex$pts) )%>%
add_trace(
text = ~paste("Team Pts: ", pts, '</br>Fantasy Pts:', npts),
hoverInfo='text'
)
p

Related

drawing rectangle on plotly R

I would like to draw a rectangle polygon over a plotly plot that uses dates. As a toy example my code is
library(tidyverse)
library(plotly)
df <- tibble(daydate = dmy(c("01-01-2022", "01-02-2022", "15-02-2022", "27-02-2022")),
value = runif(4, 0, 100))
plot_ly(df, x = ~daydate, y = ~value, color = I("#9B4393"), type = 'scatter', mode = 'lines')
I would like to draw a rectangle that spans the dates "01-02-2022" to "15-02-2022", and from 0 to 100. Also, I would like to have the rectangular area grey colour that is quite transparent.
Many thanks
Define a rectangle:
my_rectangle <- list(
type = "rect",
fillcolor = "grey",
line = list(color = "black"),
opacity = 0.3,
x0 = "2022-02-01",
x1 = "2022-02-15",
xref = "x",
y0 = 0,
y1 = 100,
yref = "y"
)
Add it to the plot:
plot_ly(
df,
x = ~daydate,
y = ~value,
color = I("#9B4393"),
type = "scatter",
mode = "lines"
) |>
layout(
shapes = list(
my_rectangle
)
)
The R plotly documentation sets out how you can draw and style rectangles and various other shapes.

Changing the color of a specific ring in a radar chart created in plotly

I have a radar chart created w/ plotly as shown below. Is there a way to have only the ring at 100 colored red, while all other rings remain in their off-gray color?
library(plotly)
fig <- plot_ly(
type = 'scatterpolar',
r = c(135, 75, 110),
theta = c('A','B','C'),
fill = 'toself'
)
fig %>%
layout(
polar = list(
radialaxis = list(
visible = T,
range = c(0, 150)
)
)
)
To my knowledge, there is not an option to use custom formatting on any axis line other than zero, so there may not actually be a "canonical" answer here that you're hoping for.
That being said, adding another trace to your plot might be the best work-around, even if it's a little clunky. Because the added line trace overrides the default categorical axis, some more extensive customization of the angular axis and some math to manually calculate categorical values relative to 360 degree coordinate system (this is normally obscured from the user) is required.
Names <- c('A','B','C')
Values <- c(135, 75, 110)
ThetaValues <- seq(from = 0, to = 360, length.out = length(Values)+1L)[seq_len(length(Values - 1L))]
plot_ly() %>%
add_trace(type = 'scatterpolar',mode = "lines",
r = rep(100,100),
theta = seq(from = 0, to = 360, length.out = 100),
line = list(smoothing = 1,
color = "red",
shape = "spline"),
hoverinfo = "skip",
showlegend = FALSE) %>%
add_trace(type = 'scatterpolar',mode = "markers",
r = Values,
name = "",
theta = ThetaValues,
color = I("blue"),
fill = 'toself') %>%
layout(polar = list(radialaxis = list(visible = T,
range = c(0, 150)),
angularaxis = list(visible = T,
type = "category",
ticktext = Names,
tickvals = ThetaValues)))

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"
)

Set the y limits of an added average line of a plotly plot

I have created a basic plotly filled plot and I am trying to add an average line with:
library(plotly)
week<-c(2,1,3)
pts<-c(10,20,30)
wex<-data.frame(week,pts)
wex <- wex[order(wex$week), ]
plot_ly(x = ~wex$week, y = ~wex$pts, type = 'scatter', mode = 'lines',
fill = 'tozeroy')%>%
add_segments(x = 0, xend = max(wex$week), y = mean(wex$pts), yend =mean(wex$pts) )
but instead of a single line I get a whole area filled. I guess it has to do with yend argument but it does not make sense as it is the same as the y argument.
It seems the fill='tozeroy' is kept for the add_segments() call.
This works:
library(plotly)
week<-c(2,1,3)
pts<-c(10,20,30)
wex<-data.frame(week,pts)
wex <- wex[order(wex$week), ]
wex
plot_ly(x = ~wex$week, y = ~wex$pts, type = 'scatter', mode = 'lines',
fill = 'tozeroy')%>%
add_segments(x = 0, xend = max(wex$week), y = mean(wex$pts), yend =mean(wex$pts),fill = 'none' )
I added fill = 'none' in add_segments()

Add a line that indicates the average value of an axis in a plotly scatterplot [duplicate]

I'm using the plotly package and I'm trying to add a horizontal line to a graph. Is there any way of doing it using plotly?
It can be done using ggplot2 and the ggplotly function as shown below:
library(plotly)
p <- ggplot() +
geom_hline(yintercept = 4) +
xlim(c(0,10)) +
ylim(c(0,10))
ggplotly(p)
But I can't add this to an existing plotly plot.
Also, the axis of my charts are not fixed, so it would be difficult (but not impossible) to just work out an x and y coordinate system for a horizontal line, but I'd rather just add one automatically.
I've looked into the y0 and dy arguments, but I can't seem to get the code for those to work, either. I'm not quite sure what they do exactly, but I think they're maybe what I'm looking for? I can't find good examples of their usage.
There are two main ways to do this (using either data or 'paper' coordinates). Assuming data coordinates, the easiest current way is via add_segments():
plot_ly() %>%
add_segments(x = 4, xend = 4, y = 0, yend = 10) %>%
add_segments(x = 3, xend = 5, y = 5, yend = 5)
Notice how we've hard coded the extent of these lines in data coordinates; so when zooming and panning the plot, the line will be "clipped" at those values. If you don't want these lines to be clipped, use a line shape with xref/yref set to paper (this puts the graph region on a 0-1 scale, rather than on the x/y data scale):
vline <- function(x = 0, color = "red") {
list(
type = "line",
y0 = 0,
y1 = 1,
yref = "paper",
x0 = x,
x1 = x,
line = list(color = color)
)
}
hline <- function(y = 0, color = "blue") {
list(
type = "line",
x0 = 0,
x1 = 1,
xref = "paper",
y0 = y,
y1 = y,
line = list(color = color)
)
}
plot_ly() %>%
layout(shapes = list(vline(4), hline(5)))
Alternatively, you could add a shape (i.e. line) under layout(). The following example adds a vertical line:
p <- plot_ly(data, x = ~x.data, y = ~y.data, text = ~text.data, type = 'scatter',
mode = 'markers', marker = list(size = ~size.data, opacity= 0.5)) %>%
layout(shapes=list(type='line', x0= 0.2, x1= 0.2, y0=min(allyvalues), y1=max(allyvalues), line=list(dash='dot', width=1)),
title = 'This is the Title',
xaxis = list(title = "X-Axis", showgrid = TRUE),
yaxis = list(title = "Y-Axis", showgrid = TRUE))
p
Building on Carson's nice answer above, here is a convenience function closer to ggplot's geom_vline()
# Add vertical line(s) at position x to plotly plot p
# Additional arguments: color, width (px), dash ('solid','dot', 'dash', etc)
# See https://plotly.com/r/reference/#layout-shapes-items-shape-line
add_vline = function(p, x, ...) {
l_shape = list(
type = "line",
y0 = 0, y1 = 1, yref = "paper", # i.e. y as a proportion of visible region
x0 = x, x1 = x,
line = list(...)
)
p %>% layout(shapes=list(l_shape))
}
To make the function additive the following modifications to the function can be used
add_vline = function(p, x, ...) {
if(!is.null(p$x$layoutAttrs)){
index <- unname(which(sapply(p$x$layoutAttrs, function(x)
!is.null(x$shapes))))
} else {
index <- integer()
}
l_shape = list(
type = "line",
y0 = 0, y1 = 1, yref = "paper", # i.e. y as a proportion of visible region
x0 = x, x1 = x,
line = list(
...
),
layer = "below"
)
if(length(index) > 0){
shapes <- p$x$layoutAttrs[[index]]$shapes
shapes[[length(shapes) + 1]] <- l_shape
p$x$layoutAttrs[[index]]$shapes <- shapes
} else {
p <- plotly::layout(
p = p,
shapes = list(l_shape)
)
}
p
}

Resources