Newer
Older
#
# *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
#
# Regroups general parameters about plotting like the theme used ang
# color management. It mainly deals with the calling to specific
# plotting functions and the organisation of each plot for the
# generation of the PDF.
# Usefull library
library(ggplot2)
library(scales)
library(qpdf)
library(gridExtra)
library(gridtext)
library(dplyr)
library(grid)
library(ggh4x)
library(RColorBrewer)
source('plotting/datasheet.R', encoding='UTF-8')
source('plotting/map.R', encoding='UTF-8')
source('plotting/matrix.R', encoding='UTF-8')
source('plotting/break.R', encoding='UTF-8')
## 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
axis.title.y=element_text(size=9, vjust=1.2,
hjust=0.5, color='grey20'),
# Axis line
axis.line.x=element_blank(),
axis.line.y=element_blank(),
)
### 1.2. Color palette
## 2. USEFUL GENERICAL PLOT
### 2.1. Void plot
# A plot completly blank
void = ggplot() + geom_blank(aes(1,1)) +
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()
)
# A plot completly blank with a contour
contour = void +
theme(plot.background=element_rect(fill=NA, color="#EC4899"),
plot.margin=margin(t=0, r=0, b=0, l=0, unit="mm"))
### 2.2. Circle
# Allow to draw circle in ggplot2 with a radius and a center position
gg_circle = function(r, xc, yc, color="black", fill=NA, ...) {
x = xc + r*cos(seq(0, pi, length.out=100))
ymax = yc + r*sin(seq(0, pi, length.out=100))
ymin = yc + r*sin(seq(0, -pi, length.out=100))
annotate("ribbon", x=x, ymin=ymin, ymax=ymax, color=color,
fill=fill, ...)
}
## 3. LAYOUT
# Generates a PDF that gather datasheets, map and summarize matrix about the trend analyses realised on selected stations
datasheet_layout = function (df_data, df_meta, layout_matrix,
figdir='', filedir_opt='', filename_opt='',
variable='', df_trend=NULL,
p_threshold=0.1, unit2day=365.25, var='',
type='', trend_period=NULL,
mean_period=NULL, axis_xlim=NULL,
missRect=FALSE, time_header=NULL,
info_header=TRUE, foot_note=FALSE,
info_ratio=1, time_ratio=2,
AEAGlogo_file=NULL,
INRAElogo_file=NULL,
FRlogo_file=NULL) {
# If there is an option to mention in the filename it adds it
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)
}
# Names of a temporary directory to store all the independent pages
if (!(file.exists(outdirTmp))) {
dir.create(outdirTmp)
# If it already exists it deletes the pre-existent directory
# and recreates one
} else {
unlink(outdirTmp, recursive=TRUE)
dir.create(outdirTmp)
# Convert data tibble to list of tibble if it is not the case
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)
# Replicates the value the number of times that there
# is of studied variables
if (all(class(unit2day) != 'list')) {
unit2day = list(unit2day)
if (length(unit2day) == 1) {
unit2day = replicate(nbp, unit2day)
}}
if (all(class(var) != 'list')) {
var = list(var)
if (length(var) == 1) {
var = replicate(nbp, var)
}}
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)
}}
# Creates a blank list to store all the data of each type of plot
# For all the type of graph / number of studied variables
# Creates a list that gather all the info for one type of graph
df2plot = list(data=df_data[[i]],
trend=df_trend[[i]],
p_threshold=p_threshold[[i]],
unit2day=unit2day[[i]],
datasheet_panel(list_df2plot, df_meta, trend_period, info_header=info_header, time_header=time_header, foot_note=foot_note, layout_matrix=layout_matrix, info_ratio=info_ratio, time_ratio=time_ratio, var_ratio=var_ratio, foot_height=foot_height, resources_path=resources_path, AEAGlogo_file=AEAGlogo_file, INRAElogo_file=INRAElogo_file, FRlogo_file=FRlogo_file, outdirTmp=outdirTmp)
matrix_panel(list_df2plot, df_meta, trend_period, mean_period,
map_panel(list_df2plot,
df_meta,
idPer=length(trend_period),
outdirTmp=outdirTmp,
margin=margin(t=5, r=0, b=5, l=5, unit="mm"))
}
pdf_combine(input=file.path(outdirTmp, list.files(outdirTmp)),
output=file.path(outdir, outfile))
}
## 4. COLOR MANAGEMENT
### 4.1. Color on colorbar
# Returns a color of a palette corresponding to a value included
# between the min and the max of the variable
get_color = function (value, min, max, ncolor=256, palette_name='perso', reverse=FALSE) {
# If the value is a NA return NA color
if (is.na(value)) {
return (NA)
}
# Else takes the palette corresponding to the name given
} else {
colorList = brewer.pal(11, palette_name)
}
# Gets the number of discrete colors in the palette
# Separates it in the middle to have a cold and a hot palette
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)
}
# Gets the relative position of the value in respect
# to its span
} else {
idNorm = value / maxAbs
id = round(idNorm*(ncolor - 1) + 1, 0)
color = palette_hot[id]
}
return(color)
}
### 4.2. Colorbar
# Returns the colorbar but also positions, labels and colors of some
# ticks along it
get_palette = function (min, max, ncolor=256, palette_name='perso', reverse=FALSE, nbTick=10) {
# Else takes the palette corresponding to the name given
} else {
colorList = brewer.pal(11, palette_name)
}
# Gets the number of discrete colors in the palette
# Separates it in the middle to have a cold and a hot palette
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)
# Blank vector to store corresponding labels and colors
col = get_color(lab, min=min, max=max,
ncolor=ncolor,
palette_name=palette_name,
reverse=reverse)
# Stores them
labTick = c(labTick, lab)
colTick = c(colTick, col)
# List of results
res = list(palette=paletteShow, posTick=posTick,
labTick=labTick, colTick=colTick)
return(res)
### 4.3. Palette tester
# Allows to display the current personal palette
# All the same arbitrary y position to create a colorbar
# Make the theme blank
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()
) +
# Plot the palette
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)
}
## 5. OTHER TOOLS
### 5.1. Number formatting
# Returns the power of ten of the scientific expression of a value
# Do not care about the sign
value = abs(value)
# If the value is greater than one
if (value >= 1) {
# The magnitude is the number of character of integer part
# of the value minus one
# If value is zero
} else if (value == 0) {
# The power is zero
power = 0
### 5.2. Pourcentage of variable
# Returns the value corresponding of a certain percentage of a
# data serie
# Computes the value corresponding to the percentage
# If the value needs to be shift by its reference
### 5.3. Add months
add_months = function (date, n) {
new_date = seq(date, by = paste (n, "months"), length = 2)[2]
return (new_date)
}