sebastiann
sebastiann

Reputation: 163

Multiplot does not work sometimes - receiving Error: Aesthetics must either be length one, or the same length as the dataProblems

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

Answers (1)

sebastiann
sebastiann

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

Related Questions