panel.R 14.8 KB
Newer Older
# Usefull library
Heraut Louis's avatar
Heraut Louis committed
library(ggplot2)
Heraut Louis's avatar
Heraut Louis committed
library(scales)
Heraut Louis's avatar
Heraut Louis committed
library(qpdf)
library(gridExtra)
library(gridtext)
Heraut Louis's avatar
Heraut Louis committed
library(dplyr)
library(grid)
Heraut Louis's avatar
Heraut Louis committed
library(ggh4x)
Heraut Louis's avatar
Heraut Louis committed
library(RColorBrewer)
louis_heraut's avatar
louis_heraut committed

Heraut Louis's avatar
Heraut Louis committed
time_panel = function (df_data_code, df_trend_code, type, p_threshold=0.1, missRect=FALSE, unit2day=365.25, period=NULL, last=FALSE, color=NULL) {
Heraut Louis's avatar
Heraut Louis committed

Heraut Louis's avatar
Heraut Louis committed

Heraut Louis's avatar
Heraut Louis committed
    if (type == 'sqrt(Q)') {
Heraut Louis's avatar
Heraut Louis committed
        df_data_code$Qm3s = sqrt(df_data_code$Qm3s)
Heraut Louis's avatar
Heraut Louis committed
    }
Heraut Louis's avatar
Heraut Louis committed
    
    maxQ = max(df_data_code$Qm3s, na.rm=TRUE)
Heraut Louis's avatar
Heraut Louis committed
    
Heraut Louis's avatar
Heraut Louis committed
    power = get_power(maxQ)
    
Heraut Louis's avatar
Heraut Louis committed
    dbrk = 10^power

Heraut Louis's avatar
Heraut Louis committed
    df_data_code$Qm3sN = df_data_code$Qm3s / dbrk
Heraut Louis's avatar
Heraut Louis committed

Heraut Louis's avatar
Heraut Louis committed
    if (!is.null(df_trend_code)) {
Heraut Louis's avatar
Heraut Louis committed
        
Heraut Louis's avatar
Heraut Louis committed
        df_trend_code$trendN = df_trend_code$trend / dbrk
        df_trend_code$interceptN = df_trend_code$intercept / dbrk
    }

    maxQN = max(df_data_code$Qm3sN, na.rm=TRUE)
    
    if (maxQN >= 5) {
        dbrk = 1.0
        accuracy = 0.1
    } else if (maxQN < 5 & maxQN >= 3) {
        dbrk = 0.5
        accuracy = 0.1
    } else if (maxQN < 3 & maxQN >= 2) {
        dbrk = 0.4
        accuracy = 0.1
    } else if (maxQN < 2 & maxQN >= 1) {
        dbrk = 0.2
        accuracy = 0.1
    } else if (maxQN < 1) {
        dbrk = 0.1
        accuracy = 0.1
Heraut Louis's avatar
Heraut Louis committed
    }
Heraut Louis's avatar
Heraut Louis committed
    
Heraut Louis's avatar
Heraut Louis committed
    dDate = as.numeric(df_data_code$Date[length(df_data_code$Date)] -
Heraut Louis's avatar
Heraut Louis committed
                       df_data_code$Date[1]) / unit2day
Heraut Louis's avatar
Heraut Louis committed

    # datebreak = round(as.numeric(dDate) / unit2day / 11 , 0)
Heraut Louis's avatar
Heraut Louis committed
    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
    }
    
    p = ggplot() + 
Heraut Louis's avatar
Heraut Louis committed
        
