Color R plotly text annotations by gradient - r

I'm trying to make a scatter plot with R plotly, where the points are colored according to a gradient, and on top of that I'd like to text annotate several points, where I'd like the color of the text annotation to follow the same color gradient.
Here's a toy data:
set.seed(1)
df <- data.frame(x=rnorm(100),y=-1*log10(runif(100,0,1)),id=paste0("id",1:100),stringsAsFactors = F)
Here's the colored scatter plot:
library(plotly)
library(dplyr)
scatter.plot <- plot_ly(type='scatter',mode='markers',x=~df$x,y=~df$y,color=~df$y,colors=c("blue","red"),showlegend=FALSE) %>%
layout(xaxis=list(title="Effect Size",zeroline=F),yaxis=list(title="Significance",zeroline=F))
which gives:
Then, I'm trying to add the text annotation.
First, I'm creating the annotation data:
ann.df <- df[sample(100,5,replace = F),]
Then I'm trying this to add the annotation text:
scatter.plot <- scatter.plot %>% layout(annotations = list(x=ann.df$x,y=ann.df$y,text=ann.df$id,xref="x",yref="y",showarrow=T,arrowhead=5,arrowcolor=ann.df$y,ax=20,ay=-40,colors=c("blue","red"),font=list(size=15,color=ann.df$y,colors=c("blue","red"))))
The text is added but not color coded:
Any idea how to get the text colored according df$y with the c("blue","red") gradient ?

I am not sure how to achieve this using plotly. Maybe someone will have a better idea but in the meantime, it might be easier by simply using ggplotly to get what you want.
You could try this:
a <- ggplot(data = df, aes(x = x, y = y, color = y, label1 = x, label2 = y)) +
geom_point() +
theme_bw() +
scale_color_continuous(low = "blue", high = "red")
b <- a +
geom_text(data = ann.df, aes(x=x, y=y, label = id, color = y), hjust = 0, nudge_x = 0.05)
ggplotly(b, tooltip = c("label", "label1", "label2"))

Related

ggplotly: unable to add a frame in PCA score plot in ggplot2

I would like to make a PCA score plot using ggplot2, and then convert the plot into interactive plot using plotly.
What I want to do is to add a frame (not ellipse using stat_ellipse, I know it worked).
My problem is that when I try to use sample name as tooltip in ggplotly, the frame will disappear. I don't know how to fix it.
Below is my code
library(ggplot2)
library(plotly)
library(dplyr)
## Demo data
dat <- iris[1:4]
Group <- iris$Species
## Calculate PCA
df_pca <- prcomp(dat, center = T, scale. = FALSE)
df_pcs <- data.frame(df_pca$x, Group = Group)
percentage <-round(df_pca$sdev^2 / sum(df_pca$sdev^2) * 100, 2)
percentage <-paste(colnames(df_pcs),"(", paste(as.character(percentage), "%", ")", sep = ""))
## Visualization
Sample_Name <- rownames(df_pcs)
p <- ggplot(df_pcs, aes(x = PC1, y = PC2, color = Group, label = Sample_Name)) +
xlab(percentage[1]) +
ylab(percentage[2]) +
geom_point(size = 3)
ggplotly(p, tooltip = "label")
Until here it works! You can see that sample names can be properly shown in the ggplotly plot.
Next I tried to add a frame
## add frame
hull_group <- df_pcs %>%
dplyr::mutate(Sample_Name = Sample_Name) %>%
dplyr::group_by(Group) %>%
dplyr::slice(chull(PC1, PC2))
p2 <- p +
ggplot2::geom_polygon(data = hull_group, aes(fill = Group), alpha = 0.1)
You can see that the static plot still worked! The frame is properly added.
However, when I tried to convert it to plotly interactive plot. The frame disappeared.
ggplotly(p2, tooltip = "label")
Thanks a lot for your help.
It works if you move the data and mapping from the ggplot() call to the geom_point() call:
p2 <- ggplot() +
geom_point(data = df_pcs, mapping = aes(x = PC1, y = PC2, color = Group, label = Sample_Name), size = 3) +
ggplot2::geom_polygon(data = hull_group, aes(x = PC1, y = PC2, fill = Group, group = Group), alpha = 0.2)
ggplotly(p2, tooltip = "label")
You might want to change the order of the geom_point and geom_polygon to make sure that the points are on top of the polygon (this also affects the tooltip location).

Legend for scatter-line graph in ggplot2 (without colour)

very new to this so apologies if there's an obvious answer. I'm trying to add a legend to a scatter-line graph with 2 y variables; i'm aware this can be done using colour, however I ideally want to keep this black and white, and define the variables in the legend by linetype/point instead. Is there any way to do this?
ggplot(birds, aes(distance)) +geom_point(aes(y=individuals_AC)) +geom_point(aes(y=species_AC, shape=17)) +geom_line(aes(y=individuals_AC)) +geom_line(aes(y=species_AC, linetype="dashed")) + scale_shape_identity() + scale_linetype_identity() + theme_classic()
library(tidyverse)
#create some dummy data
df <- tibble(
x = runif(10),
y = runif(10),
type = rep(c("a", "b"), 5)
)
#plot it with a different shape for each type
df %>%
ggplot(aes(x, y, shape = type)) +
geom_point()

