Add a line to a boxplot using plotly - r

Is it possible to add vertical line to a boxplot in plotly? I know it works in ggplot2, but I need it in plotly. Would be nice if I don't need to convert my static ggplot every time.
Here is a minimal example
plot_ly(x = ~rnorm(50), type = "box") %>%
add_trace(x = ~c(0.75),y=c(-2,0.5),type='scatter',mode='lines')
Instead of the line stoping before I want the line to go through the boxplot. In addition I want the same plot extent as the single boxplot.

Change the sequence of calls:
library(plotly)
plot_ly(x = ~c(0.75), y=c(-2,2), type='scatter', mode='lines') %>%
add_boxplot(x = ~rnorm(50), inherit = F) %>%
layout(yaxis = list(range = c(-2, 2)))

Related

Adding polygon to plotly scatterplot

I created a plotly scatterplot in R on which I would like to add a polygon.
current plot
This is the code I used to make the graph:
fig <- plot_ly(data = data, x= ~xbeak, y = ~ybeak, color = ~coordsbeak, text = ~paste(coordsbeak), type = 'scatter')
Now I want to add a polygon to this plot, which I tried with add_polygons. The polygon is a different dataframe, consisting two columns with 42 x and y coordinates.
fig <- fig %>% add_polygons(x = xym$x, y=xym$y)
However when I try to run this I get this error which I don't understand. Any idea what I'm doing wrong?
Error:
! Tibble columns must have compatible sizes.
• Size 42: Columns x and y.
• Size 11149: Columns text and color.
ℹ Only values of size one are recycled.
Run rlang::last_error() to see where the error occurred.
Two solutions below. First, adding inherit = FALSE to add_plygons().
library(tidyverse)
library(plotly)
xym<-data.frame(y=c(3,4,4,3),
x=c(5,5,6,6))
fig <- plot_ly(data = iris, x= ~Sepal.Length, y = ~Sepal.Width, color = ~Species, text = ~paste(Species), type = 'scatter', mode="markers")
fig <- fig %>% add_polygons(x = xym$x, y=xym$y, inherit = FALSE, showlegend = FALSE)
fig
Or, Switch the order of operations - make the polygons first, then the scatterplot.
Here is an example with iris data:
xym<-data.frame(x=c(5,5,6,6),
y=c(3,4,4,3))
# make an empty plot_ly object
fig <- plot_ly()
# add the polygons
fig<-fig %>% add_polygons(x = xym$x, y=xym$y)
# add the scatterplot
fig<-fig %>% add_trace(data = iris, x= ~Sepal.Length, y = ~Sepal.Width, color = ~Species, text = ~paste(Species), type ="scatter", mode="markers")
fig
referenced - Adding a polygon to a scatter plotly while retaining the hover info
and Adding a polygon to a scatter plotly

R plot_ly: How to add horizontal space in plot area?

I am using plot_ly in R to create a line chart. By default, the line runs right up to the left and right edges of the plot area. I would like to add some space here, as is done by default in ggplot. Does anyone know how to do this with plot_ly?
Reproducible example:
df <- data.frame(date = seq(as.Date('2021-01-01'), length=50, by='day'),
value = rnorm(50))
plot_ly(df, x=~date, y=~value) %>%
add_lines(color=I('black')) %>%
layout(title = 'plot_ly', plot_bgcolor = 'E9E9E9')
ggplot(df, aes(x=date, y=value)) +
geom_line() +
ggtitle('ggplot')
I would like to add the space shown below with red arrows:
You can set the range in xaxis :
library(plotly)
plot_ly(df, x=~date, y=~value) %>%
add_lines(color=I('black')) %>%
layout(title = 'plot_ly', plot_bgcolor = 'E9E9E9',
xaxis = list(range = c(min(df$date) - 3, max(df$date) + 3)))

Bar-plot does not show bar for only one x value

I am having an issue with a plotly bar plot when I define the date range for the x-axis.
When there is one or more data points with the same x-value, the bars do not show in the plot. If there is at least two different x-values or if I do not use a x-axis range, then the bars show as they should.
Below follows an example (I am currently using lubridate to deal with dates).
library(lubridate)
library(plotly)
# Same x-value: bar does not show
plot_ly(x = c(ymd("2019-08-25"), ymd("2019-08-25")), y = c(1, 2), type = "bar") %>%
layout(xaxis = list(range = ymd(c("2019-08-20", "2019-08-30"))))
# Different x-values: bars are shown
plot_ly(x = c(ymd("2019-08-25"), ymd("2019-08-26")), y = c(1, 2), type = "bar") %>%
layout(xaxis = list(range = ymd(c("2019-08-20", "2019-08-30"))))
# No x-axis range defined, same x-values: the bar is shown
plot_ly(x = c(ymd("2019-08-25"), ymd("2019-08-25")), y = c(1, 2), type = "bar")
Any solution?
Edit: For comparison, ggplot2 does not have the same issue:
# ggplot works like expected
library(lubridate)
library(ggplot2)
ggplot(NULL, aes(x = ymd(c("2019-08-25", "2019-08-25")), y = c(1, 2))) +
geom_col() +
xlim(ymd(c("2019-08-20", "2019-08-30")))
Your code is actually being understood in your first version, but you need to set the width of the bars so they show up in the end.
I'm not sure what the units are (maybe miliseconds???) so you may need to play around with it or do research to get a good width for your actual scenario.
plot_ly() %>%
add_bars(x = c(ymd("2019-08-25"), ymd("2019-08-25")), y = c(1, 2), type = "bar",width=100000000)%>%
layout(xaxis = list(range = ymd(c("2019-08-20", "2019-08-30"))))