Heraut Louis's avatar
Heraut Louis committed
        # theme_bw() +

    theme(panel.background=element_rect(fill='white'),
          text=element_text(family='sans'),
          panel.border=element_blank(),

          panel.grid.major.y=element_line(color='grey85', size=0.3),
          panel.grid.major.x=element_blank(),
          
          axis.ticks.y=element_blank(),
          axis.ticks.x=element_line(color='grey75', size=0.3),
          
          axis.text.x=element_text(color='grey40'),
          axis.text.y=element_text(color='grey40'),

          ggh4x.axis.ticks.length.minor=rel(0.5),
          axis.ticks.length=unit(1.5, 'mm'),

Heraut Louis's avatar
Heraut Louis committed
          plot.title=element_text(size=9, vjust=-3, 
                                  hjust=-1E-3, color='grey20'), 
Heraut Louis's avatar
Heraut Louis committed
          axis.title.x=element_blank(),
          axis.title.y=element_blank(),
          # axis.title.y=element_text(size=8, color='grey20'),
          axis.line.x=element_blank(),
          axis.line.y=element_blank(),
          )

    if (last) {
        p = p +
            theme(plot.margin=margin(1, 5, 5, 5, unit="mm"))
    } else {
        p = p +
            theme(plot.margin=margin(1, 5, 1, 5, unit="mm"))
    }
Heraut Louis's avatar
Heraut Louis committed
        
Heraut Louis's avatar
Heraut Louis committed

    if (type == 'sqrt(Q)' | type == 'Q') {
        p = p +
Heraut Louis's avatar
Heraut Louis committed
            geom_line(aes(x=df_data_code$Date, y=df_data_code$Qm3sN),
Heraut Louis's avatar
Heraut Louis committed
                      color='grey20',
                      size=0.3)
Heraut Louis's avatar
Heraut Louis committed
    } else {
        p = p +
Heraut Louis's avatar
Heraut Louis committed
            # geom_line(aes(x=df_data_code$Date, y=df_data_code$Qm3sN),
Heraut Louis's avatar
Heraut Louis committed
                      # color='grey70') +
Heraut Louis's avatar
Heraut Louis committed
            geom_point(aes(x=df_data_code$Date, y=df_data_code$Qm3sN),
Heraut Louis's avatar
Heraut Louis committed
                       shape=1, color='grey20', size=1)
    }

    if (missRect) {
Heraut Louis's avatar
Heraut Louis committed
        NAdate = df_data_code$Date[is.na(df_data_code$Qm3sN)]
        dNAdate = diff(NAdate)
        NAdate_Down = NAdate[append(Inf, dNAdate) != 1]
        NAdate_Up = NAdate[append(dNAdate, Inf) != 1]

        p = p +
            geom_rect(aes(xmin=NAdate_Down, 
                          ymin=0, 
                          xmax=NAdate_Up, 
Heraut Louis's avatar
Heraut Louis committed
                          ymax=maxQN*1.1),
                      linetype=0, fill='Wheat', alpha=0.4)
Heraut Louis's avatar
Heraut Louis committed

Heraut Louis's avatar
Heraut Louis committed
    if ((type == 'sqrt(Q)' | type == 'Q') & !is.null(period)) {
            period = as.Date(period)
            p = p + 
                geom_rect(aes(xmin=min(df_data_code$Date),
                              ymin=0, 
                              xmax=period[1], 
Heraut Louis's avatar
Heraut Louis committed
                              ymax= maxQN*1.1),
Heraut Louis's avatar
Heraut Louis committed
                          linetype=0, fill='grey85', alpha=0.3) +
                
                geom_rect(aes(xmin=period[2],
                              ymin=0, 
                              xmax=max(df_data_code$Date), 
Heraut Louis's avatar
Heraut Louis committed
                              ymax= maxQN*1.1),
Heraut Louis's avatar
Heraut Louis committed
                          linetype=0, fill='grey85', alpha=0.3) 
        }

Heraut Louis's avatar
Heraut Louis committed
    if (!is.null(df_trend_code)) {
Heraut Louis's avatar
Heraut Louis committed
        if (df_trend_code$p <= p_threshold) {
            abs = c(df_data_code$Date[1],
                    df_data_code$Date[length(df_data_code$Date)])
Heraut Louis's avatar
Heraut Louis committed
            abs_num = as.numeric(abs) / unit2day
Heraut Louis's avatar
Heraut Louis committed
            ord = abs_num * df_trend_code$trendN +
                df_trend_code$interceptN
Heraut Louis's avatar
Heraut Louis committed
            if (!is.null(color)) {
                p = p + 
                    geom_line(aes(x=abs, y=ord), 
Heraut Louis's avatar
Heraut Louis committed
                              color=color, 
                              size=0.7)
Heraut Louis's avatar
Heraut Louis committed
            } else {
                p = p + 
                    geom_line(aes(x=abs, y=ord), 
                              color='cornflowerblue')
            }
Heraut Louis's avatar
Heraut Louis committed
            
            p = p +
                ggtitle(bquote(.(type)~~'['*m^{3}*'.'*s^{-1}*'] x'~10^{.(as.character(power))}~~~'tendance :'~.(format(df_trend_code$trend, scientific=TRUE, digits=3))~m^{3}*'.'*s^{-1}*'.'*an^{-1}))
            
        } else {
            p = p +
                ggtitle(bquote(.(type)~' ['*m^{3}*'.'*s^{-1}*'] x'~10^{.(as.character(power))}))
        }
    } else { 
        p = p +
            ggtitle(bquote(.(type)~' ['*m^{3}*'.'*s^{-1}*'] x'~10^{.(as.character(power))}))
    }
Heraut Louis's avatar
Heraut Louis committed

Heraut Louis's avatar
Heraut Louis committed
    # if (norm) {
    #     p = p +
Heraut Louis's avatar
Heraut Louis committed
    #         ylab(bquote('dbit ['*m^{3}*'.'*s^{-1}*']  x'~10^{.(as.character(power))}))
Heraut Louis's avatar
Heraut Louis committed
    # } else {
    #     p = p +
Heraut Louis's avatar
Heraut Louis committed
    #         ylab(expression(paste('dbit [', m^{3}, '.', 
Heraut Louis's avatar
Heraut Louis committed
    #                               s^{-1}, ']', sep='')))
    # }
Heraut Louis's avatar
Heraut Louis committed

    p = p + 
Heraut Louis's avatar
Heraut Louis committed
        # xlab('date') + 
Heraut Louis's avatar
Heraut Louis committed
        scale_x_date(date_breaks=paste(as.character(datebreak), 
                                       'year', sep=' '),
Heraut Louis's avatar
Heraut Louis committed
                     date_minor_breaks=paste(as.character(dateminbreak), 
                                             'year', sep=' '),
                     guide='axis_minor',
                     date_labels="%Y",
                     limits=c(min(df_data_code$Date), 
                              max(df_data_code$Date)),
Heraut Louis's avatar
Heraut Louis committed
                     expand=c(0, 0)) +
Heraut Louis's avatar
Heraut Louis committed
        
Heraut Louis's avatar
Heraut Louis committed
        scale_y_continuous(breaks=seq(0, maxQN*10, dbrk),
                           limits=c(0, maxQN*1.1),
Heraut Louis's avatar
Heraut Louis committed
                           expand=c(0, 0),
                           labels=label_number(accuracy=accuracy))

    return(p)
}


