Control legend in ggplotly when using subplot - r

I use the R plotly package and the functions ggplotly and subplot to create an interactive plot consisting of multiple individually interactive ggplot2 plots. Some of the plots share the same grouping variables.
col <- factor(rep(c(1, 2), 5))
fill <- factor(c(rep("a", 5), rep("b", 5)))
x1 <- x2 <- y1 <- y2 <- 1:10
x3 <- y3 <- 11:20
d1 <- dplyr::tibble(x1 = x1, y1 = y1, col = col)
d2 <- dplyr::tibble(x2 = x2, y2 = y2, col = col, fill = fill)
d3 <- dplyr::tibble(x3 = x3, y3 = y3, col = col)
g1 <-
ggplot2::ggplot(d1) +
ggplot2::geom_point(ggplot2::aes(x = x1, y = y1, col = col))
g2 <-
ggplot2::ggplot(d2) +
ggplot2::geom_point(ggplot2::aes(x = x2, y = y2, col = col, fill = fill)) +
ggplot2::scale_fill_manual(values = c("red","green"))
g3 <-
ggplot2::ggplot(d3) +
ggplot2::geom_point(ggplot2::aes(x = x3, y = y3, col = col))
plotly::subplot(plotly::ggplotly(g1), plotly::ggplotly(g2), plotly::ggplotly(g3))
1) How can I remove the duplicated "col" labels in the interactive plotly legend?
2) How can I remove the legend for "fill", but keep the legend for "col"?
EDIT: I know about the following "dirty" solution, which is to manually disable the legend:
t <-
plotly::subplot(plotly::ggplotly(g1), plotly::ggplotly(g2), plotly::ggplotly(g3))
t$x$data[[1]]$showlegend <- FALSE
t$x$data[[2]]$showlegend <- FALSE
t$x$data[[3]]$showlegend <- FALSE
t$x$data[[4]]$showlegend <- FALSE
However, this requires me to know the positions of the list elements in advance, which is why I am looking for a more general solution.

Another way to manually remove the unwanted legends is to use style(). In your example, lt <- t %>% style(t, showlegend = FALSE, traces = 3:n), where n<-8 is defined before, will suppress the unwanted legends.

Related

How to put plotmath labels in ggplot facets

We often want individual regression equations in ggplot facets. The best way to do this is build the labels in a dataframe and then add them manually. But what if the labels contain plotmath, e.g., superscripts?
Here is a way to do it. The plotmath is converted to a string and then parsed by ggplot. The test_eqn function is taken from another Stackoverflow post, I'll link it when I find it again. Sorry about that.
library(ggplot2)
library(dplyr)
test_eqn <- function(y, x){
m <- lm(log(y) ~ log(x)) # fit y = a * x ^ b in log space
p <- exp(predict(m)) # model prediction of y
eq <- substitute(expression(Y==a~X^~b),
list(
a = format(unname(exp(coef(m)[1])), digits = 3),
b = format(unname(coef(m)[2]), digits = 3)
))
list(eq = as.character(eq)[2], pred = p)
}
set.seed(123)
x <- runif(20)
y <- runif(20)
test_eqn(x,y)$eq
#> [1] "Y == \"0.57\" ~ X^~\"0.413\""
data <- data.frame(x = x,
y = y,
f = sample(c("A","B"), 20, replace = TRUE)) %>%
group_by(f) %>%
mutate(
label = test_eqn(y,x)$eq, # add label
labelx = mean(x),
labely = mean(y),
pred = test_eqn(y,x)$pred # add prediction
)
# plot fits (use slice(1) to avoid multiple copies of labels)
ggplot(data) +
geom_point(aes(x = x, y = y)) +
geom_line(aes(x = x, y = pred), colour = "red") +
geom_text(data = slice(data, 1), aes(x = labelx, y = labely, label = label), parse = TRUE) +
facet_wrap("f")
Created on 2021-10-20 by the reprex package (v2.0.1)

List of plots generated in ggplot2 using scale_color_gradientn have wrong coloring