Plotly markers to appear in a bar chart

I am new to plotly and want to make my own bullet chart (a bit like http://bl.ocks.org/mbostock/4061961) that has markers/traces to show the values of the relevant values when comparing actual vs expected.
Below is my attempt:
q <- ggplot(data.frame(measure='',actual=25),aes(x=measure,y=actual))+
geom_bar(stat='identity')+
ylim(c(0,35))+
geom_hline(yintercept = 30,color='red')+
geom_text(y=30,label='Expected',angle=270,vjust=0)+
coord_flip()+
ylab('Num. of carrots')
q
q1 <- ggplotly(q) %>% add_markers()
q1
When converting it to plotly using ggplotly, the text looks like it has not rotated correctly, and the markers/traces do not show for the bar chart...Any help here would be much appreciated.
Kindest regards,
HLM
I do not think that plotly supports rotating text for type="scatter" (which is how ggplotly is interpreting your geom_text). You can delete the geom_text line from the ggplot graph, then add text to the plotly one using annotations:
q1 <- ggplotly(q) %>% add_markers() %>%
layout(annotations = list(x = 30, y = 1, text = "Expected", textangle=270))
q1
update
The 2nd part of your question (how to also get hover info on the bar) is slightly trickier. To get the hover info, we can create the bars using the plotly API directly like this
p.bars = plot_ly(data = data.frame(measure='', actual=25)) %>%
add_bars(y=~measure, x=~actual, orientation="h")
we can add the text annotation to it like this
p.bars.text = p.bars %>%
layout(annotations = list(x = 30, y = 0, text = "Expected", textangle=270,
showarrow=F, xanchor="center"))
But the problem is that adding a line also to this plot by
p.bars.text %>% add_segments(x=30, xend=30, y=-0.5, yend=0.5)
gives an error
Error in populate_categorical_axes(p) : Can't display both discrete & non-discrete data on same axis
I.e. we can only specify the y values of the line with respect to categorical values of y. So, for example we can do
dat1 = data.frame(measure=letters[1:2], actual=c(25,20))
plot_ly(data = dat1) %>%
add_bars(y=~measure, x=~actual, orientation="h") %>%
layout(annotations = list(x = 29, y = 0, text = "Expected", textangle=270,
showarrow=F, xanchor="center")) %>%
add_segments(x=30, xend=30, y='a', yend='b')
which gives the following in which the line is aligned with the category labels rather than with the width of the bars
The only solution I have to this at the moment is to use a numeric axis for the categories, and then set the axis labels using ticktext:
plot_ly(data = data.frame(measure=c(0,1), actual=c(25,20))) %>%
add_bars(y=~measure, x=~actual, orientation="h", showlegend=F) %>%
add_segments(x=30, xend=30, y=-0.4, yend=0.4, showlegend=F) %>%
layout(annotations = list(x = 29.5, y = 0, text = "Expected", textangle=270, showarrow=F, xanchor="center"),
yaxis = list(tickmode="array", tickvals=c(0,1), ticktext=c("", "") ))

Subplots using Plotly in R (bug fixed)

How can I create a subplot grid with Plotly in R?
The official site has this nice Python example:
The python code has the option rows=2 and cols=2, but in R the subplot function has just the parameter nrows, without ncols.
I tried this example in R, but nrows do not seam to work as expected:
# Basic subplot
library(plotly)
p <- plot_ly(economics, x = date, y = uempmed)
subplot(p,p,p,p,
margin = 0.05,
nrows=2
) %>% layout(showlegend = FALSE)
They are in a line instead of in a grid. See the result:
Here is the R suplots page for reference. Unfortunately, use ggplotly is not a option for me, like this
UPDATE
It was a bug. Plotly team is very fast, and it was fixed in just 3 days (check here)! Github version is already updated. Great job!
This seems to be a genuine bug in the way subplot() generates the y-axis domains for the two plots. Indeed, they overlap which can easily be seen if you execute
p <- plot_ly(economics, x = date, y = uempmed)
q <- plot_ly(economics, x = date, y = unemploy)
subplot(p,q, nrows = 2)
This will produce the following plot:
If you take a close look at the y-axis you see that they overlap. That hints at a problem in the way subplot() defines the domain of the y-axes of the subplot.
If we correct the domain specification of the y-axes manually (following the plotly documentation), we can solve the problem:
subplot(p,q, nrows = 2) %>% layout(yaxis = list(domain = c(0, 0.48)),
yaxis2 = list(domain = c(0.52, 1)))
This produces:
Now, if you want to reproduce the 4x4 subplot matrix similar to the Python example, you probably need to manually adjust the x-axis domains in a similar way.
Since this is a bug and my solution is only a workaround, I suggest, however, that you file an issue with plotly on GitHub.
Based on this:
p <- economics %>%
tidyr::gather(variable, value, -date) %>%
transform(id = as.integer(factor(variable))) %>%
plot_ly(x = ~date, y = ~value, color = ~variable, colors = "Dark2",
yaxis = ~paste0("y", id)) %>%
add_lines() %>%
subplot(nrows = 5, shareX = TRUE)

Resources