text_panel = function(code, df_meta) {
    df_meta_code = df_meta[df_meta$code == code,]

    text = paste(
        "<span style='font-size:18pt'> station <b>", code, "</b></span><br>",
        "nom : ", df_meta_code$nom, "<br>", 
Heraut Louis's avatar
Heraut Louis committed
        "rgion hydrographique : ", df_meta_code$region_hydro, "<br>",
        "position : (", df_meta_code$L93X, "; ", df_meta_code$L93Y, ")", "<br>",
        "surface : ", df_meta_code$surface_km2, " km<sup>2</sup>",
        sep='')

    gtext = richtext_grob(text,
                          x=0, y=1,
                          margin=unit(c(5, 5, 5, 5), "mm"),
                          hjust=0, vjust=1,
                          gp=gpar(col="grey20", fontsize=12))
    return(gtext)
}


Heraut Louis's avatar
Heraut Louis committed

Heraut Louis's avatar
Heraut Louis committed
matrice_panel = function (list_df2plot, df_meta) {

    nbp = length(list_df2plot)

    minTrend = c()
    maxTrend = c()

    for (i in 1:nbp) {
        
        df_trend = list_df2plot[[i]]$trend
        p_threshold = list_df2plot[[i]]$p_threshold
        
        okTrend = df_trend$trend[df_trend$p <= p_threshold]

        minTrend[i] = min(okTrend, na.rm=TRUE)
        maxTrend[i] = max(okTrend, na.rm=TRUE)
    }

    # Get all different stations code
    Code = levels(factor(df_meta$code))

Heraut Louis's avatar
Heraut Louis committed
    # Type = vector(mode='list', length=nbp)
    # for (i in 1:nbp) {
    #     Type[[i]] = 
    # }

    Type_mat = list()
Heraut Louis's avatar
Heraut Louis committed
    Code_mat = c()
Heraut Louis's avatar
Heraut Louis committed
    Trend_mat = c()
    Fill_mat = c()
Heraut Louis's avatar
Heraut Louis committed
    Color_mat = c()

    for (code in Code) {
        
        for (i in 1:nbp) {
            df_trend = list_df2plot[[i]]$trend
            p_threshold = list_df2plot[[i]]$p_threshold
            type = list_df2plot[[i]]$type
            
Heraut Louis's avatar
Heraut Louis committed
            Type_mat = append(Type_mat, type)
            Code_mat = append(Code_mat, code)
Heraut Louis's avatar
Heraut Louis committed

            df_trend_code = df_trend[df_trend$code == code,]

            if (df_trend_code$p <= p_threshold){
                color_res = get_color(df_trend_code$trend, 
                                      minTrend[i],
                                      maxTrend[i],
                                      palette_name='perso',
                                      reverse=FALSE)

Heraut Louis's avatar
Heraut Louis committed
                trend = df_trend_code$trend
                fill = color_res$color
                color = 'white'

Heraut Louis's avatar
Heraut Louis committed

Heraut Louis's avatar
Heraut Louis committed
            } else { 
                trend = NA
                fill = 'white'
Heraut Louis's avatar
Heraut Louis committed
                color = 'white'
Heraut Louis's avatar
Heraut Louis committed
                
Heraut Louis's avatar
Heraut Louis committed
            }

Heraut Louis's avatar
Heraut Louis committed
            Trend_mat = append(Trend_mat, trend)
            Fill_mat = append(Fill_mat, fill)
            Color_mat = append(Color_mat, color)
Heraut Louis's avatar
Heraut Louis committed
        }
Heraut Louis's avatar
Heraut Louis committed
    }
Heraut Louis's avatar
Heraut Louis committed

    X = as.integer(factor(as.character(Type_mat)))
    Y = as.integer(factor(Code_mat))
    
Heraut Louis's avatar
Heraut Louis committed
    mat = ggplot() +
Heraut Louis's avatar
Heraut Louis committed
        
        theme(
              panel.background=element_rect(fill='white'),
              text=element_text(family='sans'),
              panel.border=element_blank(),

              panel.grid.major.y=element_blank(),
              panel.grid.major.x=element_blank(),
              
              axis.text.x=element_blank(),
              axis.text.y=element_blank(),
              
              axis.ticks.y=element_blank(),
              axis.ticks.x=element_blank(),

              ggh4x.axis.ticks.length.minor=rel(0.5),
              axis.ticks.length=unit(1.5, 'mm'),
          
              plot.title=element_text(size=9, vjust=-3, 
                                  hjust=-1E-3, color='grey20'), 

              axis.title.x=element_blank(),
              axis.title.y=element_blank(),

              axis.line.x=element_blank(),
              axis.line.y=element_blank(),
              
              plot.margin=margin(5, 5, 5, 5, unit="mm"),
              )
    

    # geom_point(aes(x=X, y=Y),
    #            shape=21, fill=Fill_mat, color=Color_mat,
    #            size=15, stroke=1) +

    for (i in 1:length(X)) {
        mat = mat +
            gg_circle(r=0.5, xc=X[i], yc=Y[i], fill=Fill_mat[i], color=Color_mat[i])
    }
        

    mat = mat +

    coord_fixed() +
        
    scale_x_continuous(limits=c(min(c(X, Y)) - rel(1.5), 
                                max(c(X, Y)) + rel(0.5)),
                       expand=c(0, 0)) + 
        
    scale_y_continuous(limits=c(min(c(X, Y)) - rel(0.5), 
                                max(c(X, Y)) + rel(1)),
                       expand=c(0, 0))

    # scale_x_continuous(limits=c(min(X)-0.4, max(X)+0.2),
    #                    expand=c(0, 0)) + 
        
    # scale_y_continuous(limits=c(min(Y)-0.2, max(Y)+0.4),
    #                    expand=c(0, 0))
    
    for (i in 1:length(Code)) {
        mat = mat +
            annotate('text', x=-0.5, y=i,
                     label=Code[i],
                     hjust=0, vjust=0.5, 
                     size=3.5, color='grey40')       
    }

    for (i in 1:nbp) {
        type = list_df2plot[[i]]$type
        mat = mat +
            annotate('text', x=i, y=max(Y) + 0.6,
                     label=bquote(.(type)),
                     hjust=0.5, vjust=0, 
                     size=3.5, color='grey40')       
    }
    

    for (i in 1:length(Trend_mat)) {
        trend = Trend_mat[i]
        if (!is.na(trend)) {
            power = get_power(trend)
            dbrk = 10^power
            trendN = round(trend / dbrk, 2)
            trendC1 = as.character(trendN)
            trendC2 = bquote('x '*10^{.(as.character(power))})
        } else {
            trendC1 = ''
            trendC2 = ''
        }
        mat = mat +
            annotate('text', x=X[i], y=Y[i],
                     label=trendC1,
                     hjust=0.5, vjust=0, 
                     size=3, color='white') +
            annotate('text', x=X[i], y=Y[i],
                     label=trendC2,
                     hjust=0.5, vjust=1.3,
                     size=2, color='white')
        
    }
Heraut Louis's avatar
Heraut Louis committed
    
    return (mat)
}


