Reputation: 163
I am trying to make one plot consisting of multiple plots. These plots are made with ggplot (library("ggplot2")) inside a loop and saved into two lists. First list has the plots which should be on the left side of the multiplot and second list has the plots for the right side. In general, I got it working for some other six plots which are made each seperately (plot1,...,plot6).
multiplot(p1,p2,p3,p4,p5,p6,cols=2)
worked as well as
plotlista <- list(p1,p2,p3)
plotlistb <- list(p4,p5,p6)
multiplot(c(plotlista,plotlistb),cols=2)
But when I want to multiplot the plots made inside the loop, the multiplot afterwards does not work. Please see some code below...
plotlist1 <- list()
plotlist2 <- list()
for(a in types){
... some data handling ...
p5 <- ggplot(df.1, aes(xmin = wm, xmax = w, ymin = 0, ymax = height, fill = names(aaa))) +
geom_rect(color="darkgrey")+ geom_text(aes(x = (wm+w)/2, y = 150 , label = names(aaa), size=16, angle=90)) +
theme_bw() + labs(x = "cummulated", y = "costs") +
theme(axis.ticks = element_blank(), legend.position = "none") + ylim(-150, 400) + xlim(-150, 1000) +
scale_fill_manual(values=aaa) +
ggtitle(paste("type ",a,sep="- ") ) + theme(plot.title = element_text(lineheight=.8, face="bold"))
plotlist1[[which(types==a)]] <- p5
... some data handling ...
p55 <- ggplot(df.1, aes(xmin = wm, xmax = w, ymin = 0, ymax = height, fill = names(aaa))) +
geom_rect(color="darkgrey")+ geom_text(aes(x = (wm+w)/2, y = 150 , label = names(aaa), size=16, angle=90)) +
theme_bw() + labs(x = "cummulated", y = "costs") +
theme(axis.ticks = element_blank(), legend.position = "none") + ylim(-150, 400) + xlim(-150, 1000) +
scale_fill_manual(values=aaa) +
ggtitle(paste("type ",a,sep="- ") ) + theme(plot.title = element_text(lineheight=.8, face="bold"))
plotlist2[[which(types==a)]] <- p55
filepath <- paste("byxxxx",Agglevel,a,".jpg",sep="")
jpeg(filename = filepath , width = 750, height = 750)
multiplot(plotlist=list(p5,p55),cols=2)
dev.off()
}
multiplot(plotlist=c(plotlist1,plotlist2),cols=2)
The following error occurs:
Error: Aesthetics must either be length one, or the same length as the dataProblems:names(aaa)
There are 13 runs through the loop, but even when I cut the runs to two the same error occurs.
The following lines inside the loop also worked fine for each run and saved the jpeg correctly.
filepath <- paste("byxxxx",Agglevel,a,".jpg",sep="")
jpeg(filename = filepath , width = 750, height = 750)
multiplot(plotlist=list(p5,p55),cols=2)
dev.off()
It is also possible to multiplot the plots p5
and p55
as well as listplot1[[13]]
and listplot2[[13]]
which are made in the last run through the loop with:
multiplot(plotlist=list(p5,p55),cols=2)
multiplot(plotlist=c(plotlist1[13],plotlist2[13]),cols=2)
The multiplot function comes from http://www.cookbook-r.com/Graphs/Multiple_graphs_on_one_page_%28ggplot2%29/:
# Multiple plot function
#
# ggplot objects can be passed in ..., or to plotlist (as a list of ggplot objects)
# - cols: Number of columns in layout
# - layout: A matrix specifying the layout. If present, 'cols' is ignored.
#
# If the layout is something like matrix(c(1,2,3,3), nrow=2, byrow=TRUE),
# then plot 1 will go in the upper left, 2 will go in the upper right, and
# 3 will go all the way across the bottom.
#
multiplot <- function(..., plotlist=NULL, file, cols=1, layout=NULL) {
library(grid)
# Make a list from the ... arguments and plotlist
plots <- c(list(...), plotlist)
numPlots = length(plots)
# If layout is NULL, then use 'cols' to determine layout
if (is.null(layout)) {
# Make the panel
# ncol: Number of columns of plots
# nrow: Number of rows needed, calculated from # of cols
layout <- matrix(seq(1, cols * ceiling(numPlots/cols)),
ncol = cols, nrow = ceiling(numPlots/cols))
}
if (numPlots==1) {
print(plots[[1]])
} else {
# Set up the page
grid.newpage()
pushViewport(viewport(layout = grid.layout(nrow(layout), ncol(layout))))
# Make each plot, in the correct location
for (i in 1:numPlots) {
# Get the i,j matrix positions of the regions that contain this subplot
matchidx <- as.data.frame(which(layout == i, arr.ind = TRUE))
print(plots[[i]], vp = viewport(layout.pos.row = matchidx$row,
layout.pos.col = matchidx$col))
}
}
}
Is there a problem with saving the ggplot objects inside the loop?
Adding an reproducible example:
## example
library("ggplot2")
library(grid)
# Multiple plot function
#
# ggplot objects can be passed in ..., or to plotlist (as a list of ggplot objects)
# - cols: Number of columns in layout
# - layout: A matrix specifying the layout. If present, 'cols' is ignored.
#
# If the layout is something like matrix(c(1,2,3,3), nrow=2, byrow=TRUE),
# then plot 1 will go in the upper left, 2 will go in the upper right, and
# 3 will go all the way across the bottom.
#
multiplot <- function(..., plotlist=NULL, file, cols=1, layout=NULL) {
# Make a list from the ... arguments and plotlist
plots <- c(list(...), plotlist)
numPlots = length(plots)
# If layout is NULL, then use 'cols' to determine layout
if (is.null(layout)) {
# Make the panel
# ncol: Number of columns of plots
# nrow: Number of rows needed, calculated from # of cols
layout <- matrix(seq(1, cols * ceiling(numPlots/cols)),
ncol = cols, nrow = ceiling(numPlots/cols))
}
if (numPlots==1) {
print(plots[[1]])
} else {
# Set up the page
grid.newpage()
pushViewport(viewport(layout = grid.layout(nrow(layout), ncol(layout))))
# Make each plot, in the correct location
for (i in 1:numPlots) {
# Get the i,j matrix positions of the regions that contain this subplot
matchidx <- as.data.frame(which(layout == i, arr.ind = TRUE))
print(plots[[i]], vp = viewport(layout.pos.row = matchidx$row,
layout.pos.col = matchidx$col))
}
}
}
example1 <- read.table(text="x height w wm color colorcode
A 74.87091 0 0.8477582 PT E6F598FF
B 75.7462 0.8477582 2.7575227 ES 51AAAEFF
C 154.96351 2.7575227 5.0641208 IT 9DD7A4FF
D 218.2934 5.0641208 5.582455 EL 3C93B8FF",header=TRUE)
example1$colorcode <- paste("#",example1$colorcode,sep="")
#example2 <- example1[-1,]
example3 <- read.table(text=" x height w wm color colorcode
E 23.31359 0 2.619406 BG B41947FF
F 28.60724 2.619406 3.282477 HU FEE08BFF
G 33.30486 3.282477 3.292582 CY DB474CFF
H 34.40072 3.292582 24.22946 PL FDCC7AFF
I 42.86401 24.22946 26.141007 RO 9E0142FF
C 45.83487 26.141007 47.13058 IT 9DD7A4FF
J 46.48877 47.13058 48.152381 SI FDB869FF
K 47.74536 48.152381 51.518293 CZ FEEC9FFF
L 50.12508 51.518293 278.176833 FR 66C2A5FF
M 72.17257 278.176833 284.513883 DK 4C65ACFF
N 73.16484 284.513883 285.837194 SK FBA15BFF
O 75.94599 285.837194 314.661756 AT CEEB9CFF
P 77.39849 314.661756 339.818609 BL 5E4FA2FF
D 77.87686 339.818609 340.366524 EL 3C93B8FF
Q 78.60072 340.366524 623.890373 DE 3A7CB7FF
R 80.39367 623.890373 624.871331 EE F7874FFF
S 83.13369 624.871331 626.13241 LV E75A47FF
T 87.46645 626.13241 628.725496 LT F46D43FF
U 89.35913 628.725496 629.62701 FI FAFDB7FF
V 94.46328 629.62701 766.334365 NL B6E1A1FF
W 106.02335 766.334365 871.746899 IR 81CCA4FF
X 107.62544 871.746899 881.874454 SE F0F9A7FF
B 112.60728 881.874454 892.735907 ES 51AAAEFF
Y 127.36419 892.735907 991.546621 UK FEF8B4FF
Z 342.85699 991.546621 997.847212 PT E6F598FF",header=TRUE)
example3$colorcode <- paste("#",example3$colorcode,sep="")
#example4 <- example3[-1,]
example1[,c("wm","w","height")] <- example1[,c("wm","w","height")] + 10
#example2[,c("wm","w","height")] <- example2[,c("wm","w","height")] + 10
example3[,c("wm","w","height")] <- example3[,c("wm","w","height")] + 10
#example4[,c("wm","w","height")] <- example4[,c("wm","w","height")] + 10
example.data <- list(example3,example1)
listplota <- list()
listplotb <- list()
AxisX_max <- 1100
AxisY_max <- 360
AxisX_min <- 0
AxisY_min <- 0
for(i in 1:2){
df.1 <- example.data[[i]]
p5 <- ggplot(df.1, aes(xmin = wm, xmax = w, ymin = 0, ymax = height, fill = x)) +
geom_rect(color="darkgrey")+ geom_text(aes(x = (wm+w)/2, y = 150 , label = x, size=16, angle=90)) +
theme_bw() + labs(x = "cummulated", y = "costs") +
theme(axis.ticks = element_blank(), legend.position = "none") +
#ylim(-150, 400) + xlim(-150, 1000) +
ylim(max(-150,AxisY_min), min(400,AxisY_max)) + xlim(AxisX_min, AxisX_max) +
scale_fill_manual(values=df.1$colorcode) +
ggtitle(paste("type ",i,sep="- ") ) + theme(plot.title = element_text(lineheight=.8, face="bold"))
listplota[[i]] <- p5
p55 <- ggplot(df.1, aes(xmin = wm, xmax = w, ymin = 0, ymax = height, fill = x)) +
geom_rect(color="darkgrey")+ geom_text(aes(x = (wm+w)/2, y = 150 , label = x, size=16, angle=90)) +
theme_bw() + labs(x = "cummulated", y = "costs") +
theme(axis.ticks = element_blank(), legend.position = "none") +
#ylim(-150, 400) + xlim(-150, 1000) +
ylim(max(-150,AxisY_min), min(400,AxisY_max)) + xlim(AxisX_min, AxisX_max) +
scale_fill_manual(values=df.1$colorcode) +
ggtitle(paste("type ",i,sep="- ") ) + theme(plot.title = element_text(lineheight=.8, face="bold"))
listplotb[[i]] <- p55
}
multiplot(plotlist=c(listplota,listplotb),cols=2)
Error: Insufficient values in manual scale. 25 needed but only 4 provided.
Upvotes: 1
Views: 1208
Reputation: 163
Now it is working... Thanks @Heroka
## example
library("ggplot2")
library(grid)
# Multiple plot function
#
# ggplot objects can be passed in ..., or to plotlist (as a list of ggplot objects)
# - cols: Number of columns in layout
# - layout: A matrix specifying the layout. If present, 'cols' is ignored.
#
# If the layout is something like matrix(c(1,2,3,3), nrow=2, byrow=TRUE),
# then plot 1 will go in the upper left, 2 will go in the upper right, and
# 3 will go all the way across the bottom.
#
multiplot <- function(..., plotlist=NULL, file, cols=1, layout=NULL) {
# Make a list from the ... arguments and plotlist
plots <- c(list(...), plotlist)
numPlots = length(plots)
# If layout is NULL, then use 'cols' to determine layout
if (is.null(layout)) {
# Make the panel
# ncol: Number of columns of plots
# nrow: Number of rows needed, calculated from # of cols
layout <- matrix(seq(1, cols * ceiling(numPlots/cols)),
ncol = cols, nrow = ceiling(numPlots/cols))
}
if (numPlots==1) {
print(plots[[1]])
} else {
# Set up the page
grid.newpage()
pushViewport(viewport(layout = grid.layout(nrow(layout), ncol(layout))))
# Make each plot, in the correct location
for (i in 1:numPlots) {
# Get the i,j matrix positions of the regions that contain this subplot
matchidx <- as.data.frame(which(layout == i, arr.ind = TRUE))
print(plots[[i]], vp = viewport(layout.pos.row = matchidx$row,
layout.pos.col = matchidx$col))
}
}
}
example1 <- read.table(text="x height w wm color colorcode
A 74.87091 0 0.8477582 PT E6F598FF
B 75.7462 0.8477582 2.7575227 ES 51AAAEFF
C 154.96351 2.7575227 5.0641208 IT 9DD7A4FF
D 218.2934 5.0641208 5.582455 EL 3C93B8FF",header=TRUE)
example1$colorcode <- paste("#",example1$colorcode,sep="")
#example2 <- example1[-1,]
example3 <- read.table(text=" x height w wm color colorcode
E 23.31359 0 2.619406 BG B41947FF
F 28.60724 2.619406 3.282477 HU FEE08BFF
G 33.30486 3.282477 3.292582 CY DB474CFF
H 34.40072 3.292582 24.22946 PL FDCC7AFF
I 42.86401 24.22946 26.141007 RO 9E0142FF
C 45.83487 26.141007 47.13058 IT 9DD7A4FF
J 46.48877 47.13058 48.152381 SI FDB869FF
K 47.74536 48.152381 51.518293 CZ FEEC9FFF
L 50.12508 51.518293 278.176833 FR 66C2A5FF
M 72.17257 278.176833 284.513883 DK 4C65ACFF
N 73.16484 284.513883 285.837194 SK FBA15BFF
O 75.94599 285.837194 314.661756 AT CEEB9CFF
P 77.39849 314.661756 339.818609 BL 5E4FA2FF
D 77.87686 339.818609 340.366524 EL 3C93B8FF
Q 78.60072 340.366524 623.890373 DE 3A7CB7FF
R 80.39367 623.890373 624.871331 EE F7874FFF
S 83.13369 624.871331 626.13241 LV E75A47FF
T 87.46645 626.13241 628.725496 LT F46D43FF
U 89.35913 628.725496 629.62701 FI FAFDB7FF
V 94.46328 629.62701 766.334365 NL B6E1A1FF
W 106.02335 766.334365 871.746899 IR 81CCA4FF
X 107.62544 871.746899 881.874454 SE F0F9A7FF
B 112.60728 881.874454 892.735907 ES 51AAAEFF
Y 127.36419 892.735907 991.546621 UK FEF8B4FF
Z 342.85699 991.546621 997.847212 PT E6F598FF",header=TRUE)
example3$colorcode <- paste("#",example3$colorcode,sep="")
#example4 <- example3[-1,]
example1[,c("wm","w","height")] <- example1[,c("wm","w","height")] + 10
#example2[,c("wm","w","height")] <- example2[,c("wm","w","height")] + 10
example3[,c("wm","w","height")] <- example3[,c("wm","w","height")] + 10
#example4[,c("wm","w","height")] <- example4[,c("wm","w","height")] + 10
example.data <- list(example3,example1)
listplota <- list()
listplotb <- list()
AxisX_max <- 1100
AxisY_max <- 360
AxisX_min <- 0
AxisY_min <- 0
# color <- data.frame(example3$colorcode)
# color <- color$colorcode
# rownames(color) <- example3$x
for(i in 1:2){
df.1 <- example.data[[i]]
p5 <- ggplot(df.1, aes(xmin = wm, xmax = w, ymin = 0, ymax = height, fill = colorcode)) +
geom_rect(color="darkgrey")+ geom_text(aes(x = (wm+w)/2, y = 150 , label = x, size=16, angle=90)) +
theme_bw() + labs(x = "cummulated", y = "costs") +
theme(axis.ticks = element_blank(), legend.position = "none") +
#ylim(-150, 400) + xlim(-150, 1000) +
ylim(max(-150,AxisY_min), min(400,AxisY_max)) + xlim(AxisX_min, AxisX_max) +
#scale_fill_manual(values=df.1$colorcode) +
scale_fill_identity() +
ggtitle(paste("type ",i,sep="- ") ) + theme(plot.title = element_text(lineheight=.8, face="bold"))
listplota[[i]] <- p5
p55 <- ggplot(df.1, aes(xmin = wm, xmax = w, ymin = 0, ymax = height, fill = colorcode)) +
geom_rect(color="darkgrey")+ geom_text(aes(x = (wm+w)/2, y = 150 , label = x, size=16, angle=90)) +
theme_bw() + labs(x = "cummulated", y = "costs") +
theme(axis.ticks = element_blank(), legend.position = "none") +
#ylim(-150, 400) + xlim(-150, 1000) +
ylim(max(-150,AxisY_min), min(400,AxisY_max)) + xlim(AxisX_min, AxisX_max) +
#scale_fill_manual(values=df.1$colorcode) +
scale_fill_identity() +
ggtitle(paste("type ",i,sep="- ") ) + theme(plot.title = element_text(lineheight=.8, face="bold"))
listplotb[[i]] <- p55
}
multiplot(plotlist=c(listplota,listplotb),cols=2)
Upvotes: 0