I'm attempting to use library(scales) and scale_color_gradientn() to create a custom mapping of colors to a continuous variable, in an attempt to limit the effect of outliers on the coloring of my plot. This works for a single plot, but does not work when I use a loop to generate several plots and store them in a list.
Here is a minimal working example:
library(ggplot2)
library(scales)
data1 <- as.data.frame(cbind(x = rnorm(100),
y = rnorm(100),
v1 = rnorm(100, mean = 2, sd = 1),
v2 = rnorm(100, mean = -2, sd = 1)))
#add outliers
data1[1,"v1"] <- 200
data1[2,"v1"] <- -200
data1[1,"v2"] <- 50
data1[2,"v2"] <- -50
#define color palette
cols <- colorRampPalette(c("#3540FF","black","#FF3535"))(n = 100)
#simple color scale
col2 <- scale_color_gradient2(low = "#3540FF",
mid = "black",
high = "#FF3535"
)
#outlier-adjusted color scale
{
aa <- min(data1$v1)
bb <- quantile(data1$v1, 0.05)
cc <- quantile(data1$v1, 0.95)
dd <- max(data1$v1)
coln <- scale_color_gradientn(colors = cols[c(1,5,95,100)],
values = rescale(c(aa,bb,cc,dd),
limits = c(aa,dd))
)
}
Plots:
1. Plot with simple scales - outliers cause scales to stretch out.
ggplot(data1, aes(x = x, y = y, color = v1))+
geom_point()+
col2
2. Plot with outlier-adjusted scales - correct color scaling.
ggplot(data1, aes(x = x, y = y, color = v1))+
geom_point()+
coln
3. The scales for v1 do not work for v2 as the data is different.
ggplot(data1, aes(x = x, y = y, color = v2))+
geom_point()+
coln
#loop to produce list of plots each with own scale
{
plots <- list()
k <- 1
for (i in c("v1","v2")){
aa <- min(data1[,i])
bb <- quantile(data1[,i],0.05)
cc <- quantile(data1[,i], 0.95)
dd <- max(data1[,i])
colm <- scale_color_gradientn(colors = cols[c(1,5,95,100)],
values = rescale(c(aa,bb,cc,dd),
limits = c(aa,dd)))
plots[[k]] <- ggplot(data1, aes_string(x = "x",
y = "y",
color = i
))+
geom_point()+
colm
k <- k + 1
}
}
4. First plot has the wrong scales.
plots[[1]]
5. Second plot has the correct scales.
plots[[2]]
So I'm guessing this has something to do with the scale_color_gradientn() function being called when the plotting takes place, rather than within the loop.
If anyone can help with this, it'd be much appreciated. In base R I would bin the continuous data and assigning hex colors into a vector used for fill color, but I'm unsure how I can apply this within ggplot.
You need to use a closure (function with associated environment):
{
plots <- list()
k <- 1
for (i in c("v1", "v2")){
colm <- function() {
aa <- min(data1[, i])
bb <- quantile(data1[, i], 0.05)
cc <- quantile(data1[, i], 0.95)
dd <- max(data1[, i])
scale_color_gradientn(colors = cols[c(1, 5, 95, 100)],
values = rescale(c(aa, bb, cc, dd),
limits = c(aa, dd)))
}
plots[[k]] <- ggplot(data1, aes_string(x = "x",
y = "y",
color = i)) +
geom_point() +
colm()
k <- k + 1
}
}
plots[[1]]
plots[[2]]

Plot multiple curves in the same graph in R

library(ROCR);
lig <- unique(read.table("ligands.txt")[,1]);
dec <- unique(read.table("decoys.txt")[,1]);
uniqRes <- read.table("file1.txt",header=T);
colnames(uniqRes)[1]="LigandName";
uniqRes$IsActive <- as.numeric(uniqRes$LigandName %in% lig)
predTOTALuq <- prediction(uniqRes$TOTAL*-1, uniqRes$IsActive)
perfTOTALuq <- performance(predTOTALuq, 'tpr','fpr')
jpeg("hivpr_Rinter_ROC.jpg")
plot(perfTOTALuq,main="hivpr - ROC Curves",col="blue")
abline(0,1,col="grey")
dev.off()
here is the code for plotting single curve by taking data from single file.
i want to plot 3 curves in same plot by taking data from three different files i.e. file 1, file 2, file 3
please help me to do so
you can add abline or curve directly.
df1 <- data.frame(x = 1:10, y = 1:10)
df2 <- data.frame(x = 1:13, y = 2:14)
df3 <- data.frame(x = 6:10, y = 2:6)
lx <- range(c(df1$x, df2$x, df3$x))
ly <- range(c(df1$y, df2$y, df3$y))
plot(df1, main = "hivpr - ROC Curves", xlim = lx, ylim = ly, col = "blue")
abline(0, 1, col = "blue")
points(df2, col = 'red3')
points(df3, col = 'yellow')

