marrangeGrob apparently displays the charts by column first. How to arrange these charts row-wise instead?
library(gridExtra)
library(tidyr)
library(ggplot2)
dat <- c(2,3,4,5,6,7,8,9,0,1)
time <- 1:10
data <- tibble(dat, time)
p1 <- ggplot(data, aes(x= time, y=dat)) +
geom_point(color="orange")
p2 <- ggplot(data, aes(x= time, y=dat)) +
geom_point(color="blue")
clist <- list(p1,p2)
marrangeGrob(clist, nrow=2, ncol=2, as.table=F )
Using the layout_matrix argument you could specify to add the plots by row (byrow=TRUE):
library(gridExtra)
library(ggplot2)
dat <- c(2,3,4,5,6,7,8,9,0,1)
time <- 1:10
data <- data.frame(dat, time)
p1 <- ggplot(data, aes(x= time, y=dat)) +
geom_point(color="orange")
p2 <- ggplot(data, aes(x= time, y=dat)) +
geom_point(color="blue")
clist <- list(p1,p2)
marrangeGrob(clist, nrow=2, ncol=2,
layout_matrix = matrix(seq_len(4), nrow = 2, byrow = TRUE))
Related
I have an elaborate code to create a series of graphs. I would like to put a vertical line in one of the many graphs I create.
Consider the following simple code:
library(ggplot2)
library(grid)
library(gridExtra)
plots <- list()
for (i in 1:4) {
V1 <- rnorm(1000)
V2 <- seq(1000)
df <- data.frame(V1, V2)
plots[[i]] <- ggplot(df, aes(x= V2, y=V1)) +
geom_point()+
geom_vline(xintercept = 500, color="red")
}
grid.arrange(grobs=plots, nrow=2)
I would like to have the red vertical line for graph 4 but not the others. How would I do this efficiently?
You don't need a for-loop and if-statement for this matter. You can use faceting;
library(ggplot2)
library(grid)
library(gridExtra)
library(dplyr)
set.seed(123) ## set the seed for random numbers to be reproducible
df <- bind_rows(lapply(1:4, function(x)
data.frame(V1=rnorm(1000), V2=seq(1000))), .id = 'facet')
ggplot(df, aes(x= V2, y=V1)) +
geom_point() +
facet_wrap(~facet) +
geom_vline(data=data.frame(xint=500,facet=4), aes(xintercept = xint), color = "red")
just split your plot production and set a condition :)
library(ggplot2)
library(grid)
library(gridExtra)
plots <- list()
for (i in 1:4) {
V1 <- rnorm(1000)
V2 <- seq(1000)
df <- data.frame(V1, V2)
plots[[i]] <- ggplot(df, aes(x= V2, y=V1)) +
geom_point()
if (i == 4) plots[[i]] <- plots[[i]] + geom_vline(xintercept = 500, color="red")
}
grid.arrange(grobs=plots, nrow=2)
I've written a for loop which goes through the columns of a dataframe and produces a graph for each column using ggplot. The problem is the graphs that are output are all the same - they're all graphs of the final column.
The code I've used is:
library(gridExtra)
library(ggplot2)
test1 <- c("Person1","Person2","Person3","Person4","Person5")
test2 <- as.data.frame(c(1,2,3,4,5))
test3 <- as.data.frame(c(2,2,2,2,2))
test4 <- as.data.frame(c(1,3,5,3,1))
test5 <- as.data.frame(c(5,4,3,2,1))
test <- cbind(test1,test2,test3,test4,test5)
rm(test1,test2,test3,test4,test5)
colnames(test) <- c("Person","var1","var2","var3","var4")
for(i in 2:5){
nam <- paste0("graph", i-1)
graph_temp <- ggplot(test, aes(Person, test[,i])) + geom_bar(stat = "identity")
assign(nam, graph_temp)
}
grid.arrange(graph1, graph2, graph3, graph4, ncol=2)
What I'm aiming for is the plot from this code:
library(gridExtra)
library(ggplot2)
test1 <- c("Person1","Person2","Person3","Person4","Person5")
test2 <- as.data.frame(c(1,2,3,4,5))
test3 <- as.data.frame(c(2,2,2,2,2))
test4 <- as.data.frame(c(1,3,5,3,1))
test5 <- as.data.frame(c(5,4,3,2,1))
test <- cbind(test1,test2,test3,test4,test5)
rm(test1,test2,test3,test4,test5)
colnames(test) <- c("Person","var1","var2","var3","var4")
graph1 <- ggplot(test, aes(Person, test[,2])) + geom_bar(stat = "identity")
graph2 <- ggplot(test, aes(Person, test[,3])) + geom_bar(stat = "identity")
graph3 <- ggplot(test, aes(Person, test[,4])) + geom_bar(stat = "identity")
graph4 <- ggplot(test, aes(Person, test[,5])) + geom_bar(stat = "identity")
grid.arrange(graph1, graph2, graph3, graph4, ncol=2)
I know there's a similar question on saving ggplots in a for loop, but I've not managed to get that one to work for this problem.
Here's a more concise way to produce your example:
df <- data.frame(
Person = paste0("Person", 1:5),
var1 = c(1,2,3,4,5),
var2 = c(2,2,2,2,2),
var3 = c(1,3,5,3,1),
var4 = c(5,4,3,2,1)
)
Now, about your plots.
Best solution
Reshape the data frame to 'long' format, and then use facets:
library(ggplot2)
library(tidyr)
gather(df, var, value, -Person) %>%
ggplot(aes(Person, value)) +
geom_bar(stat = "identity") +
facet_wrap(~ var)
Otherwise…
If you gotta stick with a data structure that looks like what you posted, then use aes_string:
library(ggplot2)
library(gridExtra)
g <- lapply(1:4, function(i) {
ggplot(df, aes_string("Person", paste0("var", i))) +
geom_bar(stat = "identity")
})
grid.arrange(grobs = g, ncol = 2)
I want to merge 15 ggplot objects in only one image. All Plots has the same dimensions on x and y.
For example, with 2 objects:
library(ggplot2)
a <- c(1:10)
b <- c(5,4,3,2,1,6,7,8,9,10)
a2 <- c(1:10)
b2 <- c(10:1)
df1 <- as.data.frame(x=a,y=b)
df2 <- as.data.frame(x=a2,y=b2)
p1 <- ggplot(df1,aes(a, b)) + geom_line()
p2 <- ggplot(df2,aes(a2, b2)) + geom_point()
I tried with plot_grid but the result is one image for ggplot object:
library(cowplot)
plot_grid(p1, p2, labels = "AUTO")
Me too with grids but is the same result of above.
My temporal solution is this:
merge <- p1 +geom_point(data=df2,aes(x=a2, y=b2))
But I have 15 ggplot object. It is any way to make something like?
merge <- p1 + p2 +p3 ...+p15
merge
See the pictures please and thanks for your help.
We could use
library(ggplot2)
ggplot() +
geom_line(data = df1, aes(a, b)) +
geom_point(data = df2, aes(a2, b2))
-output
Or if we have already created the objects, reduce it and plot
library(purrr)
p0 <- ggplot()
p1 <- geom_line(data = df1, aes(a, b))
p2 <- geom_point(data = df2, aes(a2, b2))
mget(paste0('p', 0:2)) %>%
reduce(`+`)
I would like to make the y-axis of a bar chart symmetric, so that it's easier to see if positive or negative changes are bigger. Since otherwise this is a bit distorted. I do have working code although it's a bit clumsy and I thought it would be great if I could directly do this in the first ggplot() call. So as to say that ylim directly is symmetrical.
set.seed(123)
my.plot <- ggplot( data = data.table(x = 1:10,
y = rnorm(10,0, 2)), aes(x=x, y=y)) +
geom_bar(stat="identity")
rangepull <- layer_scales(my.plot)$y
newrange <- max(abs(rangepull$range$range))
my.plot +
ylim(newrange*-1, newrange)
What about this :
library(ggplot2)
library(data.table)
set.seed(123)
my.data = data.table(x = 1:10, y = rnorm(10,0, 2))
my.plot <- ggplot(data = my.data)+aes(x=x, y=y) +
geom_bar(stat="identity")+ylim((0-abs(max(my.data$y))),(0+max(abs(my.data$y))))
my.plot
You may want to consider using ceiling:
set.seed(123)
library(ggplot2)
library(data.table)
dT <- data.table(x = 1:10, y = rnorm(10,0, 2))
my.plot <- ggplot(dT, aes(x=x, y=y)) +
geom_bar(stat="identity") +
ylim(-ceiling(max(abs(dT$y))), ceiling(max(abs(dT$y))))
This will give you:
> my.plot
How to change the transparency level of lines in ggplot() diagram (i.e. histogram, line plot, etc.)?
For instance consider the code below:
data <- data.frame(a=rnorm(100), b = rnorm(100,.5,1.2))
data <- melt(data)
colnames(data) <- c("Category", "Intensity")
p <- ggplot(data, aes(x=Intensity))
p <- p + geom_density(aes(color=Category), size=2, alpha=.4)
print(p)
I expected the lines would be transparent (as alpha=.4), but they're not.
Simply following #baptiste's directions,
data <- data.frame(a=rnorm(100), b = rnorm(100,.5,1.2))
data <- melt(data)
colnames(data) <- c("Category", "Intensity")
p <- ggplot(data, aes(x=Intensity))
p + geom_line(aes(color=Category), stat="density", size=2, alpha=0.4)