# Nicola's function
table = matrix(rnorm(n=120, mean=0.3), 10, 12)
colors=c('white','#fef0d9','#fdd49e','#fdbb84','#fc8d59','#e34a33','#b30000', '#7f0000')
brks=c(-1, 0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 1)
title="Mean Absolute Error"
xtitle="Forecast time (month)"
ytitle="Start date"
xlabels=c("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec")

library(fields)
image.plot(t(table), xaxt = 'n', 
           yaxt = 'n', xlab = xtitle, ylab = ytitle,
      breaks = brks, col = colors)
title(title)
axis(2, at = seq(0, 1, 1/(dim(table)[1]-1)), 1:dim(table)[1], las = 2)
axis(side = 1, at = seq(0, 1, 1/(dim(table)[2]-1)), labels = xlabels)


library(s2dverification)
TableToGrid(table = table,
            colors = colors,
            brks = brks,
            title = title, xtitle = xtitle, ytitle = ytitle,
            xlabels = xlabels)
            
            
TableToGrid <- function(table, colors, brks, title = NULL, title.color = "royalblue4", xtitle = NULL, ytitle = NULL, xlabels = NULL, xvert = FALSE, ylabels = NULL, line = 3, figure.width = 1, legend = TRUE, legend.width = 0.15, file = NULL, ...){
  
  ## variable checks:
  if(is.null(colors)) stop("You have to specify a color palette of at least 2 colors")
  if(is.null(brks)) stop("You have to specify 2 or more intervals")
  if(!is.matrix(table)) stop("Input values are not a matrix")    
  n.colors <- length(colors)
  n.brks <- length(brks)
  if(n.brks != n.colors + 1) stop("There must be one break more than the number of colors")
  n.cols <- ncol(table)
  n.rows <- nrow(table)
  if(!is.null(xlabels) && length(xlabels) != n.cols) stop("The number of x labels must be equal to the number of columns of the data matrix")    
  if(!is.null(ylabels) && length(ylabels) != n.rows) stop("The number of y labels must be equal to the number of rows of the data matrix")    
  if(!is.numeric(legend.width) || legend.width < 0 || legend.width > 0.5) stop("legend.width must be a number from 0 to 0.5")
  if("s2dverification" %in% (.packages())){ print("Package s2dverification found")} else { stop("You need to load R package s2dverification") }
  
  ## print output file:
  if(is.null(file)) { file.output <- paste0(getwd(), "/table2grid.png") } else { file.output <- file } 
  print(paste0("Saving grid image in: ", file.output))
  
  ## generate grid image:
  png(file = file.output, width = 55 * n.cols * figure.width, height = 50 * n.rows) 
  plot.new()
  
  ## Draw empty plot:
  par(mar = c(4, 4, 1, 0), fig = c(0.1, 1 - legend.width, 0.1, 0.9), new=TRUE)
  plot(1, 1, type = "n", xaxt = "n", yaxt = "n", ylim = c(0.5, n.rows + 0.5), xlim = c(-0.5, n.cols - 1 + 0.5), ann = F,  bty="n") ## to remove black border
  
  ## Add axes titles:
  label.size <- 1.2 * (max(n.cols, n.rows)/10)^0.5
  mtext(side = 1, text = xtitle, line = line, cex = label.size, font = 3)
  mtext(side = 2, text = ytitle, line = 3, cex = label.size, font = 3)
  
  ## Add plot title:
  if(is.null(title.color)) title.color <- "royalblue4"
  mtext(side = 3, text = title, cex = 1.75 * (n.rows/10)^0.7, col = title.color)
  
  ## Add axis labels:
  axis.size <- (max(n.cols, n.rows)/10)^0.3
  if(is.null(xlabels)) xlabels = 1:n.cols
  if(is.null(ylabels)) ylabels = 1:n.rows
  axis(1, at=seq(0, n.cols-1), las=ifelse(xvert, 2, 1), labels=xlabels, cex.axis=axis.size, tck = 0, lwd = 0, line = - 1 - (n.rows/10 - 1))     ## Add x-axis labels
  axis(2, at=seq(1, n.rows), las=1, labels=rev(ylabels), cex.axis=axis.size, tck = 0, lwd = 0, line = 0.5 - n.cols/10)     ## Add y-axis labels
  
  ## create an array of colors instead of numbers (it starts all gray):                
  array.colors <- array("gray", c(n.rows, n.cols))
  for(int in n.colors:1) array.colors[table <= brks[int + 1]] <- colors[int]
  
  ## fill with colors the cells in the figure:
  for(p in 1:n.rows){ for(l in 0:(n.cols-1)){ polygon(c(0.5 + l - 1, 0.5 + l - 1, 1.5 + l - 1, 1.5 + l - 1), c(-0.5 + n.rows + 1 - p, 0.5 + n.rows + 1 - p, 0.5 + n.rows + 1 - p, -0.5 + n.rows + 1 - p), col = array.colors[p, 1 + l], border="black") }}
  
  ## Draw color legend:
  if(legend){
    par(fig=c(1 - legend.width - 0.01, 1 - legend.width + legend.width * min(1, 10 / n.cols), 0.3, 0.8), new=TRUE)
    legend.label.size <- (max(n.cols, n.rows)/10)^0.4
    if (any(array.colors == 'gray')) {
      ColorBar(brks, cols = colors, vert = TRUE, label_scale = legend.label.size, subsample = 1, ..., col_sup = 'gray', col_inf = 'gray')
    } else {
      ColorBar(brks, cols = colors, vert = TRUE, label_scale = legend.label.size, subsample = 1, ...)
    }
    
  }
  
  dev.off()  
}

