An error occurred while loading the file. Please try again.
-
Heraut Louis authoredca9ad56f
# \\\
# Copyright 2021-2022 Louis Hraut*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/panel.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)
palette_perso = c('#0f3b57',
'#1d7881',
'#80c4a9',
'#e2dac6', #mid
'#fadfad',
'#d08363',
'#7e392f')
display_type = function (type, bold=FALSE) {
if (type == "QA") {
if (bold) {
disp = bquote(Q[A])
} else {
disp = bquote(bold(Q[A]))
}
} else if (type == "QMNA") {
if (bold) {
disp = bquote(Q[MNA])
} else {
disp = bquote(bold(Q[MNA]))
}
} else if (type == "VCN10") {
if (bold) {
disp = bquote(V[CN10])
} else {
disp = bquote(bold(V[CN10]))
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
}
}
return (disp)
}
# 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(),
)
time_panel = function (df_data_code, df_trend_code, type, p_threshold=0.1, missRect=FALSE, unit2day=365.25, trend_period=NULL, mean_period=NULL, axis_xlim=NULL, grid=TRUE, last=FALSE, first=FALSE, color=NULL) {
# If 'type' is square root apply it to data
if (type == 'sqrt(Q)') {
df_data_code$Qm3s = sqrt(df_data_code$Qm3s)
}
# Compute max of flow
maxQ = max(df_data_code$Qm3s, na.rm=TRUE)
# Get the magnitude of the max of flow
power = get_power(maxQ)
# Normalize the max flow by it's magnitude
maxQtmp = maxQ/10^power
# Compute the spacing between y ticks
if (maxQtmp >= 5) {
dbrk = 1.0
} else if (maxQtmp < 5 & maxQtmp >= 3) {
dbrk = 0.5
} else if (maxQtmp < 3 & maxQtmp >= 2) {
dbrk = 0.4
} else if (maxQtmp < 2 & maxQtmp >= 1) {
dbrk = 0.2
} else if (maxQtmp < 1) {
dbrk = 0.1
}
141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
# Get the spacing in the right magnitude
dbrk = dbrk * 10^power
# Fix the accuracy for label
accuracy = NULL
# Time span in the unit of time
dDate = as.numeric(df_data_code$Date[length(df_data_code$Date)] -
df_data_code$Date[1]) / unit2day
# Compute the spacing between x ticks
if (dDate >= 100) {
datebreak = 25
dateminbreak = 5
} else if (dDate < 100 & dDate >= 50) {
datebreak = 10
dateminbreak = 1
} else if (dDate < 50) {
datebreak = 5
dateminbreak = 1
}
# Open new plot
p = ggplot() + theme_ash
# If it is the lats plot of the pages or not
if (last) {
if (first) {
p = p +
theme(plot.margin=margin(5, 5, 5, 5, unit="mm"))
} else {
p = p +
theme(plot.margin=margin(0, 5, 5, 5, unit="mm"))
}
# If it is the first plot of the pages or not
} else {
if (first) {
p = p +
theme(plot.margin=margin(5, 5, 0, 5, unit="mm"))
} else {
p = p +
theme(plot.margin=margin(0, 5, 0, 5, unit="mm"))
}
}
## Sub period background ##
if (!is.null(trend_period)) {
# trend_period = as.list(trend_period)
# Imin = 10^99
# for (per in trend_period) {
# I = interval(per[1], per[2])
# if (I < Imin) {
# Imin = I
# trend_period_min = as.Date(per)
# }
# }
# p = p +
# geom_rect(aes(xmin=min(df_data_code$Date),
# ymin=0,
# xmax=trend_period_min[1],
# ymax= maxQ*1.1),
# linetype=0, fill='grey97') +
# geom_rect(aes(xmin=trend_period_min[2],
# ymin=0,
# xmax=max(df_data_code$Date),
# ymax= maxQ*1.1),
# linetype=0, fill='grey97')
# Convert trend period to list if it is not
211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
trend_period = as.list(trend_period)
# Fix a disproportionate minimum for period
Imin = 10^99
# For all the sub period of analysis in 'trend_period'
for (per in trend_period) {
# Compute time interval of period
I = interval(per[1], per[2])
# If it is the smallest interval
if (I < Imin) {
# Store it
Imin = I
# Fix min period of analysis
trend_period_min = as.Date(per)
}
}
# Search for the index of the closest existing date
# to the start of the min period of analysis
idMinPer = which.min(abs(df_data_code$Date - trend_period_min[1]))
# Same for the end of the min period of analysis
idMaxPer = which.min(abs(df_data_code$Date - trend_period_min[2]))
# Get the start and end date associated
minPer = df_data_code$Date[idMinPer]
maxPer = df_data_code$Date[idMaxPer]
# If it is not a flow or sqrt of flow time serie
if (type != 'sqrt(Q)' & type != 'Q') {
# If there is an 'axis_lim'
if (!is.null(axis_xlim)) {
# If the temporary start of period is smaller
# than the fix start of x axis limit
if (minPer < axis_xlim[1]) {
# Set the start of the period to the start of
# the x axis limit
minPer = axis_xlim[1]
}
}
}
# If it is not a flow or sqrt of flow time serie
if (type != 'sqrt(Q)' & type != 'Q') {
# If there is an 'axis_lim'
if (!is.null(axis_xlim)) {
# If the temporary end of period plus one year
# is smaller than the fix end of x axis limit
if (maxPer + years(1) < axis_xlim[2]) {
# Add one year the the temporary end of period
maxPer = maxPer + years(1)
} else {
# Set the start of the period to the start of
# the x axis limit
maxPer = axis_xlim[2]
}
# Add one year the the temporary end of period
# if there is no 'axis_lim'
} else {
maxPer = maxPer + years(1)
}
}
# Draw rectangle to delimiting the sub period
p = p +
geom_rect(aes(xmin=minPer,
ymin=0,
xmax=maxPer,
ymax= maxQ*1.1),
linetype=0, fill='grey97')
}
## Mean step ##
# If there is a 'mean_period'
if (!is.null(mean_period)) {
281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
# Convert 'mean_period' to list
mean_period = as.list(mean_period)
# Number of mean period
nPeriod_mean = length(mean_period)
# Blank tibble to store variable in order to plot
# rectangle for mean period
plot_mean = tibble()
# Blank tibble to store variable in order to plot
# upper limit of rectangle for mean period
plot_line = tibble()
# For all mean period
for (j in 1:nPeriod_mean) {
# Get the current start and end of the sub period
Start_mean = mean_period[[j]][1]
End_mean = mean_period[[j]][2]
# Extract the data corresponding to this sub period
df_data_code_per =
df_data_code[df_data_code$Date >= Start_mean
& df_data_code$Date <= End_mean,]
# Min for the sub period
xmin = min(df_data_code_per$Date)
# If the min over the sub period is greater
# than the min of the entier period and
# it is not the first sub period
if (xmin > min(df_data_code$Date) & j != 1) {
# Substract 6 months to be in the middle of
# the previous year
xmin = xmin - months(6)
}
# If it is not a flow or sqrt of flow time serie and
# it is the first period
if (type != 'sqrt(Q)' & type != 'Q' & j == 1) {
# If there is an x axis limit
if (!is.null(axis_xlim)) {
# If the min of the period is before the x axis min
if (xmin < axis_xlim[1]) {
# The min for the sub period is the x axis
xmin = axis_xlim[1]
}
}
}
# Max for the sub period
xmax = max(df_data_code_per$Date)
# If the max over the sub period is smaller
# than the max of the entier period and
# it is not the last sub period
if (xmax < max(df_data_code$Date) & j != nPeriod_mean) {
# Add 6 months to be in the middle of
# the following year
xmax = xmax + months(6)
}
# If it is not a flow or sqrt of flow time serie and
# it is the last period
if (type != 'sqrt(Q)' & type != 'Q' & j == nPeriod_mean) {
# If there is an x axis limit
if (!is.null(axis_xlim)) {
# If the max of the period plus 1 year
# is smaller thant the max of the x axis limit
if (xmax + years(1) < axis_xlim[2]) {
# Add one year to the max to include
# the entire last year graphically
xmax = xmax + years(1)
} else {
# The max of this sub period is the max
# of the x axis limit
xmax = axis_xlim[2]
}