How can I combine a line and scatter on same plotly chart? - r

The two separate charts created from data.frame work correctly when created using the R plotly package.
However,
I am not sure how to combine them into one (presumably with the add_trace function)
df <- data.frame(season=c("2000","2000","2001","2001"), game=c(1,2,1,2),value=c(1:4))
plot_ly(df, x = game, y = value, mode = "markers", color = season)
plot_ly(subset(df,season=="2001"), x = game, y = value, mode = "line")
Thanks in advance

The answer given by #LukeSingham does not work anymore with plotly 4.5.2.
You have to start with an "empty" plot_ly() and then to add the traces:
df1 <- data.frame(season=c("2000","2000","2001","2001"), game=c(1,2,1,2), value=c(1:4))
df2 <- subset(df, season=="2001")
plot_ly() %>%
add_trace(data=df1, x = ~game, y = ~value, type="scatter", mode="markers") %>%
add_trace(data=df2, x = ~game, y = ~value, type="scatter", mode = "lines")

here is a way to do what you want, but with ggplot2 :-) You can change the background, line, points color as you want.
library(ggplot2)
library(plotly)
df_s <- df[c(3:4), ]
p <- ggplot(data=df, aes(x = game, y = value, color = season)) +
geom_point(size = 4) +
geom_line(data=df_s, aes(x = game, y = value, color = season))
(gg <- ggplotly(p))

There are two main ways you can do this with plotly, make a ggplot and convert to a plotly object as #MLavoie suggests OR as you suspected by using add_trace on an existing plotly object (see below).
library(plotly)
#data
df <- data.frame(season=c("2000","2000","2001","2001"), game=c(1,2,1,2),value=c(1:4))
#Initial scatter plot
p <- plot_ly(df, x = game, y = value, mode = "markers", color = season)
#subset of data
df1 <- subset(df,season=="2001")
#add line
p %>% add_trace(x = df1$game, y = df1$value, mode = "line")

Related

How to change a certain point on a scatterplot in Plotly a different colour to rest of data

I am using Plotly to plot a scatterplot of GWAS data and want to highlight a certain point a different colour to the rest of the data. I have tried multiple times but unable to find away around this in Plotly. Any advice would be great please.
input data looks like this:
fig <- fig %>% add_trace(data=data_1, x = ~BP, y = ~log, name = "data", mode = "markers", type = "scatter",
y = c(117300000, 117900000), marker = list(size = 8, color = '#d62728'),
x = c(117558703), y = c(19.75696195), marker = list(color = 'blue',size = 8), type = "scatter")
fig
One of the easiest ways is to create a variable to identify that specific point. I created sample data here and assigned a colour variable equal to 1 for the point I want in another color.
df = tibble(bp = round(rnorm(10,5,2),2),
log = round(rnorm(10,6,1.5),2))
df$colour <- as.factor(ifelse(df$bp == 4.41,1 ,0))
fig <- plot_ly(data = df, x = ~bp, y = ~log, group_by = ~colour,marker = list(color = factor(df$colour,labels=c("red","purple")))) %>%
add_trace(data = df, x = ~bp, y = ~log, mode = 'markers', type = 'scatter')
fig
Link to plot produced by this code
One option to achieve your desired result would be to add an indicator variable to your data to indicate which points you want to highlight. This variable could then be mapped on the color attribute. The colors could then be set via the colors attribute.
Using a minimal reproducible example base on mtcars:
library(plotly)
data_1 <- mtcars
data_1$highlight <- row.names(data_1) %in% c("Honda Civic", "Porsche 914-2")
plot_ly() %>%
add_trace(
data = data_1, x = ~hp, y = ~mpg, color = ~highlight,
mode = "markers", type = "scatter",
marker = list(size = 8), colors = c("#d62728", "blue")
)

How can I add scatter point to an existing 3D scatter plot in plotly

I created a 3D scatter plot using plotly in R but I have trouble adding more data to the 3D plot.
library(plotly)
names(b) <- c('m1','m2','m3','clust')
umap_1 <- b$m1
umap_2 <- b$m2
umap_3 <- b$m3
clust <- b$clust
palette <- c('#e86e41','#d9b53f','#9857ba','#57ba64','#57b7ba')
p <- plot_ly(x = umap_1, y = umap_2, z =umap_3,
color = b$clust,
colors = palette,
marker = list(size = 1, width=1),
text = b$clust,
hoveringinfo = 'text'# controls size of points
)
I would like to add to this scatter plot other points with other size and color.
I thought first about adding a fifth column to my dataset and using this in marker with something like ifelse(b$V4=='something'], size=1, size=5)
but it doesn't work.
So i thought about adding element using %>% like :
p <- plot_ly(x = umap_1, y = umap_2, z =umap_3,
color = b$clust,
colors = palette,
marker = list(size = 1, width=1),
text = b$clust,
hoveringinfo = 'text'
)
p <- p >%> add_something(x,y,z, marker = list(size = 5, width=1))
But there is no function to add scatter point to a 3D plot.
Is there a way to do so ?
You can add several traces as in the example below.
fig <- plot_ly(data = df, x = ~x, y = ~y, z = ~z) %>%
add_trace(
data = df2
, x = ~x
, y = ~y
, z = ~z
, color= ~group
, mode = "markers"
, type = "scatter3d"
, marker = list(size = 5))
See for a related example: Mixing surface and scatterplot in a single 3D plot
In python, you can do:
fig = px.line_3d(...)
fig.add_scatter3d(...)

Grouping not respected when using ggplotly to group boxplots

