2

I am trying to produce multiple facet plots per group in the data. The problem I am facing is that in my real data sometimes facets per group is over 100 and ggplot2 is trying to put all facets into the one graph. This is not good for the visuality.

Basically, what I want to achieve is that when the certain number of facet windows is exceeded per page (lets say draw 10 window per page) I would like to continue to plot them in the next graphs per group.

The minimal example to make this covers only plotting facets per group.

x <- rnorm(25,0,5)
y <- rnorm(25,5,10)

gr=rep(c(1,2),c(20,5))

set <- c(rep(1:20,1),1:5)

test_data <- data.frame(x,y,set,gr)

utils::View(test_data)

For this minimal example set number for gr 1 is 20. But I want to separate it so to say 10 facets per page.

library(ggplot2)
library(gtable)
library(grid)
library(gridExtra)

plot_list=list()

for (i in unique(test_data$gr)){


plot_sets<- ggplot(data = test_data[test_data$gr==i,], aes(y = y, x=x,fill=factor(set))) +


geom_point(alpha = 0.8,size=8,shape=21,col="black",aes(group=set)) +


  facet_wrap(~set)+


  theme_bw()+
  theme(legend.position = "top",plot.title=element_text(face="bold",colour ="Blue",size=25),
        axis.title.x = element_text(face="bold",size=24), 
        axis.title.y = element_text(face="bold",size=24),
        #axis.text.x = element_blank(),
        axis.text.x = element_text(size = 22 , colour = "black",angle=0,vjust = 0.0, hjust = 0),
        axis.text.y = element_text(size = 22 , colour = "black"),
        strip.text = element_text(size=22, lineheight=1.0,face="bold"),
        strip.background = element_rect(fill="#FFFFCC", colour="black", size=0.1),
        legend.title = element_text(colour="black", size=20,face="bold"),
        legend.text = element_text(colour="black", size=26),
        panel.spacing = unit(0.2, "lines"))+
  labs(fill='set',col="set",x = "x",y="y",title=paste(i,j,"my_Sets",sep="_"))+
  guides(fill = guide_legend(override.aes = list(alpha=1,nrow=1,size=5)))  

  plot_list[[i]]=plot_sets

}

Saving the graphs in .png format

for (i in 1:length(unique(test_data$gr))) {

  file_name = paste(unique(test_data$gr), "my_sets.png", sep="_")

  png(paste("C:/test","/",file_name[i],sep=""), width =6400, height =4400, pointsize = 16, units = 'px', res = 200)

  grid.draw(plot_list[[i]])
  dev.off()
}

I found some relevant posts like

Multiple graphs over multiple pages using ggplot

ggplot2: Plots over Multiple pages

but they use .pdf output and this example is the most relevant one but it works wit .pdf output

@agstudy solution with .pdf output version

tab <- data.frame(Date = rep(seq(as.Date('2013-03-01'),
                       by = 'day', length.out = ii), nn),
                   value = rep(runif(nn, 100, 200)))

tab$Station <- rep(1:nn, each = ii)

*library(gridExtra)
library(ggplot2)
pdf('test.pdf', width=21, height=27)
i = 1
plot = list() 
for (n in unique(tab$Station)){
  ### process data for plotting here ####
  plot[[i]] = ggplot(tab[tab$Station==n,], aes(x=Date,y = value)) +

    geom_line() +
    facet_wrap(~ Station, ncol = 5)

  if (i %% 20 == 0) { ## print 8 plots on a page
    print (do.call(grid.arrange,  plot))
    plot = list() # reset plot 
    i = 0 # reset index
  }
  i = i + 1
}

if (length(plot) != 0) { 
  print (do.call(grid.arrange,  plot))
}
dev.off()
Alexander
  • 4,527
  • 5
  • 51
  • 98
  • any questions regarding to post ? – Alexander May 12 '18 at 00:07
  • 1
    Have you tried `pagination` with [`ggforce`](https://cran.r-project.org/web/packages/ggforce/vignettes/Visual_Guide.html#pagination) yet? – Tung May 12 '18 at 00:08
  • @Tung I haven't heard about that? Could you suggest how to implement to this code ? – Alexander May 12 '18 at 00:39
  • Maybe look at the documentation, have a go yourself, and then post an answer for us if you manage? –  May 12 '18 at 13:25
  • @dash2 yes, I am on it! But anybody has the solution without using `ggforce` or `ggplus` that is also welcome. – Alexander May 13 '18 at 01:40

1 Answers1

2

Here is an example that uses cut() and ggsave().

Let's say you have 80 sets that you would like to facet wrap.

library(tidyverse)

param_n <- 800

data <- data_frame(
  x = rnorm(param_n, 0, 5),
  y = rnorm(param_n, 5, 10),
  group = factor(sample(c(1, 0), param_n, TRUE)),
  set = sample(1:(param_n / 10), param_n, TRUE)
) 

That's way to many for one plot, so you use cut() to split it into ten pages.

data_cut <- 
  data %>%
  mutate(page = cut(set, 10))           # split into 10 groups

You then just loop over each page, filter() out that data, and save a .png file with ggsave().

for (current_page in levels(data_cut$page)) {

  fig <- 
    data_cut %>%
    filter(page == current_page) %>%
    ggplot(
      aes(y = y, x = x,
          colour = group,
          group = set)) +
    facet_wrap(~ set) +
    geom_point() +
    labs(title = paste("Sets", current_page)) +
    theme_bw() +
    theme(legend.position = "bottom")

  ggsave(
    paste0("figures_sets_", current_page, ".png"),
    plot = fig
  )

}

Example output

I simplified your plot make the code more compact.