Heraut Louis's avatar
Heraut Louis committed

Heraut Louis's avatar
Heraut Louis committed


get_color = function (value, min, max, ncolor=256, palette_name='perso', reverse=FALSE) {
    
    if (palette_name == 'perso') {
        palette = colorRampPalette(c(
            '#1a4157',
            '#00af9d',
            '#fbdd7e',
            '#fdb147',
            '#fd4659'
        ))(ncolor)
        
    } else {
        palette = colorRampPalette(brewer.pal(11, palette_name))(ncolor)
    }
Heraut Louis's avatar
Heraut Louis committed

    if (reverse) {
        palette = rev(palette)
    }
    
Heraut Louis's avatar
Heraut Louis committed
    palette_cold = palette[1:as.integer(ncolor/2)]
    palette_hot = palette[(as.integer(ncolor/2)+1):ncolor]
Heraut Louis's avatar
Heraut Louis committed

Heraut Louis's avatar
Heraut Louis committed
    ncolor_cold = length(palette_cold)
    ncolor_hot = length(palette_hot)
Heraut Louis's avatar
Heraut Louis committed

Heraut Louis's avatar
Heraut Louis committed
    if (value < 0) {
        idNorm = (value - min) / (0 - min)
        id = round(idNorm*(ncolor_cold - 1) + 1, 0)
        color = palette_cold[id]
    } else {
        idNorm = (value - 0) / (max - 0)
        id = round(idNorm*(ncolor_hot - 1) + 1, 0)
        color = palette_hot[id]
    }
Heraut Louis's avatar
Heraut Louis committed
    
    return(list(color=color, palette=palette))
Heraut Louis's avatar
Heraut Louis committed
}

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()
    )
Heraut Louis's avatar
Heraut Louis committed



palette_tester = function () {

    n = 300
    X = 1:n
    Y = rep(0, times=n)

    palette = colorRampPalette(c(
        '#1a4157',
        '#00af9d',
        '#fbdd7e',
        '#fdb147',
        '#fd4659'
    ))(n)

    p = ggplot() + 
        geom_line(aes(x=X, y=Y), color=palette[X], size=10) +
        scale_y_continuous(expand=c(0, 0))

    ggsave(plot=p,
           path='/figures',
           filename=paste('palette_test', '.pdf', sep=''),
           width=10, height=10, units='cm', dpi=100)
}

# palette_teste()
Heraut Louis's avatar
Heraut Louis committed


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)
}


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, ...)
}