How to add inside legend for a combined plot in ggplot2

I have the following df and ggplot2 code to make a scatter plot but failed to add a legend inside the plot. Thanks :)
x1 = 1:5
x2 = 6:10
y1 = 3:7
y2 = 2:6
df <- data.frame(x1, y1, x2, y2)
ggplot(df) + geom_point(aes(x=x1, y = y1),col='red') + geom_point(aes(x = x2, y = y2),col='black')
Try:
x1 = 1:5
x2 = 6:10
y1 = 3:7
y2 = 2:6
df <- data.frame(x1, y1, x2, y2)
ggplot(df) + geom_point(aes(x=x1, y = y1, col = "1")) +
geom_point(aes(x = x2, y = y2, col = "2")) + scale_colour_manual(values = c("red", "black"))
In the above code, by putting col = "1" and col = "2" inside the aesthetics aes(), you're telling ggplot to add a colour dimension to the plot (and not just colour the points "red" and "black"). Hence, you see a legend now. Then, by setting colour equal to "1" and "2", you're saying to use these as labels. scale_colour_manual allows you to change these colours to red and black, instead of the red and blue" default.
The same applies anytime you want to add any dimension to the plot. But, instead of using col and scale_colour_manual, you would use an alternative such as shape and scale_shape_manual.
Here is a way of long format data input
#data into long format
x1 = 1:5
x2 = 6:10
y1 = 3:7
y2 = 2:6
df <- data.frame(x=c(x1, x2), y=c(y1, y2), group=rep(c("x1", "x2"), c(5, 5)))
#plot it
library(ggplot2)
ggplot(df) +
geom_point(aes(x=x, y = y, colour=group))+
scale_colour_manual(values=c("red", "black"))

lattice plot only lines with positive slope

Is there a easy and efficient way to define a function like panel.xyplot (or rather panel.lines) that connects only two point (x1,y1) and (x2,y2) if x1 <= x2 and y1 <= y2? (Ideally, with all other properties are retained by label.xyplot(...))
I asked the same question a view month ago and the solution is great:
lattice, connect points only if the connection has a positive slope
Now it would be fine to have a real panel.xyplot like function so that I can use my own groups. It should work and plot like below, except the crossed lines.
I welcome suggestions.
I'm not sure I understand what you're after, but if I do, then I think this should work for any given group:
library(dplyr)
set.seed(1)
dat <- data.frame(x=1:10,y=sample(1:10))
dat <- mutate(dat, x0 = x, y0 = y, x1 = lead(x), y1 = lead(y), slope = (x1 - x0)/(y1 - y0))
with(dat, plot(x, y))
with(dat[1:nrow(dat) - 1,], segments(x0 = x0, y0 = y0, x1 = x1, y1 = y1,
col = ifelse(slope >= 0, "black", "white"))) # This bit gets makes line-drawing conditional
Here's what I get from that:
And here's a version for grouped data that doesn't depend on lattice:
dat2 <- data.frame(x = rep(seq(10), 10),
y = sample(1:10, size = 100, replace = TRUE),
indx = rep(seq(10), each = 10))
dat2g <- dat2 %>%
group_by(indx) %>%
mutate(., x0 = x, y0 = y, x1 = lead(x), y1 = lead(y), slope = (x1 - x0)/(y1 - y0))
plotit <- function(group) {
require(dplyr)
datsub <- filter(dat2g, indx == group)
with(datsub, plot(x, y, main = group))
with(datsub[1:nrow(datsub) - 1,], segments(x0 = x0, y0 = y0, x1 = x1, y1 = y1, col = ifelse(slope >= 0, "black", "white")))
}
par(mfrow=c( floor(sqrt(max(dat2g$indx))), ceiling(sqrt(max(dat2g$indx)))))
par(mai=c(0.5,0.5,0.5,0.25))
for (i in 1:length(unique(dat2g$indx))) { plotit(i) }
Here's the plot output from that process. It could use fine-tuning, but I think it's what you're after?

Resources