# \\\ # Copyright 2021-2022 Louis H�raut*1 # # *1 INRAE, France # louis.heraut@inrae.fr # # This file is part of ash R toolbox. # # ash R toolbox is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or (at # your option) any later version. # # ash R toolbox is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with ash R toolbox. If not, see <https://www.gnu.org/licenses/>. # /// # # # plotting/layout.R # # # Usefull library library(ggplot2) library(scales) library(qpdf) library(gridExtra) library(gridtext) library(dplyr) library(grid) library(ggh4x) library(RColorBrewer) library(rgdal) library(shadowtext) # Sourcing R file source('plotting/time.R', encoding='latin1') source('plotting/info.R', encoding='latin1') source('plotting/map.R', encoding='latin1') source('plotting/matrix.R', encoding='latin1') source('plotting/other.R', encoding='latin1') ## 1. PERSONALISATION ### 1.1. Personal theme theme_ash = theme( # White background panel.background=element_rect(fill='white'), # Font text=element_text(family='sans'), # Border of plot panel.border = element_rect(color="grey85", fill=NA, size=0.7), # Grid panel.grid.major.x=element_blank(), panel.grid.major.y=element_blank(), # Ticks marker axis.ticks.x=element_line(color='grey75', size=0.3), axis.ticks.y=element_line(color='grey75', size=0.3), # Ticks label axis.text.x=element_text(color='grey40'), axis.text.y=element_text(color='grey40'), # Ticks length axis.ticks.length=unit(1.5, 'mm'), # Ticks minor ggh4x.axis.ticks.length.minor=rel(0.5), # Title plot.title=element_text(size=9, vjust=-2, hjust=-1E-3, color='grey20'), # Axis title axis.title.x=element_blank(), axis.title.y=element_blank(), # Axis line axis.line.x=element_blank(), axis.line.y=element_blank(), ) ### 1.2. Color palette palette_perso = c('#0f3b57', '#1d7881', '#80c4a9', '#e2dac6', #mid '#fadfad', '#d08363', '#7e392f') ## 2. LAYOUT datasheet_layout = function (df_data, df_meta, layout_matrix, isplot=c('datasheet', 'matrix', 'map'), figdir='', filedir_opt='', filename_opt='', variable='', df_trend=NULL, p_threshold=0.1, unit2day=365.25, type='', trend_period=NULL, mean_period=NULL, axis_xlim=NULL, missRect=FALSE, time_header=NULL, info_header=TRUE, info_ratio=1, time_ratio=2, var_ratio=3, df_shapefile=NULL) { outfile = "Panels" if (filename_opt != '') { outfile = paste(outfile, '_', filename_opt, sep='') } outfile = paste(outfile, '.pdf', sep='') # If there is not a dedicated figure directory it creats one outdir = file.path(figdir, filedir_opt, sep='') if (!(file.exists(outdir))) { dir.create(outdir) } outdirTmp = file.path(outdir, 'tmp') if (!(file.exists(outdirTmp))) { dir.create(outdirTmp) } else { unlink(outdirTmp, recursive=TRUE) dir.create(outdirTmp) } nbp = length(df_data) if (all(class(df_data) != 'list')) { df_data = list(df_data) } if (all(class(df_trend) != 'list')) { df_trend = list(df_trend) if (length(df_trend) == 1) { df_trend = replicate(nbp, df_trend) }} if (all(class(p_threshold) != 'list')) { p_threshold = list(p_threshold) if (length(p_threshold) == 1) { p_threshold = replicate(nbp, p_threshold) }} if (all(class(unit2day) != 'list')) { unit2day = list(unit2day) if (length(unit2day) == 1) { unit2day = replicate(nbp, unit2day) }} if (all(class(type) != 'list')) { type = list(type) if (length(type) == 1) { type = replicate(nbp, type) }} if (all(class(missRect) != 'list')) { missRect = list(missRect) if (length(missRect) == 1) { missRect = replicate(nbp, missRect) }} list_df2plot = vector(mode='list', length=nbp) # minTrend = c() # maxTrend = c() for (i in 1:nbp) { df2plot = list(data=df_data[[i]], trend=df_trend[[i]], p_threshold=p_threshold[[i]], unit2day=unit2day[[i]], type=type[[i]], missRect=missRect[[i]]) # okTrend = df_trend[[i]]$trend[df_trend[[i]]$p <= p_threshold[[i]]] # minTrend[i] = min(okTrend, na.rm=TRUE) # maxTrend[i] = max(okTrend, na.rm=TRUE) list_df2plot[[i]] = df2plot } if ('datasheet' %in% isplot) { time_panel(list_df2plot, df_meta, trend_period, info_header=info_header, time_header=time_header, layout_matrix=layout_matrix, info_ratio=info_ratio, time_ratio=time_ratio, var_ratio=var_ratio, outdirTmp=outdirTmp) } if ('matrix' %in% isplot) { matrix_panel(list_df2plot, df_meta, trend_period, mean_period, slice=12, outdirTmp=outdirTmp, A3=TRUE) } if ('map' %in% isplot) { map_panel(list_df2plot, df_meta, idPer=length(trend_period), df_shapefile=df_shapefile, outdirTmp=outdirTmp, margin=margin(t=5, r=0, b=5, l=5, unit="mm")) } # PDF combine pdf_combine(input=file.path(outdirTmp, list.files(outdirTmp)), output=file.path(outdir, outfile)) # unlink(outdirTmp, recursive=TRUE) } ## 3. COLOR MANAGEMENT ### 3.1. Color on colorbar get_color = function (value, min, max, ncolor=256, palette_name='perso', reverse=FALSE) { if (palette_name == 'perso') { colorList = palette_perso } else { colorList = brewer.pal(11, palette_name) } nSample = length(colorList) palette = colorRampPalette(colorList)(ncolor) Sample_hot = 1:(as.integer(nSample/2)+1) Sample_cold = (as.integer(nSample/2)+1):nSample palette_hot = colorRampPalette(colorList[Sample_hot])(ncolor) palette_cold = colorRampPalette(colorList[Sample_cold])(ncolor) if (reverse) { palette = rev(palette) palette_hot = rev(palette_hot) palette_cold = rev(palette_cold) } if (is.na(value)) { return (NA) } maxAbs = max(abs(max), abs(min)) if (value < 0) { idNorm = (value + maxAbs) / maxAbs id = round(idNorm*(ncolor - 1) + 1, 0) color = palette_cold[id] } else { idNorm = value / maxAbs id = round(idNorm*(ncolor - 1) + 1, 0) color = palette_hot[id] } return(color) } ### 3.2. Colorbar get_palette = function (min, max, ncolor=256, palette_name='perso', reverse=FALSE, nbTick=10) { if (palette_name == 'perso') { colorList = palette_perso } else { colorList = brewer.pal(11, palette_name) } nSample = length(colorList) palette = colorRampPalette(colorList)(ncolor) Sample_hot = 1:(as.integer(nSample/2)+1) Sample_cold = (as.integer(nSample/2)+1):nSample palette_hot = colorRampPalette(colorList[Sample_hot])(ncolor) palette_cold = colorRampPalette(colorList[Sample_cold])(ncolor) if (reverse) { palette = rev(palette) palette_hot = rev(palette_hot) palette_cold = rev(palette_cold) } if (min < 0 & max < 0) { paletteShow = palette_cold } else if (min > 0 & max > 0) { paletteShow = palette_hot } else { paletteShow = palette } posTick = seq(0, 1, length.out=nbTick) labTick = c() colTick = c() for (i in 1:nbTick) { lab = (i-1)/(nbTick-1) * (max - min) + min labTick = c(labTick, lab) col = get_color(lab, min=min, max=max, ncolor=ncolor, palette_name=palette_name, reverse=reverse) colTick = c(colTick, col) } return(list(palette=paletteShow, posTick=posTick, labTick=labTick, colTick=colTick)) } ### 3.3. Palette tester palette_tester = function (n=256) { X = 1:n Y = rep(0, times=n) palette = colorRampPalette(palette_perso)(n) p = ggplot() + theme( plot.background = element_blank(), panel.grid.major = element_blank(), panel.grid.minor = element_blank(), panel.border = element_blank(), panel.background = element_blank(), axis.title.x = element_blank(), axis.title.y = element_blank(), axis.text.x = element_blank(), axis.text.y = element_blank(), axis.ticks = element_blank(), axis.line = element_blank() ) + geom_line(aes(x=X, y=Y), color=palette[X], size=60) + scale_y_continuous(expand=c(0, 0)) ggsave(plot=p, filename=paste('palette_test', '.pdf', sep=''), width=10, height=10, units='cm', dpi=100) } ## 4. OTHER ### 4.1. Number formatting get_power = function (value) { if (value > 1) { power = nchar(as.character(as.integer(value))) - 1 } else { dec = gsub('0.', '', as.character(value), fixed=TRUE) ndec = nchar(dec) nnum = nchar(as.character(as.numeric(dec))) power = -(ndec - nnum + 1) } return(power) } ### 4.2. Pourcentage of variable gpct = function (pct, L, ref=NULL, shift=FALSE) { if (is.null(ref)) { minL = min(L, na.rm=TRUE) } else { minL = ref } maxL = max(L, na.rm=TRUE) spanL = maxL - minL xL = pct/100 * as.numeric(spanL) if (shift) { xL = xL + minL } return (xL) }