ggplotly in r generates different legend from ggplot

I have created the following dataframe in R. The first step is to import the necessary libraries
library(ggplot2)
library(plotly)
library(dplyr)
We create the dataframe here as follows
DF_1<-data.frame("A"= c(1:10))
DF_1$B<-c("D", "C")
DF_1$C<-DF_1$A^2
Next we create a plot as follows
p2<-ggplot(DF_1, aes(x=A, y=C, group=B, fill=B)) +
geom_line(size=.5) + geom_ribbon(data=subset(DF_1),aes(x=A,ymax=C),ymin=0,alpha=0.3) +
scale_fill_manual(name='Legend', values=c("green4", "red"), labels=c("D", "C" ))+theme_bw()
When p2 is rendered, the legend displays correctly. When I nest p2 in ggplotly, the legend changes to two dark lines.
p3<-ggplotly(p2, dynamicTicks = T)
p3= layout(p3, xaxis = list(type = "log"))
Is it possible to retain the legends of p2 in p3. I request someone to take a look
Looks like ggplotly is a more sensible than ggplot2 in how one sets the aesthetics. Simply moving the fill aes from the global setup in ggplot into geom_ribbon gives the correct legend:
library(ggplot2)
library(plotly)
library(dplyr)
DF_1<-data.frame("A"= c(1:10))
DF_1$B<-c("D", "C")
DF_1$C<-DF_1$A^2
ggplot(DF_1, aes(x = A, y = C, group=B)) +
geom_line(size=.5) +
geom_ribbon(aes(x = A, ymin = 0, ymax = C, fill = B), alpha=0.3) +
scale_fill_manual(name='Legend', values=c("green4", "red"), labels=c("D", "C" ))+theme_bw()
ggplotly(dynamicTicks = T) %>%
layout(xaxis = list(type = "log"))

plotting stacked points using ggplot

I have a data frame and I would like to stack the points that have overlaps exactly on top of each other.
here is my example data:
value <- c(1.080251e-04, 1.708859e-01, 1.232473e-05, 4.519876e-03,2.914256e-01, 5.869711e-03, 2.196347e-01,4.124873e-01, 5.914052e-03, 2.305623e-03, 1.439013e-01, 5.407597e-03, 7.530298e-02, 7.746897e-03)
names = letters[1:7]
data <- data.frame(names = rep(names,), group = group, value = value, stringsAsFactors = T)
group <- c(rep("AA", 7) , rep("BB", 7))
I am using the following command:
p <- ggplot(data, aes(x = names, y = "", color = group)) +
geom_point(aes(size = -log(value)), position = "stack")
plot(p)
But the stacked circle outlines out of the grid. I want it close or exactly next to the bottom circle. do you have any idea how I can fix the issue?
Thanks,
The y-axis has no numeric value, so use the group instead. And we don't need the color legend now since the group labels are shown on the y-axis.
ggplot(data, aes(x = names, y = group, color = group)) +
geom_point(aes(size = -log(value))) +
guides(color=FALSE)

Plotly hovering on tiles in the background of a cloud of points - how to show the tooltip?

I'm converting a ggplot2 plot to plotly.
The plot consists of a tile layer (in the background) and a point layer (in the foreground).
I would like to have tooltips when hovering on the tiles.
The code below mostly gets me what I am looking for. When I hover on tiles in "points free" zones, the desired tooltip appears. However, when I hover in areas with a high density of dots, the tooltips do not appear.
I thought that playing with the layerData parameter in the ggplotly call might help, but that was not the case.
library(ggplot2)
library(dplyr)
library(plotly)
set.seed(1)
dat_points <- data.frame(x = rnorm(100), y = rnorm(100))
dat_tiles <- expand.grid(tx = -3:3, ty = -3:3)
dat_tiles$val <- rnorm(nrow(dat_tiles))
dat_tiles$label <- sample(LETTERS[1:5], nrow(dat_tiles), replace = T)
p <- ggplot() +
geom_tile(data = dat_tiles, aes(x = tx, y = ty, fill = val, text = label)) +
geom_point(data = dat_points, aes(x = x, y = y), alpha = .5)
gg <- ggplotly(p, tooltip = "text")
gg
I would like that hovering on high density areas (e.g. 0, 0) would bring up tooltips with the same promptness as in low density areas.
EDIT: added static image of the plot.
You can switch the order of you layers in p and because of how ggplotly() constructs from a ggplot object, you get an identical looking plot, but with the desired tooltip behavior!
p <- ggplot() +
geom_point(data = dat_points, aes(x = x, y = y), alpha = 1) +
geom_tile(data = dat_tiles, aes(x = tx, y = ty, fill = val, text = label))
p # this looks bad
gg <- ggplotly(p, tooltip = "text")
gg # but this looks good!

Resources