I was trying the following code in order to get a graph of boxplots with ggplot2 which are grouped according to different categories:
category_1 <- rep(LETTERS[1:4], each = 20)
value <- rnorm(length(category_1), mean = 200, sd = 20)
category_2 <- rep(as.factor(c("Good", "Medium", "Bad")), length.out = length(category_1))
category_3 <- rep(as.factor(c("Bright", "Dark")), length.out = length(category_1))
df <- data.frame( category_1, value, category_2, category_3)
p <- ggplot(df, aes(x = category_1, y = value, color = category_2, shape = category_3)) +
geom_boxplot(alpha = 0.5) +
geom_point(position=position_jitterdodge(), alpha=0.7)
p
I'm still too noob in stackoverflow to post images, but this is the result I want.
However, when I try to convert it to plotly using
pp <- ggplotly(p)
pp
the last 2 grouping layers (shape and color) are "ignored" and all the boxplots are plotted on top of each other, only respecting the x-axis grouping specified in aes(x = category_1, ...) as you can see here.
How can I avoid this problem? Thanks for your time.
EDIT
I've tried using plotly syntax directly and I get a similar result using the following code:
pp <- plot_ly(df, x = ~category_1, y = ~value, color = ~category_2,
mode = "markers", symbol = ~category_3, type = "box", boxpoints = "all") %>%
layout(boxmode = "group")
pp
Here the result. I said similar because plotly forces the dots to be next to, and not on top of the boxplot, which is not exactly what I wanted.
I guess the question is "solved". Although, I'm still curious if there is an explanation for the problem above. Thanks again!
I think this will solve your issue.
p <- ggplot(df, aes(x = category_1, y = value, color = category_2, shape = category_3)) +
geom_boxplot(alpha = 0.5) +
geom_point(position=position_jitterdodge(), alpha=0.7)
p %>%
ggplotly() %>%
layout(boxmode = "group")
Cheers.

Create a filled area line plot with plotly

I want to create a basic filled area plot with plotly using this dataset:
week<-c(2,1,3)
pts<-c(10,20,30)
wex<-data.frame(week,pts)
The x-axis should contain the week which as you can see may not be in order in the dataset but MUST be in order in the x-axis of the plot. The y axis should contain the pts.
For some reason I take nothing as a result but no error seems to exist.
library(plotly)
week<-c(2,1,3)
pts<-c(10,20,30)
wex<-data.frame(week,pts)
wex$week <- factor(wex$week, levels = wex[["week"]])
p <- plot_ly(x = ~wex$week, y = ~wex$pts,
type = 'scatter', mode = 'lines',fill = 'tozeroy')
p
Values on x axis need to be numeric (see example) and ordered.
wex <- wex[order(wex$week), ]
# wex$week <- factor(wex$week, levels = wex[["week"]])
plot_ly(x = ~wex$week, y = ~wex$pts, type = 'scatter', mode = 'lines',
fill = 'tozeroy')
This will work if you want to keep the x-axis, but it's not a pure plot_ly answer:
p <- ggplot(wex, aes(x = week, y = pts)) +
geom_point() +
geom_line() +
geom_ribbon(aes(ymin = 0, ymax = pts), fill = "blue", alpha = .6, group = 1)
g <- ggplotly(p)
g

plotly not creating linear trend line

In creating a trend line for a scatter plot, I am using add_trace to add a linear trend line.
When the data only has one "series" of data, i.e. there is only one group of coordinates, the code below works fine. However, when I introduce a number of series, the "trend line" looks like this:
Here is the relevant part of the code:
p <- plot_ly(filteredFull(), x=Relative.Time.Progress, y=cumul.ans.keystroke,
mode='markers', color=KeystrokeRate, size=KeystrokeRate,
marker=list(sizeref=100), type='scatter',
hoverinfo='text', text=paste("token: ",Token, "Keystrokes: ",
KeystrokeCount)) %>%
layout(
xaxis=list(range=c(0,1)),
yaxis=list(range=c(0,max(filteredFull()$cumul.ans.keystroke)))
)
lm.all <- lm(cumul.ans.keystroke ~ Relative.Time.Progress,
data=df)
observe(print(summary(lm.all)))
p <- add_trace(p, y=fitted(lm.all), x=Relative.Time.Progress,
mode='lines') %>%
layout(
xaxis= list(range = c(0,1))
)
p
I can add more code, or try to make a minimal working example, if necessary. However, I'm hoping that this is a famililar problem that is obvious from the code.
I think you'll need to specify the data = ... argument in add_trace(p, y=fitted(lm.all), x=Relative.Time.Progress, mode='lines').
The first trace seems to be a subset but the second trace uses the regression fitted values which are obtained by fitting a regression model to the entire dataset.
There might be a mismatch between Relative.Time.Progress in filteredFull() vs df.
Here's an example. Hopefully helps...
library(plotly)
df <- diamonds[sample(1:nrow(diamonds), size = 500),]
fit <- lm(price ~ carat, data = df)
df1 <- df %>% filter(cut == "Ideal")
plot_ly(df1, x = carat, y = price, mode = "markers") %>%
add_trace(x = carat, y = fitted(fit), mode = "lines")
plot_ly(df1, x = carat, y = price, mode = "markers") %>%
add_trace(data = df, x = carat, y = fitted(fit), mode = "lines")
It changed now a bit, the following code should work fine:
df <- diamonds[sample(1:nrow(diamonds), size = 500),]
fit <- lm(price ~ carat, data = df)
df1 <- df %>% filter(cut == "Ideal")
plot_ly() %>%
add_trace(data = df1, x = ~carat, y = ~price, mode = "markers") %>%
add_trace(data = df, x = ~carat, y = fitted(fit), mode = "lines")
Need to start with empty plotly and add traces.

Resources