R/plot_multidim_layers.R

Defines functions fspe.plot fori.plot fnnd.plot feve.plot fdis.plot fide.plot fdiv.plot fric.plot panels.to.patchwork sp.plot pool.plot background.plot

Documented in background.plot fdis.plot fdiv.plot feve.plot fide.plot fnnd.plot fori.plot fric.plot fspe.plot panels.to.patchwork pool.plot

#' Plot background of multidimensional plots
#'
#' This function creates a ggplot object with customized axes range 
#' (same for both), names and background
#'
#' @param range_faxes a vector with minimum and maximum values of axes. Note
#'   that to have a fair representation of position of species in all plots,
#'   they should have the same range. Default: `range_faxes = c(NA, NA)` (the 
#'   range is computed according to the range of values among all axes).
#' 
#' @param faxes_nm a vector with axes labels for figure.
#' 
#' @param color_bg a R color name  or an hexadecimal code used to fill plot
#'  background. Default: `color_bg = "grey95"`.
#'
#' @return A ggplot object plotting background of multidimensional graphs.
#' 
#' @author Camille Magneville and Sebastien Villeger
#' 
#' @export
#' 
#' @examples
#'  background <- background.plot(range_faxes = c(-1, 2), 
#'                                faxes_nm    = c("PC 1", "PC 2"), 
#'                                color_bg    = "grey90")
#'  background 


background.plot <- function(range_faxes, faxes_nm, color_bg) {
  
  ggplot_bg <- ggplot2::ggplot( ) +
    ggplot2::scale_x_continuous(limits = range_faxes, expand = c(0, 0)) +
    ggplot2::xlab(faxes_nm[1]) +
    ggplot2::scale_y_continuous(limits = range_faxes, expand = c(0, 0)) +
    ggplot2::ylab(faxes_nm[2]) +
    ggplot2::theme(panel.grid.minor = ggplot2::element_blank(),
                   panel.grid.major = ggplot2::element_blank(),
                   panel.background = ggplot2::element_rect(fill = color_bg),
                   axis.line = ggplot2::element_line(colour = "grey50", 
                                                     size = 1)) +
    ggplot2::coord_fixed()
  
  return(ggplot_bg)
} 




#' Plot species from the pool
#' 
#' Plot all species from the study case and associated convex hull
#' 
#' @param ggplot_bg a ggplot object of the plot background retrieved through
#' the \code{\link{background.plot}} function.
#' 
#' @param sp_coord2D a list of matrix (ncol = 2) with coordinates of 
#' species present in the pool for a given pair of axes
#' 
#' @param vertices_nD a list (with names as in sp_coord2D) of vectors with 
#' names of species being vertices in n dimensions.
#' 
#' @param plot_pool a logical value indicating whether species of each 
#' assemblage should be plotted or not. Default: plot_pool = TRUE.
#' 
#' @param color_ch a R color name or an hexadecimal code referring to the 
#'   border of the convex hull filled by the pool of species. Default: 
#'  `color_ch = "black"`.
#' 
#' @param color_pool a R color name or an hexadecimal code referring to the 
#' color of the pool.  This color is also used for FRic convex hull color. 
#' Default: `color_pool = "#0072B2"`.
#' 
#' @param color_vert a R color name or an hexadecimal code referring to the
#'   color of vertices if plotted. If color_vert = NA, vertices are not plotted
#'   (for shapes only defined by color, ie shape inferior to 20. Otherwise fill
#'   must also be set to NA). Default: `color_vert =  NA`. 
#'   
#' @param fill_ch a R color name or an hexadecimal code referring to the 
#'   filling of the convex hull filled by the pool of species. Default is: 
#'  `fill_ch = "white"`.
#' 
#' @param fill_pool a R color name or an hexadecimal code referring to the 
#'   colour to fill species symbol (if \code{shape_sp} > 20) and the assemblage 
#'   convex hull. Default: `fill_pool = '#0072B2'`.
#' 
#' @param fill_vert a character value referring to the color for filling symbol
#'   for vertices (if \code{shape_vert} >20). If `fill = NA` and `color = NA`,
#'   vertices are not plotted (if \code{shape_vert} superior to 20. Otherwise
#'   `color_vert = NULL` is enough). Default is `NA`. 
#' 
#' @param shape_pool a numeric value referring to the shape used to plot 
#'   species pool. Default: `shape_pool = 16`(filled circle). 
#' 
#' @param shape_vert a numeric value referring to the shape used to plot
#'   vertices if vertices should be plotted in a different way than other
#'   species. If `shape_vert = NA`, no vertices plotted. Default: 
#'   `shape_vert = NA`. 
#' 
#' @param size_pool a numeric value referring to the size of species belonging 
#' to the global pool. Default: `size_pool = 1`.
#' 
#' @param size_vert a numeric value referring to the size of symbol for 
#'   vertices. Default: `size_vert = 1`. 
#' 
#' @param alpha_ch a numeric value for transparency of the filling of the 
#'   convex hull (0 = high transparency, 1 = no transparency). Default: 
#'  `alpha_ch = 0.3`.
#'
#' @return A ggplot object plotting background of multidimensional graphs and
#'   species from the global pool (associated convex hull if asked).
#' 
#' @author Camille Magneville and Sebastien Villeger
#' 
#' @export
#' 
#' @examples
#' # Load Species*Traits dataframe:
#' data("fruits_traits", package = "mFD")
#' 
#' # Load Assemblages*Species dataframe:      
#' data("baskets_fruits_weights", package = "mFD") 
#' 
#' # Load Traits categories dataframe:
#' data("fruits_traits_cat", package = "mFD") 
#'  
#' # Compute functional distance 
#' sp_dist_fruits <- mFD::funct.dist(sp_tr         = fruits_traits,
#'                                   tr_cat        = fruits_traits_cat,
#'                                   metric        = "gower",
#'                                   scale_euclid  = "scale_center",
#'                                   ordinal_var   = "classic",
#'                                   weight_type   = "equal",
#'                                   stop_if_NA    = TRUE)
#'   
#' # Compute functional spaces quality to retrieve species coordinates matrix:
#' fspaces_quality_fruits <- mFD::quality.fspaces(sp_dist = sp_dist_fruits, 
#'  maxdim_pcoa         = 10,
#'  deviation_weighting = "absolute",
#'  fdist_scaling       = FALSE,
#'  fdendro             = "average")
#'  
#' # Retrieve species coordinates matrix:
#' sp_faxes_coord_fruits_2D <- 
#'   fspaces_quality_fruits$details_fspaces$sp_pc_coord[ , c("PC1", "PC2")]
#' 
#' # Set faxes limits:
#' # set range of axes if c(NA, NA):
#'  range_sp_coord_fruits  <- range(sp_faxes_coord_fruits_2D)
#'  range_faxes_lim <- range_sp_coord_fruits + 
#'    c(-1, 1)*(range_sp_coord_fruits[2] - 
#'    range_sp_coord_fruits[1]) * 0.05
#'  
#'  # Retrieve the background plot:
#'  ggplot_bg_fruits <- mFD::background.plot(
#'                                range_faxes = range_faxes_lim, 
#'                                faxes_nm    = c("PC 1", "PC 2"), 
#'                                color_bg    = "grey90") 
#'                                
#'  # Retrieve vertices names:
#'  vert_nm_fruits <- vertices(sp_faxes_coord_fruits_2D, 
#'   order_2D = TRUE, check_input = TRUE)
#'   
#'  # Plot the pool:
#'  plot_pool_fruits <- pool.plot(ggplot_bg   = ggplot_bg_fruits,
#'            sp_coord2D    = sp_faxes_coord_fruits_2D,
#'            vertices_nD   = vert_nm_fruits,
#'            plot_pool     = TRUE,
#'            shape_pool    = 3, 
#'            size_pool     = 0.8, 
#'            color_pool    = "grey95", 
#'            fill_pool     = NA, 
#'            color_ch      = NA, 
#'            fill_ch       = "white", 
#'            alpha_ch      = 1, 
#'            shape_vert    = 3, 
#'            size_vert     = 1, 
#'            color_vert    = "black", 
#'            fill_vert     = NA) 
#'  plot_pool_fruits


pool.plot <- function(ggplot_bg,
                    sp_coord2D,
                    vertices_nD,
                    plot_pool = TRUE,
                    shape_pool = 3, size_pool = 0.8, color_pool = "grey95", 
                    fill_pool = NA, color_ch = NA, fill_ch = "white", 
                    alpha_ch = 1, shape_vert = 3, size_vert = 1, 
                    color_vert = "black", fill_vert = NA) {
  
  
  # prepare data for plotting ####
  
  # dataframe with species coordinates and vertex status in nD:
  sp_xyv <- data.frame(x = sp_coord2D[, 1], y = sp_coord2D[, 2], vert = "sp")
  
  
  # if required vertices and convex hull:
  if (! is.null(vertices_nD)) {
    sp_xyv$vert <- as.character(sp_xyv$vert)
    sp_xyv[vertices_nD, "vert"] <- "vert"
    sp_xyv$vert <- as.factor(sp_xyv$vert)
    
    # coordinates of species vertices in nD:
    vertnD_xy <- sp_xyv[sp_xyv$vert == "vert", c("x", "y")]
    
    #  species being vertices of the convex hull in 2D:
    vert2D <- vertices(as.matrix(vertnD_xy), order_2D = TRUE)
    
  } # end of if vertices
  
  
  # plotting layers ####
  
  # default plot is background:
  ggplot_pool <- ggplot_bg
  
  # plotting convex hull if required:
  x <- NULL
  y <- NULL
  if (! is.null(vertices_nD)) {
    ggplot_pool <- ggplot_pool +
      ggplot2::geom_polygon(data = vertnD_xy[vert2D, ],
                            ggplot2::aes(x = x, y = y) ,
                            colour = color_ch, fill = fill_ch, 
                            alpha = alpha_ch)
  } # end of if vertices
  
  # plotting species if required:
  if (plot_pool) {
    
    # plotting species not being vertices
    x <- NULL
    y <- NULL
    ggplot_pool <- ggplot_pool +
      ggplot2::geom_point(data = sp_xyv[sp_xyv$vert == "sp", ],
                          ggplot2::aes(x = x, y = y),
                          size = size_pool, shape = shape_pool,
                          colour = color_pool, fill = fill_pool)
    
    # plotting species being vertices
    if (! is.null(vertices_nD)) {
      ggplot_pool <- ggplot_pool +
        ggplot2::geom_point(data = sp_xyv[sp_xyv$vert == "vert", ],
                            ggplot2::aes(x = x, y = y),
                            size = size_vert, shape = shape_vert,
                            colour = color_vert, fill = fill_vert)
    } # end of if vertices
    
  } # end of if plot species
  
  return(ggplot_pool)
  
}




#' Plot species
#' 
#' Plot species for one to n assemblages
#' 
#' @param ggplot_bg a ggplot object of the plot background retrieved through
#' the \code{\link{background.plot}} function.
#' 
#' @param asb_sp_coord2D a list of matrix (ncol = 2) with coordinates of 
#' species present in each assemblage for a given pair of axes.
#' 
#' @param asb_vertices_nD a list (with names as in asb_sp_coord2D) of vectors 
#' with names of species being vertices in n dimensions.
#' 
#' @param asb_sp_relatw a list of vector gathering species relative weight in
#'   each assemblage. It can be retrieved through the
#'   \code{\link{alpha.fd.multidim}}.
#' 
#' @param size_sp a numeric value referring to the size of the symbol used for
#'   species plotting if one assemblage to plot or a vector numeric values if
#'   several assemblages to plot. If more than one assemblage to plot, the
#'   vector should be formatted as: c(asb1 = "firstRsize", asb2 =
#'   "secondRsize", ...).
#' 
#' @param size_vert a numeric value referring to the size of the symbol used for
#'   vertices plotting if one assemblage to plot or a vector numeric values if
#'   several assemblages to plot. If more than one assemblage to plot, the
#'   vector should be formatted as: c(asb1 = "firstRsize", asb2 =
#'   "secondRsize", ...).
#' 
#' @param @param shape_sp a numeric value referring to the shape of the symbol 
#' used for
#'   species plotting if one assemblage to plot or a vector numeric values if
#'   several assemblages to plot. If more than one assemblage to plot, the
#'   vector should be formatted as: c(asb1 = "firstRshape", asb2 =
#'   "secondRshape", ...).
#' 
#' @param shape_vert a numeric value referring to the shape of the symbol used
#'   for vertices plotting if one assemblage to plot or a vector numeric values
#'   if several assemblages to plot. If more than one assemblage to plot, the
#'   vector should be formatted as: c(asb1 = "firstRshape", asb2 =
#'   "secondRshape", ...).
#' 
#' @param color_sp a R color name or an hexadecimal code referring to the color
#'   of species if one assemblage to plot or a vector of R color names or
#'   hexadecimal codes if several assemblages to plot. If more than one
#'   assemblage to plot, the vector should be formatted as: c(asb1 =
#'   "firstRcolorname", asb2 = "secondRcolorname", ...).
#' 
#' @param color_vert a R color name or an hexadecimal code referring to the
#'   color of vertices if one assemblage to plot or a vector of R color names or
#'   hexadecimal codes if several assemblages to plot. If more than one
#'   assemblage to plot, the vector should be formatted as: c(asb1 =
#'   "firstRcolorname", asb2 = "secondRcolorname", ...). If color_vert = NA,
#'   vertices are not plotted (for shapes only defined by color, ie shape
#'   inferior to 20. Otherwise `fill` must also be set to NA).
#'
#' @param fill_sp a R color name or an hexadecimal code referring to the color
#'   of species symbol filling (if \code{shape_sp} > 20) if one assemblage to
#'   plot or a vector of R color names or hexadecimal codes if several
#'   assemblages to plot. If more than one assemblage to plot, the vector should
#'   be formatted as: c(asb1 = "firstRcolorname", asb2 = "secondRcolorname",
#'   ...).
#' 
#' @param fill_vert a R color name or an hexadecimal code referring to the color
#'   of vertices symbol filling  (if \code{shape_vert} >20) if one assemblage to
#'   plot or a vector of R color names or hexadecimal codes if several
#'   assemblages to plot. If more than one assemblage to plot, the vector should
#'   be formatted as: c(asb1 = "firstRcolorname", asb2 = "secondRcolorname",
#'   ...). If `fill = NA` and `color = NA`, vertices are not plotted (if
#'   \code{shape_vert} superior to 20
#' 
#' @param limits_relatw a vector of two numbers giving the limits to set for 
#' the scale of species relative weights.
#' 
#' @param range_size_relatw a vector of two numbers specifying the minimum and 
#' the maximum size of the plotting symbol for relative weights.
#' 
#' @return A ggplot object with species plotted on the background plot.
#' 
#' @author Camille Magneville and Sebastien Villeger
#' 
#' @note If \code{asb_vertices_nD = NULL}, all arguments for vertices are 
#' ignored and if \code{asb_sp_relatw != NULL}, \code{size_sp} and 
#' \code{size_vert} are ignored. And if several assemblages are to be 
#' represented, aesthetics inputs should be formatted as c(pool = ..., asb1 =
#' ..., asb2 = ...).
#' 
#' @noRd

sp.plot <- function(ggplot_bg,
                    asb_sp_coord2D,
                    asb_vertices_nD = NULL,
                    asb_sp_relatw = NULL,
                    size_sp, shape_sp, color_sp, fill_sp,
                    size_vert, shape_vert, color_vert, fill_vert,
                    limits_relatw = c(0, 1),
                    range_size_relatw = c(1, 10)) {
  
  # names of assemblages:
  asb_nm <- names(asb_sp_coord2D)
  
  # dataframe with variables needed for plotting ####
  asb_sp_xywv <- NULL
  
  # loop on assemblages:
  for (z in asb_nm) {
    
    x <- NULL
    y <- NULL
    w <- NULL
    vert <- NULL
    asb <- NULL
    # species coordinates and name of assemblage: 
    data_z <- data.frame(x = asb_sp_coord2D[[z]][, 1],
                         y = asb_sp_coord2D[[z]][, 2],
                         w = 0,
                         vert = "no",
                         asb = z)
    
    
    # adding species weight:
    if (! is.null (asb_sp_relatw))  {
      data_z[, "w"] <- asb_sp_relatw[[z]][row.names(data_z)] 
    } else { 
      data_z[, "w"] <- size_sp[[z]]/100
    }

    # if needed, adding vertex status and size if fixed
    if (! is.null(asb_vertices_nD)) {
      data_z[asb_vertices_nD[[z]], "vert"] <- "vert"
      
      if (is.null (asb_sp_relatw)) {
        data_z[asb_vertices_nD[[z]], "w"] <- size_vert[[z]]/100
      }
    }
    
    # row binding:
    asb_sp_xywv <- rbind(asb_sp_xywv, data_z)
    
  } # end of z
  
  
  # define aesthetics ####
  
  # add new variable mixing assemblage and vertex status:
  asb_vert <- NULL
  asb_sp_xywv$asb_vert <- paste(asb_sp_xywv$asb, asb_sp_xywv$vert, sep = "_")
  
  # define aesthetics for species according to asb and vertex status:
  lev_asb_vert <- c(paste(asb_nm, "no", sep = "_"),
                    paste(asb_nm, "vert", sep = "_"))
  
  # if no vertices, setting aesthetics as for species:
  if (is.null(asb_vertices_nD)) {
    shape_vert <- shape_sp
    color_vert <- color_sp
    fill_vert <- fill_sp
  }
  
  # 2 cases: if one or more than one asb
  # otherwise the filling of aesthetic fills NA for vertices of asb1:
  if (length(asb_sp_coord2D) >= 2) {
    shape_asb_vert <- c(shape_sp, shape_vert)
    names(shape_asb_vert) <- lev_asb_vert
    
    color_asb_vert <- c(color_sp, color_vert)
    names(color_asb_vert) <- lev_asb_vert
    
    fill_asb_vert <- c(fill_sp, fill_vert)
    names(fill_asb_vert) <- lev_asb_vert
  }
  

  if (length(asb_sp_coord2D) == 1) {
    shape_asb_vert <- c(shape_sp[1], shape_vert[1])
    names(shape_asb_vert) <- lev_asb_vert
    
    color_asb_vert <- c(color_sp[1], color_vert[1])
    names(color_asb_vert) <- lev_asb_vert
    
    fill_asb_vert <- c(fill_sp[1], fill_vert[1])
    names(fill_asb_vert) <- lev_asb_vert
  }
  
  
  # reorder species according to decreasing weight:
  asb_sp_xywv <- asb_sp_xywv[order(asb_sp_xywv$w, decreasing = TRUE), ]
  
  
  ## plotting ####
  
  # default plot is background and set size of points:
  ggplot_sp <- ggplot_bg +
    ggplot2::scale_size(limits = limits_relatw, range = range_size_relatw)
  
  
  # Reorder the column with vertices information:
  # To first plot sp and then vertices (if 2 species same place but one vert
  # and the other not vert):
  order_vert_levels <- c("no", "vert")
  asb_sp_xywv$vert <- factor(as.character(asb_sp_xywv$vert), 
                             levels = order_vert_levels)
  asb_sp_xywv <- asb_sp_xywv[order(asb_sp_xywv$vert), ]
  
  
  # plot species as points with chosen shape, size and colors:
  ggplot_sp <- ggplot_sp +
    ggplot2::geom_point(data = asb_sp_xywv,
                        ggplot2::aes(x = x, y = y, size = w,
                            shape = asb_vert,
                            colour = asb_vert, fill = asb_vert),
                        show.legend = FALSE) +
    ggplot2::scale_shape_manual(name = "asb_vert", values = shape_asb_vert) +
    ggplot2::scale_colour_manual(name = "asb_vert", values = color_asb_vert) +
    ggplot2::scale_fill_manual(name = "asb_vert", values = fill_asb_vert)
  
  return(ggplot_sp)
  
}




#' Plot individual plots along a pair of functional axes into a unique graph
#' 
#' This function gathers panels into a unique \code{patchwork} graph 
#' with caption.
#' 
#' @param panels a list of ggplot objects illustrating an index on two given 
#' functional axes. There must be either one, three or six ggplot objects given
#' the number of studied functional axes.
#' 
#' @param plot_caption a ggplot object illustrating the caption of the 
#' final patchwork plot.
#' 
#' @return A unique ggplot object gathering functional panels and caption.
#' 
#' @author Camille Magneville and Sebastien Villeger
#' 
#' @export
#' 
#' @examples 
#' ## Retrieve FRic plot:
#' # Load Species*Traits dataframe:
#' data("fruits_traits", package = "mFD")
#' 
#' # Load Assemblages*Species dataframe:      
#' data("baskets_fruits_weights", package = "mFD") 
#' 
#' # Load Traits categories dataframe:
#' data("fruits_traits_cat", package = "mFD") 
#'  
#' # Compute functional distance 
#' sp_dist_fruits <- mFD::funct.dist(sp_tr         = fruits_traits,
#'                                   tr_cat        = fruits_traits_cat,
#'                                   metric        = "gower",
#'                                   scale_euclid  = "scale_center",
#'                                   ordinal_var   = "classic",
#'                                   weight_type   = "equal",
#'                                   stop_if_NA    = TRUE)
#'   
#' # Compute functional spaces quality to retrieve species coordinates matrix:
#' fspaces_quality_fruits <- mFD::quality.fspaces(sp_dist = sp_dist_fruits, 
#'  maxdim_pcoa         = 10,
#'  deviation_weighting = "absolute",
#'  fdist_scaling       = FALSE,
#'  fdendro             = "average")
#'  
#' # Retrieve species coordinates matrix:
#'   sp_faxes_coord_fruits <- 
#'     fspaces_quality_fruits$details_fspaces$sp_pc_coord
#'     
#'  # Retrieve species coordinates matrix for the assemblage "basket_1":
#'   sp_filter <- mFD::sp.filter(asb_nm          = c("basket_1"), 
#'                               sp_faxes_coord = sp_faxes_coord_fruits, 
#'                               asb_sp_w       = baskets_fruits_weights)
#'   sp_faxes_coord_fruits_b1 <- sp_filter$`species coordinates`
#'  
#'  # Reduce it to the two studed axes: PC1 and PC2:
#'  sp_faxes_coord_fruits_b1_2D <- sp_faxes_coord_fruits_b1[, c("PC1", "PC2")]
#'
#' # Set faxes limits:
#' # set range of axes if c(NA, NA):
#'  range_sp_coord_fruits  <- range(sp_faxes_coord_fruits)
#'  range_faxes_lim <- range_sp_coord_fruits + c(-1, 1)*(range_sp_coord_fruits[2] - 
#'  range_sp_coord_fruits[1]) * 0.05
#'  
#'  # Retrieve the background plot:
#'  ggplot_bg_fruits <- mFD::background.plot(
#'                                range_faxes = range_faxes_lim, 
#'                                faxes_nm    = c("PC 1", "PC 2"), 
#'                                color_bg    = "grey90") 
#'                                
#'  # Retrieve vertices names:
#'  vert_nm_fruits <- vertices(sp_faxes_coord_fruits_b1_2D, 
#'   order_2D = TRUE, check_input = TRUE)
#'                                
#'  # Plot in white the convex hull of all fruits species:
#'  ggplot_fric <- mFD::fric.plot(
#'            ggplot_bg       = ggplot_bg_fruits,
#'            asb_sp_coord2D  = list(basket_1 = sp_faxes_coord_fruits_b1_2D),
#'            asb_vertices_nD = list(basket_1 = vert_nm_fruits),
#'            plot_sp         = TRUE,
#'            color_ch        = c("basket_1" = "black"), 
#'            fill_ch         = c("basket_1" = "white"), 
#'            alpha_ch        = c("basket_1" = 0.3),
#'            size_sp = c("basket_1" = 1),
#'            shape_sp = c("basket_1" = 16),
#'            color_sp = c("basket_1" = "red"),
#'            fill_sp = c("basket_1" = "red"),
#'            size_vert = c("basket_1" = 1),
#'            color_vert = c("basket_1" = "red"),
#'            fill_vert = c("basket_1" = "red"),
#'            shape_vert = c("basket_1" = 16))
#'  ggplot_fric
#'  
#' ## Create a caption summing up FRic values 
#' # retrieve values to plot:
#' top_fric <- c("Functional richness", "basket_1", "")
#' 
#' asb_fd_ind <- alpha_fd_indices_fruits <- mFD::alpha.fd.multidim(
#' sp_faxes_coord   = sp_faxes_coord_fruits[ , c("PC1", "PC2", "PC3", "PC4")],
#' asb_sp_w         = baskets_fruits_weights,
#' ind_vect         = c("fric"),
#' scaling          = TRUE,
#' check_input      = TRUE,
#' details_returned = TRUE)
#' 
#' values_fric <- c(round(asb_fd_ind$functional_diversity_indices["basket_1", 
#' "fric"], 3), "")
#'
#' # customize position of texts in the plot:
#' spread_faxes <- (range_sp_coord_fruits[2] - range_sp_coord_fruits[1])
#' hh <- c(1, 2.5, 4, 5.5)
#' vv <- 0.3
#'
#' # plot window:
#' x <- NULL
#' y <- NULL
#' plot_caption <- ggplot2::ggplot(data.frame(x = range_sp_coord_fruits, 
#'                                           y = range_sp_coord_fruits),
#'                                ggplot2::aes(x = x, y = y)) +
#'  ggplot2::scale_x_continuous(limits = range_sp_coord_fruits, 
#'  expand = c(0, 0)) +
#'  ggplot2::scale_y_continuous(limits = range_sp_coord_fruits, 
#'  expand = c(0, 0)) +
#'  ggplot2::theme_void() + ggplot2::theme(legend.position = "none") +
#'  ggplot2::geom_rect(xmin = range_sp_coord_fruits[1], 
#'                     xmax = range_sp_coord_fruits[2],
#'                     ymin = range_sp_coord_fruits[1], 
#'                     ymax = range_sp_coord_fruits[2],
#'                     fill = "white", colour ="black")
#'
#' # plot names of index and of assemblages:
#' h   <- NULL
#' v   <- NULL
#' top <- NULL
#' x <- NULL
#' y <- NULL
#' plot_caption <- plot_caption +
#'  ggplot2::geom_text(data = data.frame(
#'    h = range_sp_coord_fruits[1] + spread_faxes * 0.15 * hh[c(1,3:4)],
#'    v = range_sp_coord_fruits[2] - spread_faxes * rep(0.2, 3),
#'    top = top_fric),
#'    ggplot2::aes(x = h, y = v, label = top),
#'    size = 3, hjust = 0.5, fontface = "bold")
#'
#' # plot FRic values:
#' values_lab <- NULL
#' data_caption <- data.frame(
#'   h = range_sp_coord_fruits[1] + spread_faxes * 0.15 * hh[2:4],
#'   v = range_sp_coord_fruits[2] - spread_faxes*rep(vv, 3),
#'   values_lab = c("FRic", values_fric))
#' plot_caption <- plot_caption +
#'   ggplot2::geom_text(data = data_caption,
#'                     ggplot2::aes(x = h, y = v, label = values_lab),
#'                     size = 3, hjust = 0.5, fontface = "plain")
#'
#' ## Create patchwork:
#' patchwork_fric <- mFD::panels.to.patchwork(list(ggplot_fric), plot_caption)
#' patchwork_fric


panels.to.patchwork <- function(panels, plot_caption) {
  
  plot_nb <- length(panels)
  
  # if 2 axes = 1 plot + caption:
  if (plot_nb == 1) { 
    
    patchwork_plots_all <- panels[[1]] + plot_caption +
      patchwork::plot_layout(byrow = TRUE, heights = c(1), widths = c(1, 1),
                             ncol = 2, nrow = 1, guides = "collect")
  }
  
  # if 3 axes = 3 plots + caption in a 2*2 layout:
  if (plot_nb == 3) {
    patchwork_plots_all <- (panels[[1]] + plot_caption +
                              panels[[2]] + panels[[3]]) +
      patchwork::plot_layout(byrow = TRUE, heights = c(1, 1), widths = c(1, 1),
                             ncol = 2, nrow = 2, guides = "collect")
  }
  
  # if 4 axes = 6 plots + caption in a 3*3 layout with 2 empty cases:
  if (plot_nb == 6) {
    patchwork_plots_all <- (panels[[1]] + patchwork::plot_spacer() +
                              plot_caption +
                              panels[[2]] + panels[[4]] +
                              patchwork::plot_spacer() +
                              panels[[3]] + panels[[5]] + panels[[6]]) +
      patchwork::plot_layout(byrow = TRUE, heights = rep(1, 3),
                             widths = rep(1, 3), ncol = 3, nrow = 3,
                             guides = "collect")
  }
  
  return(patchwork_plots_all)
  
}



#' Plot FRic index
#'
#' This function plots FRic index for a given pair of functional axes and one 
#' or several assemblages. It adds convex hull(s), points and vertices of 
#' 1:N assemblages on the background plot
#'
#' @param ggplot_bg a ggplot object of the plot background retrieved through
#' the \code{\link{background.plot}} function.
#' 
#' @param asb_sp_coord2D a list of matrix (ncol = 2) with coordinates of 
#' species present in each assemblage for a given pair of axes for a given pair 
#' of functional axes.
#' 
#' @param asb_vertices_nD a list (with names as in asb_sp_coord2D) of vectors 
#' with names of species being vertices in n dimensions.
#' 
#' @param plot_sp a logical value indicating whether species of each assemblage 
#'  should be plotted or not. Default: plot_sp = TRUE.
#' 
#' @param color_ch a R color name or an hexadecimal code referring to the color
#'   of the border of the convex hull filled by the pool of species if one
#'   assemblage to plot or a vector of R color names or hexadecimal codes if
#'   several assemblages to plot. If more than one assemblage to plot, the
#'   vector should be formatted as: c(asb1 = "firstRcolorname", asb2 =
#'   "secondRcolorname", ...).
#' 
#' @param color_sp a R color name or an hexadecimal code referring to the color
#'   of species if one assemblage to plot or a vector of R color names or
#'   hexadecimal codes if several assemblages to plot. If more than one
#'   assemblage to plot, the vector should be formatted as: c(asb1 =
#'   "firstRcolorname", asb2 = "secondRcolorname", ...).
#'  
#' @param color_vert a R color name or an hexadecimal code referring to the
#'   color of vertices if one assemblage to plot or a vector of R color names or
#'   hexadecimal codes if several assemblages to plot. If more than one
#'   assemblage to plot, the vector should be formatted as: c(asb1 =
#'   "firstRcolorname", asb2 = "secondRcolorname", ...). If color_vert = NA,
#'   vertices are not plotted (for shapes only defined by color, ie shape
#'   inferior to 20. Otherwise `fill` must also be set to NA).
#'
#' @param fill_ch a R color name or an hexadecimal code referring to the color
#'   of convex hull filling if one assemblage to plot or a vector of R color
#'   names or hexadecimal codes if several assemblages to plot. If more than one
#'   assemblage to plot, the vector should be formatted as: c(asb1 =
#'   "firstRcolorname", asb2 = "secondRcolorname", ...).
#' 
#' @param fill_sp a R color name or an hexadecimal code referring to the color
#'   of species symbol filling (if \code{shape_sp} > 20) if one assemblage to
#'   plot or a vector of R color names or hexadecimal codes if several
#'   assemblages to plot. If more than one assemblage to plot, the vector should
#'   be formatted as: c(asb1 = "firstRcolorname", asb2 = "secondRcolorname",
#'   ...).
#' 
#' @param fill_vert a R color name or an hexadecimal code referring to the color
#'   of vertices symbol filling  (if \code{shape_vert} >20) if one assemblage to
#'   plot or a vector of R color names or hexadecimal codes if several
#'   assemblages to plot. If more than one assemblage to plot, the vector should
#'   be formatted as: c(asb1 = "firstRcolorname", asb2 = "secondRcolorname",
#'   ...). If `fill = NA` and `color = NA`, vertices are not plotted (if
#'   \code{shape_vert} superior to 20
#'   
#' @param shape_sp a numeric value referring to the shape of the symbol used for
#'   species plotting if one assemblage to plot or a vector numeric values if
#'   several assemblages to plot. If more than one assemblage to plot, the
#'   vector should be formatted as: c(asb1 = "firstRshape", asb2 =
#'   "secondRshape", ...).
#' 
#' @param shape_vert a numeric value referring to the shape of the symbol used
#'   for vertices plotting if one assemblage to plot or a vector numeric values
#'   if several assemblages to plot. If more than one assemblage to plot, the
#'   vector should be formatted as: c(asb1 = "firstRshape", asb2 =
#'   "secondRshape", ...).
#' 
#' @param size_sp a numeric value referring to the size of the symbol used for
#'   species plotting if one assemblage to plot or a vector numeric values if
#'   several assemblages to plot. If more than one assemblage to plot, the
#'   vector should be formatted as: c(asb1 = "firstRsize", asb2 =
#'   "secondRsize", ...).
#' 
#' @param size_vert a numeric value referring to the size of the symbol used for
#'   vertices plotting if one assemblage to plot or a vector numeric values if
#'   several assemblages to plot. If more than one assemblage to plot, the
#'   vector should be formatted as: c(asb1 = "firstRsize", asb2 =
#'   "secondRsize", ...).
#' 
#' @param alpha_ch a numeric value referring to the value of transparency of
#'   the convex hull filling (0 = high transparency, 1 = no
#'   transparency) if one assemblage to
#'   plot or a vector numeric values if several assemblages to plot. If more
#'   than one assemblage to plot, the vector should be formatted as: c(asb1 =
#'   "firstRtransparency", asb2 = "secondRtransparency", ...).
#'
#' @return A ggplot object plotting background of multidimensional graphs and
#' FRic convex hulls.
#' 
#' @author Camille Magneville and Sebastien Villeger
#' 
#' @export
#' 
#' @examples
#' # Load Species*Traits dataframe:
#' data("fruits_traits", package = "mFD")
#' 
#' # Load Assemblages*Species dataframe:      
#' data("baskets_fruits_weights", package = "mFD") 
#' 
#' # Load Traits categories dataframe:
#' data("fruits_traits_cat", package = "mFD") 
#'  
#' # Compute functional distance 
#' sp_dist_fruits <- mFD::funct.dist(sp_tr         = fruits_traits,
#'                                   tr_cat        = fruits_traits_cat,
#'                                   metric        = "gower",
#'                                   scale_euclid  = "scale_center",
#'                                   ordinal_var   = "classic",
#'                                   weight_type   = "equal",
#'                                   stop_if_NA    = TRUE)
#'   
#' # Compute functional spaces quality to retrieve species coordinates matrix:
#' fspaces_quality_fruits <- mFD::quality.fspaces(sp_dist = sp_dist_fruits, 
#'  maxdim_pcoa         = 10,
#'  deviation_weighting = "absolute",
#'  fdist_scaling       = FALSE,
#'  fdendro             = "average")
#'  
#' # Retrieve species coordinates matrix:
#'   sp_faxes_coord_fruits <- 
#'     fspaces_quality_fruits$details_fspaces$sp_pc_coord
#'     
#'  # Retrieve species coordinates matrix for the assemblage "basket_1":
#'   sp_filter <- mFD::sp.filter(asb_nm          = c("basket_1"), 
#'                               sp_faxes_coord = sp_faxes_coord_fruits, 
#'                               asb_sp_w       = baskets_fruits_weights)
#'   sp_faxes_coord_fruits_b1 <- sp_filter$`species coordinates`
#'  
#'  # Reduce it to the two studid axes: PC1 and PC2:
#'  sp_faxes_coord_fruits_b1_2D <- sp_faxes_coord_fruits_b1[, c("PC1", "PC2")]
#'
#' # Set faxes limits:
#' # set range of axes if c(NA, NA):
#'  range_sp_coord_fruits  <- range(sp_faxes_coord_fruits)
#'  range_faxes_lim <- range_sp_coord_fruits + c(-1, 1)*(range_sp_coord_fruits[2] - 
#'  range_sp_coord_fruits[1]) * 0.05
#'  
#'  # Retrieve the background plot:
#'  ggplot_bg_fruits <- mFD::background.plot(
#'                                range_faxes = range_faxes_lim, 
#'                                faxes_nm    = c("PC 1", "PC 2"), 
#'                                color_bg    = "grey90") 
#'                                
#'  # Retrieve vertices names:
#'  vert_nm_fruits <- vertices(sp_faxes_coord_fruits_b1_2D, 
#'   order_2D = TRUE, check_input = TRUE)
#'                                
#'  # Plot in white the convex hull of all fruits species:
#'  ggplot_fric <- mFD::fric.plot(
#'            ggplot_bg       = ggplot_bg_fruits,
#'            asb_sp_coord2D  = list(basket_1 = sp_faxes_coord_fruits_b1_2D),
#'            asb_vertices_nD = list(basket_1 = vert_nm_fruits),
#'            plot_sp         = TRUE,
#'            color_ch        = c("basket_1" = "black"), 
#'            fill_ch         = c("basket_1" = "white"), 
#'            alpha_ch        = c("basket_1" = 0.3),
#'            size_sp = c("basket_1" = 1),
#'            shape_sp = c("basket_1" = 16),
#'            color_sp = c("basket_1" = "red"),
#'            fill_sp = c("basket_1" = "red"),
#'            size_vert = c("basket_1" = 1),
#'            color_vert = c("basket_1" = "red"),
#'            fill_vert = c("basket_1" = "red"),
#'            shape_vert = c("basket_1" = 16))
#'  ggplot_fric


fric.plot <- function(ggplot_bg,
                      asb_sp_coord2D,
                      asb_vertices_nD,
                      plot_sp = TRUE,
                      color_ch, fill_ch, alpha_ch,
                      shape_sp, size_sp, color_sp, fill_sp,
                      shape_vert, size_vert, color_vert, fill_vert) {
  
  # names of assemblages
  asb_nm <- names(asb_sp_coord2D)
  
  ## plotting layers ####
  
  # default plot is background
  ggplot_fric <- ggplot_bg
  
  # computing and plotting 2D convex hull(s)
  for (k in asb_nm) {
    # coordinates of species vertices in nD
    k_vertnD_xy <- asb_sp_coord2D[[k]][asb_vertices_nD[[k]], ]
    
    # species being vertices of the convex hull in 2D
    k_vert2D <- vertices(k_vertnD_xy, order_2D = TRUE)
    
    # dataframe with coordinates of vertices
    x <- NULL
    y <- NULL
    k_vertnD_xy <- data.frame(x = k_vertnD_xy[k_vert2D, 1],
                              y = k_vertnD_xy[k_vert2D, 2])
    
    # plotting convex hulls
    ggplot_fric <- ggplot_fric +
      ggplot2::geom_polygon(data = k_vertnD_xy,
                            ggplot2::aes(x = x, y = y),
                            colour = color_ch[k],
                            fill = fill_ch[k],
                            alpha = alpha_ch[k])
  }
  
  
  # plotting species if required ----
  if(plot_sp) {
    ggplot_fric <- sp.plot(ggplot_bg = ggplot_fric,
                           asb_sp_coord2D = asb_sp_coord2D,
                           asb_vertices_nD = asb_vertices_nD,
                           asb_sp_relatw = NULL,
                           shape_sp = shape_sp,
                           size_sp = size_sp,
                           color_sp = color_sp,
                           fill_sp = fill_sp,
                           shape_vert = shape_vert,
                           size_vert = size_vert,
                           color_vert = color_vert,
                           fill_vert = fill_vert)
    
  }# end of if plot_sp

  return(ggplot_fric)
}



#' Plot FDiv indice
#'
#' This plot fDiv indice for a given pair of functional axes and one or several 
#' assemblages. This function adds mean distance to center of gravity of 
#' vertices, points and vertices of 1:N assemblages on the background plot
#'
#' @param ggplot_bg a ggplot object of the plot background retrieved through
#' the \code{\link{background.plot}} function.
#' 
#' @param asb_sp_coord2D a list of matrix (ncol = 2) with coordinates of 
#' species present in each assemblage for a given pair of functional axes.
#' 
#' @param asb_sp_relatw a list of vector gathering species relative weight in
#'   each assemblage. It can be retrieved through the
#'   \code{\link{alpha.fd.multidim}}.
#' 
#' @param asb_vertices_nD a list (with names as in asb_sp_coord2D) of vectors
#'   with names of species being vertices in n dimensions.
#' 
#' @param asb_vertG_coord2D a list (with names as in asb_sp_coord2D) containing 
#' for each assemblage the coordinates of center of gravity of vertices for a 
#' given pair of axes
#' 
#' @param plot_sp a logical value indicating whether species of each assemblage 
#'  should be plotted or not. Default: `plot_sp = TRUE`.
#' 
#' @param color_sp a R color name or an hexadecimal code referring to the color
#'   of species if one assemblage to plot or a vector of R color names or
#'   hexadecimal codes if several assemblages to plot. If more than one
#'   assemblage to plot, the vector should be formatted as: c(asb1 =
#'   "firstRcolorname", asb2 = "secondRcolorname", ...).
#' 
#' @param color_vert a R color name or an hexadecimal code referring to the
#'   color of vertices if one assemblage to plot or a vector of R color names or
#'   hexadecimal codes if several assemblages to plot. If more than one
#'   assemblage to plot, the vector should be formatted as: c(asb1 =
#'   "firstRcolorname", asb2 = "secondRcolorname", ...). If color_vert = NA,
#'   vertices are not plotted (for shapes only defined by color, ie shape
#'   inferior to 20. Otherwise `fill` must also be set to NA).
#'   
#' @param color_vertG a R color name or an hexadecimal code referring to the
#'   color of the center of gravity of vertices. if one assemblage to plot or a
#'   vector of R color names or hexadecimal codes if several assemblages to
#'   plot. If more than one assemblage to plot, the vector should be formatted
#'   as: c(asb1 = "firstRcolorname", asb2 = "secondRcolorname", ...).
#' 
#' @param fill_sp a R color name or an hexadecimal code referring to the color
#'   of species symbol filling (if \code{shape_sp} > 20) if one assemblage to
#'   plot or a vector of R color names or hexadecimal codes if several
#'   assemblages to plot. If more than one assemblage to plot, the vector should
#'   be formatted as: c(asb1 = "firstRcolorname", asb2 = "secondRcolorname",
#'   ...).
#' 
#' @param fill_vert a R color name or an hexadecimal code referring to the color
#'   of vertices symbol filling  (if \code{shape_vert} >20) if one assemblage to
#'   plot or a vector of R color names or hexadecimal codes if several
#'   assemblages to plot. If more than one assemblage to plot, the vector should
#'   be formatted as: c(asb1 = "firstRcolorname", asb2 = "secondRcolorname",
#'   ...). If `fill = NA` and `color = NA`, vertices are not plotted (if
#'   \code{shape_vert} superior to 20
#'   
#' @param fill_vertG a R color name or an hexadecimal code referring to the
#'   color to fill the center of gravity of vertices (if \code{shape_vert} >20)
#'   if one assemblage to plot or a vector of R color names or hexadecimal codes
#'   if several assemblages to plot. If more than one assemblage to plot, the
#'   vector should be formatted as: c(asb1 = "firstRcolorname", asb2 =
#'   "secondRcolorname", ...).
#'  
#' @param shape_sp a numeric value referring to the shape of the symbol used for
#'   species plotting if one assemblage to plot or a vector numeric values if
#'   several assemblages to plot. If more than one assemblage to plot, the
#'   vector should be formatted as: c(asb1 = "firstRshape", asb2 =
#'   "secondRshape", ...).
#' 
#' @param shape_vert a numeric value referring to the shape of the symbol used
#'   for vertices plotting if one assemblage to plot or a vector numeric values
#'   if several assemblages to plot. If more than one assemblage to plot, the
#'   vector should be formatted as: c(asb1 = "firstRshape", asb2 =
#'   "secondRshape", ...).
#'   
#' @param shape_vertG a numeric value referring to the shape to use to plot the
#'   center of gravity of vertices if one assemblage to plot or a vector numeric
#'   values if several assemblages to plot. If more than one assemblage to plot,
#'   the vector should be formatted as: c(asb1 = "firstRshape", asb2 =
#'   "secondRshape", ...).
#'   
#' @param size_vertG a numeric value referring to the size of the symbol used
#'   for the center of gravity of vertices if one assemblage to plot or a vector
#'   numeric values if several assemblages to plot. If more than one assemblage
#'   to plot, the vector should be formatted as: c(asb1 = "firstRsize", asb2 =
#'   "secondRsize", ...).
#'
#' @return A ggplot object plotting background of multidimensional graphs and
#'   FDiv indice.
#' 
#' @author Camille Magneville and Sebastien Villeger
#' 
#' @export
#' 
#' @examples
#' # Load Species*Traits dataframe:
#' data("fruits_traits", package = "mFD")
#' 
#' # Load Assemblages*Species dataframe:      
#' data("baskets_fruits_weights", package = "mFD") 
#' 
#' # Load Traits categories dataframe:
#' data("fruits_traits_cat", package = "mFD") 
#'  
#' # Compute functional distance 
#' sp_dist_fruits <- mFD::funct.dist(sp_tr         = fruits_traits,
#'                                   tr_cat        = fruits_traits_cat,
#'                                   metric        = "gower",
#'                                   scale_euclid  = "scale_center",
#'                                   ordinal_var   = "classic",
#'                                   weight_type   = "equal",
#'                                   stop_if_NA    = TRUE)
#'   
#' # Compute functional spaces quality to retrieve species coordinates matrix:
#' fspaces_quality_fruits <- mFD::quality.fspaces(sp_dist = sp_dist_fruits, 
#'  maxdim_pcoa         = 10,
#'  deviation_weighting = "absolute",
#'  fdist_scaling       = FALSE,
#'  fdendro             = "average")
#'  
#' # Retrieve species coordinates matrix:
#' sp_faxes_coord_fruits <- fspaces_quality_fruits$details_fspaces$sp_pc_coord
#' 
#' # Set faxes limits:
#' # set range of axes if c(NA, NA):
#'  range_sp_coord_fruits  <- range(sp_faxes_coord_fruits)
#'  range_faxes_lim <- range_sp_coord_fruits + 
#'  c(-1, 1)*(range_sp_coord_fruits[2] - 
#'  range_sp_coord_fruits[1]) * 0.05
#'  
#'  # Retrieve the background plot:
#'  ggplot_bg_fruits <- mFD::background.plot(
#'                                range_faxes = range_faxes_lim, 
#'                                faxes_nm    = c("PC 1", "PC 2"), 
#'                                color_bg    = "grey90") 
#'                                
#'  # Retrieve the matrix of species coordinates for "basket_1" and PC1 and PC2
#'  sp_filter <- mFD::sp.filter(asb_nm          = "basket_1", 
#'                              sp_faxes_coord = sp_faxes_coord_fruits, 
#'                              asb_sp_w       = baskets_fruits_weights)
#'  fruits_asb_sp_coord_b1 <- sp_filter$`species coordinates`
#'  fruits_asb_sp_coord2D_b1 <- fruits_asb_sp_coord_b1[, c("PC1", "PC2")]
#'                                
#'  # Use alpha.fd.multidim() function to get inputs to plot FDiv:
#'  alpha_fd_ind <- mFD::alpha.fd.multidim(
#' sp_faxes_coord   = sp_faxes_coord_fruits[ , c("PC1", "PC2", "PC3", "PC4")],
#' asb_sp_w         = baskets_fruits_weights,
#' ind_vect         = c("fdiv"),
#' scaling          = TRUE,
#' check_input      = TRUE,
#' details_returned = TRUE)
#'   
#'  # Retrieve inputs of the fdiv.plot() function for "basket_1" and PC1, PC2
#'  # ... through alpha.fd.multidim outputs:
#'  fruits_asb_sp_relatw_b1 <- 
#'          alpha_fd_ind$details$asb_sp_relatw["basket_1", ]
#'  fruits_asb_vertices_nD_b1_2D <- 
#'                      alpha_fd_ind$details$asb_vert_nm["basket_1"]
#'  fruits_asb_vertG_coord_b1 <- 
#'                      alpha_fd_ind$details$asb_G_coord["basket_1"]
#'  fruits_asb_vertG_coord_b1_2D <- 
#'              fruits_asb_vertG_coord_b1[[1]][c("PC1", "PC2")]
#'  
#'  # Retrieve FDiv plot:
#'  fdiv_plot <- fdiv.plot(
#'            ggplot_bg         = ggplot_bg_fruits,
#'            asb_sp_coord2D    = list(basket_1 = fruits_asb_sp_coord2D_b1),
#'            asb_sp_relatw     = list(basket_1 = fruits_asb_sp_relatw_b1),
#'            asb_vertices_nD   = fruits_asb_vertices_nD_b1_2D,
#'            asb_vertG_coord2D = list(basket_1 = fruits_asb_vertG_coord_b1_2D),
#'            plot_sp           = TRUE,
#'            shape_sp          = 16,
#'            color_sp          = c(basket_1 = "red"),
#'            fill_sp           = "red",
#'            color_vert        = "red",
#'            fill_vert         = "red",
#'            shape_vert        = 16,
#'            shape_vertG       = list(basket_1 = 18),
#'            size_vertG        = list(basket_1 = 2),
#'            color_vertG       = list(basket_1 = "blue"),
#'            fill_vertG        = list(basket_1 = "blue"))
#'  fdiv_plot


fdiv.plot <- function(ggplot_bg,
                      asb_sp_coord2D,
                      asb_sp_relatw,
                      asb_vertices_nD,
                      asb_vertG_coord2D,
                      plot_sp = TRUE,
                      shape_sp, color_sp, fill_sp,
                      shape_vert, color_vert, fill_vert,
                      shape_vertG, size_vertG,
                      color_vertG, fill_vertG) {
  
  # get the names of assemblages:
  asb_nm <- names(asb_sp_coord2D)
  
  # prepare data for plotting ####
  
  # list of dataframe with coordinates of center of gravity of vertices...
  # ... and mean distance to it:
  asb_vertG_xy <- list()
  x <- NULL
  y <- NULL

  for (z in asb_nm) {
    asb_vertG_xy[[z]] <- data.frame(x = asb_vertG_coord2D[[z]][1],
                                     y = asb_vertG_coord2D[[z]][2])
    rownames(asb_vertG_xy[[z]]) <- z
  }
  
  ## plotting layers ####
  
  # default plot is background:
  ggplot_fdiv <- ggplot_bg
  
  # plotting all species if required:
  if (plot_sp) {
    ggplot_fdiv <- sp.plot(ggplot_bg = ggplot_fdiv,
                           asb_sp_coord2D = asb_sp_coord2D,
                           asb_vertices_nD = asb_vertices_nD,
                           asb_sp_relatw = asb_sp_relatw,
                           shape_sp = shape_sp,
                           color_sp = color_sp,
                           fill_sp = fill_sp,
                           shape_vert = shape_vert,
                           color_vert = color_vert,
                           fill_vert = fill_vert)
  }
  
  # plotting center of gravity of vertices in nD and mean distance to it:
  for (k in asb_nm) {
    x <- NULL
    y <- NULL
    ggplot_fdiv <- ggplot_fdiv +
      ggplot2::geom_point(data = asb_vertG_xy[[k]], 
                          ggplot2::aes(x = x , y = y),
                          colour = color_vertG[[k]], fill = fill_vertG[[k]],
                          shape = shape_vertG[[k]], size = size_vertG[[k]])
  }
  
  return(ggplot_fdiv)
  
}



#' Plot FIde index
#' 
#' Plot FIde index given a pair of functional axes for one or several 
#' assemblages. It adds the centroid of species for each assemblage and 
#' segments showing centroid coordinates on functional axes on the background 
#' plot.
#' 
#' @param ggplot_bg a ggplot object of the plot background retrieved through
#' the \code{\link{background.plot}} function.
#' 
#' @param asb_sp_coord2D a list of matrix (ncol = 2) with coordinates of 
#' species present in each assemblage for a given pair of functional axes.
#' 
#' @param asb_sp_relatw a list of vector gathering species relative weight in
#'   each assemblage. It can be retrieved through the
#'   \code{\link{alpha.fd.multidim}}.
#' 
#' @param asb_fide_coord2D a list (with names as in asb_sp_coord2D) of 
#' vectors with coordinates of the centroid of species for each assemblage
#' for a given pair of axes.
#' 
#' @param plot_sp a logical value indicating whether species of each assemblage 
#'  should be plotted or not. Default: `plot_sp = TRUE`
#' 
#' @param color_sp a R color name or an hexadecimal code referring to the color
#'   of species if one assemblage to plot or a vector of R color names or
#'   hexadecimal codes if several assemblages to plot. If more than one
#'   assemblage to plot, the vector should be formatted as: c(asb1 =
#'   "firstRcolorname", asb2 = "secondRcolorname", ...). 
#'  
#' @param color_fide a R color name or an hexadecimal code referring to the
#'   color of species centroid for agiven assemblage if one assemblage to plot
#'   or a vector of R color names or hexadecimal codes if several assemblages to
#'   plot. If more than one assemblage to plot, the vector should be formatted
#'   as: c(asb1 = "firstRcolorname", asb2 = "secondRcolorname", ...).
#' 
#' @param color_segment a R color name or an hexadecimal code referring to the
#'   color of of the segment linking axes and centroid from the studied
#'   assemblage if one assemblage to plot or a vector of R color names or
#'   hexadecimal codes if several assemblages to plot. If more than one
#'   assemblage to plot, the vector should be formatted as: c(asb1 =
#'   "firstRcolorname", asb2 = "secondRcolorname", ...).
#' 
#'@param fill_sp a R color name or an hexadecimal code referring to the color
#'   of species symbol filling (if \code{shape_sp} > 20) if one assemblage to
#'   plot or a vector of R color names or hexadecimal codes if several
#'   assemblages to plot. If more than one assemblage to plot, the vector should
#'   be formatted as: c(asb1 = "firstRcolorname", asb2 = "secondRcolorname",
#'   ...).
#'  
#' @param fill_fide a R color name or an hexadecimal code referring to the color
#'   to fill assemblage centroid symbol (if \code{shape_sp} > 20) if one
#'   assemblage to plot or a vector of R color names or hexadecimal codes if
#'   several assemblages to plot. If more than one assemblage to plot, the
#'   vector should be formatted as: c(asb1 = "firstRcolorname", asb2 =
#'   "secondRcolorname", ...).
#' 
#' @param shape_sp a numeric value referring to the shape of the symbol used for
#'   species plotting if one assemblage to plot or a vector numeric values if
#'   several assemblages to plot. If more than one assemblage to plot, the
#'   vector should be formatted as: c(asb1 = "firstRshape", asb2 =
#'   "secondRshape", ...).
#' 
#' @param shape_fide a numeric value referring to the shape of the symbol used
#'   for fide centroid plotting if one assemblage to plot or a vector numeric
#'   values if several assemblages to plot. If more than one assemblage to plot,
#'   the vector should be formatted as: c(asb1 = "firstRshape", asb2 =
#'   "secondRshape", ...).
#' 
#' @param size_fide a numeric value referring to the size of the symbol used for
#'   fide centroid plotting if one assemblage to plot or a vector numeric values
#'   if several assemblages to plot. If more than one assemblage to plot, the
#'   vector should be formatted as: c(asb1 = "firstRsize", asb2 = "secondRsize",
#'   ...).
#'   
#' @param width_segment a numeric value referring to the width of the segment
#'   linking fide centroid and functional axes if one assemblage to plot or a
#'   vector numeric values if several assemblages to plot. If more than one
#'   assemblage to plot, the vector should be formatted as: c(asb1 =
#'   "firstRsize", asb2 = "secondRsize", ...).
#' 
#' @param linetype_segment a numeric value referring to the linetype of the
#'   segment linking fide centroid and functional axes if one assemblage to plot
#'   or a vector numeric values if several assemblages to plot. If more than one
#'   assemblage to plot, the vector should be formatted as: c(asb1 =
#'   "firstRlinetype", asb2 = "secondRlinetype", ...).
#' 
#' @return A ggplot object with FIde index, species and background.
#' 
#' @author Camille Magneville and Sebastien Villeger
#' 
#' @export
#' 
#' @examples 
#' # Load Species*Traits dataframe:
#' data("fruits_traits", package = "mFD")
#' 
#' # Load Assemblages*Species dataframe:      
#' data("baskets_fruits_weights", package = "mFD") 
#' 
#' # Load Traits categories dataframe:
#' data("fruits_traits_cat", package = "mFD") 
#'  
#' # Compute functional distance 
#' sp_dist_fruits <- mFD::funct.dist(sp_tr         = fruits_traits,
#'                                   tr_cat        = fruits_traits_cat,
#'                                   metric        = "gower",
#'                                   scale_euclid  = "scale_center",
#'                                   ordinal_var   = "classic",
#'                                   weight_type   = "equal",
#'                                   stop_if_NA    = TRUE)
#'   
#' # Compute functional spaces quality to retrieve species coordinates matrix:
#' fspaces_quality_fruits <- mFD::quality.fspaces(sp_dist = sp_dist_fruits, 
#'  maxdim_pcoa         = 10,
#'  deviation_weighting = "absolute",
#'  fdist_scaling       = FALSE,
#'  fdendro             = "average")
#'  
#' # Retrieve species coordinates matrix:
#' sp_faxes_coord_fruits <- fspaces_quality_fruits$details_fspaces$sp_pc_coord
#' 
#' # Set faxes limits:
#' # set range of axes if c(NA, NA):
#'  range_sp_coord_fruits  <- range(sp_faxes_coord_fruits)
#'  range_faxes_lim <- range_sp_coord_fruits + 
#'  c(-1, 1)*(range_sp_coord_fruits[2] - 
#'  range_sp_coord_fruits[1]) * 0.05
#'  
#'  # Retrieve the background plot:
#'  ggplot_bg_fruits <- mFD::background.plot(
#'                                range_faxes = range_faxes_lim, 
#'                                faxes_nm    = c("PC 1", "PC 2"), 
#'                                color_bg    = "grey90") 
#'                                
#'  # Retrieve the matrix of species coordinates for "basket_1" and PC1 and PC2
#'  sp_filter <- mFD::sp.filter(asb_nm          = "basket_1", 
#'                              sp_faxes_coord = sp_faxes_coord_fruits, 
#'                              asb_sp_w       = baskets_fruits_weights)
#'  fruits_asb_sp_coord_b1 <- sp_filter$`species coordinates`
#'  fruits_asb_sp_coord2D_b1 <- fruits_asb_sp_coord_b1[, c("PC1", "PC2")]
#'                                
#'  # Use alpha.fd.multidim() function to get inputs to plot FIde:
#'  alpha_fd_indices_fruits <- mFD::alpha.fd.multidim(
#'  sp_faxes_coord    = sp_faxes_coord_fruits[, c("PC1", "PC2", "PC3", "PC4")],
#'   asb_sp_w         = baskets_fruits_weights,
#'   ind_vect         = c("fide"),
#'   scaling          = TRUE,
#'   check_input      = TRUE,
#'   details_returned = TRUE)
#'   
#'  # Retrieve fide values through alpha.fd.multidim outputs:
#'  fruits_asb_fide_coord2D <- 
#'   alpha_fd_indices_fruits$functional_diversity_indices[c("fide_PC1", 
#'                                                          "fide_PC2")]
#'  fruits_asb_fide_coord2D_b1 <- fruits_asb_fide_coord2D[c("basket_1"), ]
#'  fruits_asb_sp_relatw_b1 <- 
#'          alpha_fd_indices_fruits$details$asb_sp_relatw["basket_1", ]
#'  
#'  # Retrieve FIde plot:
#'  fide_plot <- fide.plot(ggplot_bg = ggplot_bg_fruits,
#'            asb_sp_coord2D = list(basket_1 = fruits_asb_sp_coord2D_b1),
#'            asb_sp_relatw = list(basket_1 = fruits_asb_sp_relatw_b1),
#'            asb_fide_coord2D = list(basket_1 = fruits_asb_fide_coord2D_b1),
#'            plot_sp = TRUE,
#'            shape_sp = 16,
#'            color_sp = "red",
#'            fill_sp = "red",
#'            shape_fide = list(basket_1 = 18),
#'            size_fide = list(basket_1 = 5),
#'            color_fide = list(basket_1 = "blue"),
#'            fill_fide = list(basket_1 = "blue"),
#'            color_segment = list(basket_1 = "red"),
#'            width_segment = list(basket_1 = 1),
#'            linetype_segment = list(basket_1 = "dashed"))
#'            
#'  fide_plot


fide.plot <-function(ggplot_bg,
                    asb_sp_coord2D,
                    asb_sp_relatw,
                    asb_fide_coord2D,
                    plot_sp = TRUE,
                    shape_sp, color_sp, fill_sp,
                    shape_fide, size_fide,
                    color_fide, fill_fide,
                    color_segment, width_segment, linetype_segment) {
  
  # names of assemblages:
  asb_nm <- names(asb_sp_coord2D)
  
  
  ## prepare data for plotting:
  
  # actual limits of plot:
  ggplot_bg_lim <- 
    ggplot2::ggplot_build(ggplot_bg)$layout$panel_params[[1]]$x.range
  
  # list of dataframe with coordinates of center of gravity and links to axes:
  asb_centroid_xy <- list()
  asb_centroidtoaxes_xyxy <- list()
  
  for (z in asb_nm){
    
    cent_z <- asb_fide_coord2D[[z]]
    
    x <- NULL
    y <- NULL
    asb_centroid_xy[[z]] <- data.frame(x = cent_z[1, 1], y = cent_z[1, 2])
    
    asb_centroidtoaxes_xyxy[[z]] <- data.frame(
                          x = c(ggplot_bg_lim[1], cent_z[1, 1]),
                          y = c(cent_z[1, 2], ggplot_bg_lim[1]),
                          xend = rep(cent_z[1, 1], 2),
                          yend = rep(cent_z[1, 2], 2))
  }
  
  
  # plotting layers ####
  
  # default plot is background:
  ggplot_fide <- ggplot_bg
  
  # plot species if required:
  if (plot_sp) {
    ggplot_fide <- sp.plot(ggplot_bg = ggplot_fide,
                          asb_sp_coord2D = asb_sp_coord2D,
                          asb_vertices_nD = NULL,
                          asb_sp_relatw = asb_sp_relatw,
                          shape_sp = shape_sp,
                          color_sp = color_sp,
                          fill_sp = fill_sp)
  }
  
  
  # plotting projection of mean along axes:
  for (k in asb_nm) {
    xend <- NULL
    yend <- NULL
    ggplot_fide <- ggplot_fide +
      ggplot2::geom_segment(data = asb_centroidtoaxes_xyxy[[k]],
                            ggplot2::aes(x = x , 
                                         y = y, xend = xend, yend = yend),
                            colour = color_segment[[k]],
                            size = width_segment[[k]],
                            linetype = linetype_segment[[k]])
  }
  
  # plotting center of gravity of species:
  for (k in asb_nm) {
    ggplot_fide <- ggplot_fide +
      ggplot2::geom_point(data = asb_centroid_xy[[k]], 
                          ggplot2::aes(x = x , y = y),
                          colour = color_fide[[k]], fill = fill_fide[[k]],
                          shape = shape_fide[[k]], size = size_fide[[k]])
  }

  return(ggplot_fide)
}



#' Plot FDis index
#' 
#' This function plots FDis index for a given pair of functional axes and for
#' one or several assemblages. It adds segments between species relative 
#' weights and assemblage cenntroid on the background plot.
#' 
#' @param ggplot_bg a ggplot object of the plot background retrieved through
#' the \code{\link{background.plot}} function.
#' 
#' @param asb_sp_coord2D a list of matrix (ncol = 2) with coordinates of 
#' species present in each assemblage for a given pair of functional axes.
#' 
#' @param asb_sp_relatw a list of vector gathering species relative weight in
#'   each assemblage. It can be retrieved through the
#'   \code{\link{alpha.fd.multidim}}.
#' 
#' @param asb_fide_coord2D a list (with names as in `asb_sp_coord2D`) of 
#' vectors with coordinates of the fide centroid of species for each assemblage
#' for a given pair of axes.
#' 
#' @param plot_sp a logical value indicating whether species of each assemblage 
#'  should be plotted or not. Default: `plot_sp = TRUE`
#' 
#' @param shape_sp a numeric value referring to the shape of the symbol used for
#'   species plotting if one assemblage to plot or a vector numeric values if
#'   several assemblages to plot. If more than one assemblage to plot, the
#'   vector should be formatted as: c(asb1 = "firstRshape", asb2 =
#'   "secondRshape", ...).
#' 
#' @param shape_fide a numeric value referring to the shape of the symbol used
#'   for fide centroid if one assemblage to plot or a vector numeric values if
#'   several assemblages to plot. If more than one assemblage to plot, the
#'   vector should be formatted as: c(asb1 = "firstRshape", asb2 =
#'   "secondRshape", ...).
#' 
#' @param color_sp a R color name or an hexadecimal code referring to the color
#'   of species if one assemblage to plot or a vector of R color names or
#'   hexadecimal codes if several assemblages to plot. If more than one
#'   assemblage to plot, the vector should be formatted as: c(asb1 =
#'   "firstRcolorname", asb2 = "secondRcolorname", ...).
#' 
#' @param color_fide a R color name or an hexadecimal code referring to the 
#' color
#'   of fide centroid if one assemblage to plot or a vector of R color names or
#'   hexadecimal codes if several assemblages to plot. If more than one
#'   assemblage to plot, the vector should be formatted as: c(asb1 =
#'   "firstRcolorname", asb2 = "secondRcolorname", ...).
#' 
#' @param color_segment a R color name or an hexadecimal code referring to the
#'   color of of the segment linking axes and centroid from the studied
#'   assemblage if one assemblage to plot or a vector of R color names or
#'   hexadecimal codes if several assemblages to plot. If more than one
#'   assemblage to plot, the vector should be formatted as: c(asb1 =
#'   "firstRcolorname", asb2 = "secondRcolorname", ...).
#' 
#' @param fill_sp a R color name or an hexadecimal code referring to the color
#'   of species symbol filling (if \code{shape_sp} > 20) if one assemblage to
#'   plot or a vector of R color names or hexadecimal codes if several
#'   assemblages to plot. If more than one assemblage to plot, the vector should
#'   be formatted as: c(asb1 = "firstRcolorname", asb2 = "secondRcolorname",
#'   ...).
#' 
#' @param fill_fide a R color name or an hexadecimal code referring to the color
#'   to fill assemblage centroid symbol (if \code{shape_sp} > 20) if one
#'   assemblage to plot or a vector of R color names or hexadecimal codes if
#'   several assemblages to plot. If more than one assemblage to plot, the
#'   vector should be formatted as: c(asb1 = "firstRcolorname", asb2 =
#'   "secondRcolorname", ...).
#' 
#' @param size_fide a numeric value referring to the size of the symbol used for
#'   fide centroid plotting if one assemblage to plot or a vector numeric values
#'   if several assemblages to plot. If more than one assemblage to plot, the
#'   vector should be formatted as: c(asb1 = "firstRsize", asb2 = "secondRsize",
#'   ...).
#'   
#' @param width_segment a numeric value referring to the width of the segment
#'   linking fide centroid and functional axes if one assemblage to plot or a
#'   vector numeric values if several assemblages to plot. If more than one
#'   assemblage to plot, the vector should be formatted as: c(asb1 =
#'   "firstRsize", asb2 = "secondRsize", ...).
#' 
#' @param linetype_segment a numeric value referring to the linetype of the
#'   segment linking fide centroid and functional axes if one assemblage to plot
#'   or a vector numeric values if several assemblages to plot. If more than one
#'   assemblage to plot, the vector should be formatted as: c(asb1 =
#'   "firstRlinetype", asb2 = "secondRlinetype", ...).
#' 
#' @return A ggplot object showing FDis index for one or several assemblage(s) 
#' and a given pair of functional axes.
#' 
#' @author Camille Magneville and Sebastien Villeger
#' 
#' @export
#' 
#' @examples 
#' # Load Species*Traits dataframe:
#' data("fruits_traits", package = "mFD")
#' 
#' # Load Assemblages*Species dataframe:      
#' data("baskets_fruits_weights", package = "mFD") 
#' 
#' # Load Traits categories dataframe:
#' data("fruits_traits_cat", package = "mFD") 
#'  
#' # Compute functional distance 
#' sp_dist_fruits <- mFD::funct.dist(sp_tr         = fruits_traits,
#'                                   tr_cat        = fruits_traits_cat,
#'                                   metric        = "gower",
#'                                   scale_euclid  = "scale_center",
#'                                   ordinal_var   = "classic",
#'                                   weight_type   = "equal",
#'                                   stop_if_NA    = TRUE)
#'   
#' # Compute functional spaces quality to retrieve species coordinates matrix:
#' fspaces_quality_fruits <- mFD::quality.fspaces(sp_dist = sp_dist_fruits, 
#'  maxdim_pcoa         = 10,
#'  deviation_weighting = "absolute",
#'  fdist_scaling       = FALSE,
#'  fdendro             = "average")
#'  
#' # Retrieve species coordinates matrix:
#' sp_faxes_coord_fruits <- fspaces_quality_fruits$details_fspaces$sp_pc_coord
#' 
#' # Set faxes limits:
#' # set range of axes if c(NA, NA):
#'  range_sp_coord_fruits  <- range(sp_faxes_coord_fruits)
#'  range_faxes_lim <- range_sp_coord_fruits + 
#'  c(-1, 1)*(range_sp_coord_fruits[2] - 
#'  range_sp_coord_fruits[1]) * 0.05
#'  
#'  # Retrieve the background plot:
#'  ggplot_bg_fruits <- mFD::background.plot(
#'                                range_faxes = range_faxes_lim, 
#'                                faxes_nm    = c("PC 1", "PC 2"), 
#'                                color_bg    = "grey90") 
#'                                
#'  # Retrieve the matrix of species coordinates for "basket_1" and PC1 and PC2
#'  sp_filter <- mFD::sp.filter(asb_nm         = "basket_1", 
#'                              sp_faxes_coord = sp_faxes_coord_fruits, 
#'                              asb_sp_w       = baskets_fruits_weights)
#'  fruits_asb_sp_coord_b1 <- sp_filter$`species coordinates`
#'  fruits_asb_sp_coord2D_b1 <- fruits_asb_sp_coord_b1[, c("PC1", "PC2")]
#'                                
#'  # Use alpha.fd.multidim() function to get inputs to plot FIde:
#'  alpha_fd_indices_fruits <- mFD::alpha.fd.multidim(
#'  sp_faxes_coord    = sp_faxes_coord_fruits[, c("PC1", "PC2", "PC3", "PC4")],
#'   asb_sp_w         = baskets_fruits_weights,
#'   ind_vect         = c("fdis"),
#'   scaling          = TRUE,
#'   check_input      = TRUE,
#'   details_returned = TRUE)
#'   
#'  # Retrieve fide values through alpha.fd.multidim outputs:
#'  fruits_asb_fide_coord2D <- 
#'   alpha_fd_indices_fruits$functional_diversity_indices[c("fide_PC1", 
#'                                                          "fide_PC2")]
#'  fruits_asb_fide_coord2D_b1 <- fruits_asb_fide_coord2D[c("basket_1"), ]
#'  fruits_asb_sp_relatw_b1 <- 
#'          alpha_fd_indices_fruits$details$asb_sp_relatw["basket_1", ]
#'
#'  # Retrieve FDis plot:
#'  fdis_plot <- fdis.plot(ggplot_bg = ggplot_bg_fruits,
#'            asb_sp_coord2D = list(basket_1 = fruits_asb_sp_coord2D_b1),
#'            asb_sp_relatw = list(basket_1 = fruits_asb_sp_relatw_b1),
#'            asb_fide_coord2D = list(basket_1 = fruits_asb_fide_coord2D_b1),
#'            plot_sp = TRUE,
#'            shape_sp = 16,
#'            color_sp = "red",
#'            fill_sp = "red",
#'            shape_fide = list(basket_1 = 18),
#'            size_fide = list(basket_1 = 5),
#'            color_fide = list(basket_1 = "blue"),
#'            fill_fide = list(basket_1 = "blue"),
#'            color_segment = list(basket_1 = "red"),
#'            width_segment = list(basket_1 = 1),
#'            linetype_segment = list(basket_1 = "dashed"))
#'            
#'  fdis_plot


fdis.plot <- function(ggplot_bg,
                    asb_sp_coord2D,
                    asb_sp_relatw,
                    asb_fide_coord2D,
                    plot_sp = TRUE,
                    shape_sp, color_sp, fill_sp, 
                    shape_fide, size_fide,
                    color_fide, fill_fide,
                    color_segment, width_segment, linetype_segment) {
  
  # get names of assemblages:
  asb_nm <- names(asb_sp_coord2D)
  
  
  ## retrieve data for plotting:
  
  # list of dataframe with coordinates of center of gravity and links...
  # ... to species:
  
  asb_centroid_xy <- list()
  asb_sptocentroid_xyxy <- list()
  
  for (z in asb_nm) {
    
    sp_z <- asb_sp_coord2D[[z]]
    cent_z <- asb_fide_coord2D[[z]]
    
    x <- NULL
    y <- NULL
    xend <- NULL
    yend <- NULL
    
    asb_centroid_xy[[z]] <- data.frame(x = cent_z[1, 1], y = cent_z[1, 2])
    
    asb_sptocentroid_xyxy[[z]] <- data.frame(x = sp_z[, 1],
                                             y = sp_z[, 2],
                                             xend = cent_z[1, 1],
                                             yend = cent_z[1, 2])
  }
  
  ## plotting layers ####
  
  # default plot is background:
  ggplot_fdis <- ggplot_bg
  
  # plotting species if required:
  
  if(plot_sp) {
    ggplot_fdis <- sp.plot(ggplot_bg = ggplot_fdis,
                           asb_sp_coord2D = asb_sp_coord2D,
                           asb_vertices_nD = NULL,
                           asb_sp_relatw = asb_sp_relatw,
                           shape_sp = shape_sp,
                           color_sp = color_sp,
                           fill_sp = fill_sp)
  }
  
  
  # plotting distance to center of gravity of species:
  for (k in asb_nm) {
    ggplot_fdis <- ggplot_fdis +
      ggplot2::geom_segment(data = asb_sptocentroid_xyxy[[k]],
                            ggplot2::aes(x = x , y = y, xend= xend, 
                                         yend = yend),
                            colour = color_segment[[k]],
                            size = width_segment[[k]],
                            linetype = linetype_segment[[k]])
  }
  
  # plotting center of gravity of species ----
  for (k in asb_nm) {
    ggplot_fdis <- ggplot_fdis +
      ggplot2::geom_point(data = asb_centroid_xy[[k]], 
                          ggplot2::aes(x = x , y = y),
                          colour = color_fide[[k]], fill = fill_fide[[k]],
                          shape = shape_fide[[k]], size = size_fide[[k]])
  }
  
  return(ggplot_fdis)
}



#' Plot FEve index
#' 
#' This function plots FEve index for a given pair of functional axes and one 
#' or several assemblages. It adds Minimum Spanning Tree (MST) of a given 
#' assemblage on the background plot.
#' 
#' @param ggplot_bg a ggplot object of the plot background retrieved through
#' the \code{\link{background.plot}} function.
#' 
#' @param asb_sp_coord2D a list of matrix (ncol = 2) with coordinates of 
#' species present in each assemblage for a given pair of functional axes.
#' 
#' @param asb_sp_relatw a list of vector gathering species relative weight in
#'   each assemblage. It can be retrieved through the
#'   \code{\link{alpha.fd.multidim}}.
#' 
#' @param asb_mst a list (with names as in `asb_sp_coord2D`) of 
#' vectors with names of species linked in the MST of the 
#' studied assemblage. 
#' 
#' @param plot_sp a logical value indicating whether species of each assemblage 
#'  should be plotted or not. Default: `plot_sp = TRUE`
#' 
#' @param shape_sp a numeric value referring to the shape of the symbol used for
#'   species plotting if one assemblage to plot or a vector numeric values if
#'   several assemblages to plot. If more than one assemblage to plot, the
#'   vector should be formatted as: c(asb1 = "firstRshape", asb2 =
#'   "secondRshape", ...).
#'  
#' @param color_sp a R color name or an hexadecimal code referring to the color
#'   of species if one assemblage to plot or a vector of R color names or
#'   hexadecimal codes if several assemblages to plot. If more than one
#'   assemblage to plot, the vector should be formatted as: c(asb1 =
#'   "firstRcolorname", asb2 = "secondRcolorname", ...).
#'  
#' @param color_mst a R color name or an hexadecimal code referring to the color
#'   the MST if one assemblage to plot or a vector of R color names or
#'   hexadecimal codes if several assemblages to plot. If more than one
#'   assemblage to plot, the vector should be formatted as: c(asb1 =
#'   "firstRcolorname", asb2 = "secondRcolorname", ...).
#' 
#' @param fill_sp a R color name or an hexadecimal code referring to the color
#'   of species symbol filling (if \code{shape_sp} > 20) if one assemblage to
#'   plot or a vector of R color names or hexadecimal codes if several
#'   assemblages to plot. If more than one assemblage to plot, the vector should
#'   be formatted as: c(asb1 = "firstRcolorname", asb2 = "secondRcolorname",
#'   ...).
#'  
#' @param width_mst a numeric value referring to the width of segments of the
#'   MST if one assemblage to plot or a vector numeric values if several
#'   assemblages to plot. If more than one assemblage to plot, the vector should
#'   be formatted as: c(asb1 = "firstRsize", asb2 = "secondRsize", ...).
#' 
#' @param linetype_mst a numeric value referring to the linetype of the segments
#'   representing the MST if one assemblage to plot or a vector numeric values
#'   if several assemblages to plot. If more than one assemblage to plot, the
#'   vector should be formatted as: c(asb1 = "firstRlinetype", asb2 =
#'   "secondRlinetype", ...).
#' 
#' @return A ggplot object showing FEve index on the background plot.
#' 
#' @author Camille Magneville and Sebastien Villeger
#' 
#' @export
#' 
#' @examples 
#' # Load Species*Traits dataframe:
#' data("fruits_traits", package = "mFD")
#' 
#' # Load Assemblages*Species dataframe:      
#' data("baskets_fruits_weights", package = "mFD") 
#' 
#' # Load Traits categories dataframe:
#' data("fruits_traits_cat", package = "mFD") 
#'  
#' # Compute functional distance 
#' sp_dist_fruits <- mFD::funct.dist(sp_tr         = fruits_traits,
#'                                   tr_cat        = fruits_traits_cat,
#'                                   metric        = "gower",
#'                                   scale_euclid  = "scale_center",
#'                                   ordinal_var   = "classic",
#'                                   weight_type   = "equal",
#'                                   stop_if_NA    = TRUE)
#'   
#' # Compute functional spaces quality to retrieve species coordinates matrix:
#' fspaces_quality_fruits <- mFD::quality.fspaces(sp_dist = sp_dist_fruits, 
#'  maxdim_pcoa         = 10,
#'  deviation_weighting = "absolute",
#'  fdist_scaling       = FALSE,
#'  fdendro             = "average")
#'  
#' # Retrieve species coordinates matrix:
#' sp_faxes_coord_fruits <- fspaces_quality_fruits$details_fspaces$sp_pc_coord
#' 
#' # Set faxes limits:
#' # set range of axes if c(NA, NA):
#'  range_sp_coord_fruits  <- range(sp_faxes_coord_fruits)
#'  range_faxes_lim <- range_sp_coord_fruits + 
#'  c(-1, 1)*(range_sp_coord_fruits[2] - 
#'  range_sp_coord_fruits[1]) * 0.05
#'  
#'  # Retrieve the background plot:
#'  ggplot_bg_fruits <- mFD::background.plot(
#'                                range_faxes = range_faxes_lim, 
#'                                faxes_nm    = c("PC 1", "PC 2"), 
#'                                color_bg    = "grey90") 
#'                                
#'  # Retrieve the matrix of species coordinates for "basket_1" and PC1 and PC2
#'  sp_filter <- mFD::sp.filter(asb_nm          = "basket_1", 
#'                              sp_faxes_coord = sp_faxes_coord_fruits, 
#'                              asb_sp_w       = baskets_fruits_weights)
#'  fruits_asb_sp_coord_b1 <- sp_filter$`species coordinates`
#'  fruits_asb_sp_coord2D_b1 <- fruits_asb_sp_coord_b1[, c("PC1", "PC2")]
#'                                
#'  # Use alpha.fd.multidim() function to get inputs to plot FIde:
#'  alpha_fd_indices_fruits <- mFD::alpha.fd.multidim(
#'   sp_faxes_coord   = sp_faxes_coord_fruits[, c("PC1", "PC2", "PC3", "PC4")],
#'   asb_sp_w         = baskets_fruits_weights,
#'   ind_vect         = c("feve"),
#'   scaling          = TRUE,
#'   check_input      = TRUE,
#'   details_returned = TRUE)
#'   
#'  # Retrieve fide values through alpha.fd.multidim outputs:
#'  fruits_asb_mst_b1 <- 
#'          alpha_fd_indices_fruits$details$asb_mst["basket_1"]
#'  fruits_asb_sp_coord_b1 <- sp_filter$`species coordinates`
#'  fruits_asb_sp_coord2D_b1 <- fruits_asb_sp_coord_b1[, c("PC1", "PC2")]
#'  fruits_asb_sp_relatw_b1 <- 
#'          alpha_fd_indices_fruits$details$asb_sp_relatw["basket_1", ]
#'          
#'  # Retrieve FEve plot:
#'  feve_plot <- feve.plot(ggplot_bg = ggplot_bg_fruits,
#'            asb_sp_coord2D = list(basket_1 = fruits_asb_sp_coord2D_b1),
#'            asb_sp_relatw = list(basket_1 = fruits_asb_sp_relatw_b1),
#'            asb_mst = fruits_asb_mst_b1,
#'            plot_sp = TRUE,
#'            shape_sp = 16,
#'            color_sp = "red",
#'            fill_sp = "red",
#'            color_mst = list(basket_1 = "blue"),
#'            width_mst = list(basket_1 = 1),
#'            linetype_mst = list(basket_1 = "solid"))
#'            
#'  feve_plot


feve.plot <- function(ggplot_bg,
                      asb_sp_coord2D,
                      asb_sp_relatw,
                      asb_mst,
                      plot_sp = TRUE,
                      shape_sp, color_sp, fill_sp,
                      color_mst, width_mst, linetype_mst) {
  
  # get names of assemblages:
  asb_nm <- names(asb_sp_coord2D)
  
  ## plotting layers ####
  
  # default plot is background:
  ggplot_feve <- ggplot_bg
   
  # plotting species if required:
  if (plot_sp) {
    ggplot_feve <- sp.plot(ggplot_bg = ggplot_feve,
                           asb_sp_coord2D = asb_sp_coord2D,
                           asb_vertices_nD = NULL,
                           asb_sp_relatw = asb_sp_relatw,
                           shape_sp = shape_sp,
                           color_sp = color_sp,
                           fill_sp = fill_sp)
  }
  
  # plotting minimum spanning tree:
  for (k in asb_nm) {
    
    # branches of MST in 2D:
    mst_k <- dendextend::dist_long(asb_mst[[k]])
    k_branches <- mst_k[which(mst_k$distance == 1), ]
    
    x <- NULL
    y <- NULL
    xend <- NULL
    yend <- NULL
    
    k_branches_xyxy <- data.frame(k_branches,
                                x = asb_sp_coord2D[[k]][k_branches$rows, 1],
                                y = asb_sp_coord2D[[k]][k_branches$rows, 2],
                                xend = asb_sp_coord2D[[k]][k_branches$cols, 1],
                                yend = asb_sp_coord2D[[k]][k_branches$cols, 2])
    
    ggplot_feve <- ggplot_feve +
      ggplot2::geom_segment(data = k_branches_xyxy,
                          ggplot2::aes(x = x , y = y, xend = xend, 
                                       yend = yend),
                          colour = color_mst[[k]],
                          size = width_mst[[k]],
                          linetype = linetype_mst[[k]])
  }
  
  
  return(ggplot_feve)
  
}# end of function



#' Plot FNND index
#'
#' This function plots FNND index for a given pair of functional axes and for 
#' one or several assemblages
#' 
#' @param ggplot_bg a ggplot object of the plot background retrieved through
#' the \code{\link{background.plot}} function.
#' 
#' @param asb_sp_coord2D a list of matrix (ncol = 2) with coordinates of 
#' species present in each assemblage for a given pair of functional axes
#' 
#' @param asb_sp_relatw a list of vector gathering species relative weight in
#'   each assemblage. It can be retrieved through the
#'   \code{\link{alpha.fd.multidim}}. 
#' 
#' @param asb_nn_asb a list gathering for each species of a studied assemblage 
#' its nearest neighbour(s) in the assemblage. 
#' 
#' @param plot_sp a logical value indicating whether species of each assemblage 
#'  should be plotted or not. Default: `plot_sp = TRUE`
#' 
#' @param shape_sp a numeric value referring to the shape used to plot species
#'  belonging to the studied assemblage.
#'  
#' @param color_sp a R color name or an hexadecimal code referring to the color
#'   of species if one assemblage to plot or a vector of R color names or
#'   hexadecimal codes if several assemblages to plot. If more than one
#'   assemblage to plot, the vector should be formatted as: c(asb1 =
#'   "firstRcolorname", asb2 = "secondRcolorname", ...).
#'  
#' @param fill_sp a R color name or an hexadecimal code referring to the color
#'   of species symbol filling (if \code{shape_sp} > 20) if one assemblage to
#'   plot or a vector of R color names or hexadecimal codes if several
#'   assemblages to plot. If more than one assemblage to plot, the vector should
#'   be formatted as: c(asb1 = "firstRcolorname", asb2 = "secondRcolorname",
#'   ...).
#'  
#' @param color_segment a R color name or an hexadecimal code referring to the
#'   color of of the segment linking nearest neighbors in a given assemblage or
#'   a vector of R color names or hexadecimal codes if several assemblages to
#'   plot. If more than one assemblage to plot, the vector should be formatted
#'   as: c(asb1 = "firstRcolorname", asb2 = "secondRcolorname", ...).
#' 
#' @param width_segment a numeric value referring to the size of the segment
#'   linking nearest neighbors in a given assemblage or a vector of numeric
#'   values if several assemblages to plot. If more than one assemblage to plot,
#'   the vector should be formatted as: c(asb1 = "firstRwidth", asb2 =
#'   "secondRwidth", ...).
#' 
#' @param linetype_segment a character string referring to the linetype used to
#'   link nearest neighbors in the studied assemblages or a vector of character
#'   strings if several assemblages to plot. If more than one assemblage to
#'   plot, the vector should be formatted as: c(asb1 = "firstRlinetype", asb2 =
#'   "secondRlinetype", ...).
#' 
#' @return A ggplot object with FNND index.
#' 
#' @author Camille Magneville and Sebastien Villeger
#' 
#' @export
#' 
#' @examples 
#' # Load Species*Traits dataframe:
#' data("fruits_traits", package = "mFD")
#' 
#' # Load Assemblages*Species dataframe:      
#' data("baskets_fruits_weights", package = "mFD") 
#' 
#' # Load Traits categories dataframe:
#' data("fruits_traits_cat", package = "mFD") 
#'  
#' # Compute functional distance 
#' sp_dist_fruits <- mFD::funct.dist(sp_tr         = fruits_traits,
#'                                   tr_cat        = fruits_traits_cat,
#'                                   metric        = "gower",
#'                                   scale_euclid  = "scale_center",
#'                                   ordinal_var   = "classic",
#'                                   weight_type   = "equal",
#'                                   stop_if_NA    = TRUE)
#'   
#' # Compute functional spaces quality to retrieve species coordinates matrix:
#' fspaces_quality_fruits <- mFD::quality.fspaces(sp_dist = sp_dist_fruits, 
#'  maxdim_pcoa         = 10,
#'  deviation_weighting = "absolute",
#'  fdist_scaling       = FALSE,
#'  fdendro             = "average")
#'  
#' # Retrieve species coordinates matrix:
#' sp_faxes_coord_fruits <- fspaces_quality_fruits$details_fspaces$sp_pc_coord
#' 
#' # Set faxes limits:
#' # set range of axes if c(NA, NA):
#'  range_sp_coord_fruits  <- range(sp_faxes_coord_fruits)
#'  range_faxes_lim <- range_sp_coord_fruits + 
#'  c(-1, 1)*(range_sp_coord_fruits[2] - 
#'  range_sp_coord_fruits[1]) * 0.05
#'  
#'  # Retrieve the background plot:
#'  ggplot_bg_fruits <- mFD::background.plot(
#'                                range_faxes = range_faxes_lim, 
#'                                faxes_nm    = c("PC 1", "PC 2"), 
#'                                color_bg    = "grey90") 
#'                                
#'  # Retrieve the matrix of species coordinates for "basket_1" and PC1 and PC2
#'  sp_filter <- mFD::sp.filter(asb_nm          = "basket_1", 
#'                              sp_faxes_coord = sp_faxes_coord_fruits, 
#'                              asb_sp_w       = baskets_fruits_weights)
#'  fruits_asb_sp_coord_b1 <- sp_filter$`species coordinates`
#'  fruits_asb_sp_coord2D_b1 <- fruits_asb_sp_coord_b1[, c("PC1", "PC2")]
#'                                
#'  # Use alpha.fd.multidim() function to get inputs to plot FIde:
#'  alpha_fd_indices_fruits <- mFD::alpha.fd.multidim(
#'   sp_faxes_coord   = sp_faxes_coord_fruits[, c("PC1", "PC2", "PC3", "PC4")],
#'   asb_sp_w         = baskets_fruits_weights,
#'   ind_vect         = c("fnnd"),
#'   scaling          = TRUE,
#'   check_input      = TRUE,
#'   details_returned = TRUE)
#'   
#'  # Retrieve nearest neighbor(s) names and relative weights ...
#'  # ... through alpha.fd.multidim outputs:
#'  fruits_asb_nn_asb_b1 <- 
#'          alpha_fd_indices_fruits$details$asb_nm_nn_asb["basket_1"]
#'  fruits_asb_sp_relatw_b1 <- 
#'          alpha_fd_indices_fruits$details$asb_sp_relatw["basket_1", ]
#'
#'  # Retrieve FNND plot:
#'  fnnd_plot <- fnnd.plot(ggplot_bg = ggplot_bg_fruits,
#'            asb_sp_coord2D = list(basket_1 = fruits_asb_sp_coord2D_b1),
#'            asb_sp_relatw = list(basket_1 = fruits_asb_sp_relatw_b1),
#'            asb_nn_asb = fruits_asb_nn_asb_b1 ,
#'            plot_sp = TRUE,
#'            shape_sp = 16,
#'            color_sp = "red",
#'            fill_sp = "red",
#'            color_segment = list(basket_1 = "blue"),
#'            width_segment = list(basket_1 = 1),
#'            linetype_segment = list(basket_1 = "solid"))
#'            
#'  fnnd_plot


fnnd.plot <- function(ggplot_bg,
                    asb_sp_coord2D,
                    asb_sp_relatw,
                    asb_nn_asb,
                    plot_sp = TRUE,
                    shape_sp, color_sp, fill_sp,
                    color_segment, width_segment, linetype_segment) {
  
  # names of assemblages:
  asb_nm <- names(asb_sp_coord2D)
  
  ## plotting layers ####
  
  # default plot is background:
  ggplot_fnnd <- ggplot_bg
  
  # plotting species if required:
  if (plot_sp) {
    ggplot_fnnd <- sp.plot(ggplot_bg = ggplot_fnnd,
                           asb_sp_coord2D = asb_sp_coord2D,
                           asb_vertices_nD = NULL,
                           asb_sp_relatw = asb_sp_relatw,
                           shape_sp = shape_sp,
                           color_sp = color_sp,
                           fill_sp = fill_sp)
  }
  
  # plotting nearest neighbours:
  for (k in asb_nm) {
    
    # nearest neighbours (could be > 1 per species)
    k_sp_xy <- asb_sp_coord2D[[k]]
    k_nn <- asb_nn_asb[[k]]
    
    k_segments_xyxy <- data.frame(sp_f = NULL, sp_nn = NULL, x = NULL, 
                                  y = NULL, xend = NULL, yend = NULL)
    
    for (i in names(k_nn)) {
      
      i_nn <- k_nn[[i]]
      
      k_segments_xyxy <- rbind(k_segments_xyxy,
                             data.frame(sp_f = rep(i, length(i_nn)),
                                        sp_nn = i_nn,
                                        x = k_sp_xy[i, 1],
                                        y = k_sp_xy[i, 2],
                                        xend = k_sp_xy[i_nn, 1],
                                        yend = k_sp_xy[i_nn, 2]))
    }
    
    x <- NULL
    y <- NULL
    xend <- NULL
    yend <- NULL
    ggplot_fnnd <- ggplot_fnnd +
      ggplot2::geom_segment(data = k_segments_xyxy,
                            ggplot2::aes(x = x, y = y, xend = xend, 
                                         yend = yend),
                            colour = color_segment[[k]],
                            size = width_segment[[k]],
                            linetype = linetype_segment[[k]],
                            arrow = grid::arrow(length = grid::unit(0.10,
                                                                    "inches"),
                                                ends = "last",
                                                type = "open"))
  }

  return(ggplot_fnnd)
}



#' Plot FOri
#' 
#' This function plots FOri index for a given pair of functional axes and for 
#' one or several assemblages. It adds the distance of species from the studied
#' to their nearest neighbour(s) from the global pool.
#' 
#' @param ggplot_bg a ggplot object of the plot background retrieved through
#' the \code{\link{background.plot}} function.
#' 
#' @param asb_sp_coord2D a list of matrix (ncol = 2) with coordinates of 
#' species present in each assemblage for a given pair of functional axes.
#' 
#' @param asb_sp_relatw a list of vector gathering species relative weight in
#'   each assemblage. It can be retrieved through the
#'   \code{\link{alpha.fd.multidim}}.
#' 
#' @param asb_nn_pool a list gathering for each species of a studied assemblage 
#' its nearest neighbour(s) in the global pool. 
#' 
#' @param pool_coord2D a matrix (ncol = 2) with coordinates of 
#' species present in the global pool for a given pair of functional axes.
#' 
#' @param plot_pool a logical value indicating whether species of each 
#' assemblage should be plotted or not. Default: `plot_pool = TRUE`.
#' 
#' @param plot_sp a logical value indicating whether species of each assemblage 
#' should be plotted or not. Default: `plot_sp = TRUE`
#' 
#' @param color_pool a R color name or an hexadecimal code referring to the 
#' color of the pool.  This color is also used for FRic convex hull color. 
#' 
#' @param color_sp a R color name or an hexadecimal code referring to the color
#'  of species if one assemblage to plot or a vector of R color names or
#'  hexadecimal codes if several assemblages to plot. If more than one
#'  assemblage to plot, the vector should be formatted as: c(asb1 =
#'  "firstRcolorname", asb2 = "secondRcolorname", ...).
#' 
#' @param fill_pool a R color name or an hexadecimal code referring to the 
#'   colour to fill species symbol (if \code{shape_sp} > 20) and the assemblage 
#'   convex hull. 
#'  
#' @param fill_sp a R color name or an hexadecimal code referring to the color
#'   of species symbol filling (if \code{shape_sp} > 20) if one assemblage to
#'   plot or a vector of R color names or hexadecimal codes if several
#'   assemblages to plot. If more than one assemblage to plot, the vector should
#'   be formatted as: c(asb1 = "firstRcolorname", asb2 = "secondRcolorname",
#'   ...).
#' 
#' @param shape_pool a numeric value referring to the shape used to plot species
#'  pool. 
#'  
#' @param shape_sp a numeric value referring to the shape of the symbol used for
#'   species plotting if one assemblage to plot or a vector numeric values if
#'   several assemblages to plot. If more than one assemblage to plot, the
#'   vector should be formatted as: c(asb1 = "firstRshape", asb2 =
#'   "secondRshape", ...).
#' 
#' @param size_pool a numeric value referring to the size of species belonging 
#' to the global pool. 
#' 
#' @param color_segment color_segment a R color name or an hexadecimal code
#'   referring to the color of of the segment linking nearest neighbors in the
#'   global pool or a vector of R color names or hexadecimal codes if several
#'   assemblages to plot. If more than one assemblage to plot, the vector should
#'   be formatted as: c(asb1 = "firstRcolorname", asb2 = "secondRcolorname",
#'   ...).
#' 
#' @param width_segment a numeric value referring to the size of the segment
#'   linking nearest neighbors in the global pool or a vector of numeric
#'   values if several assemblages to plot. If more than one assemblage to plot,
#'   the vector should be formatted as: c(asb1 = "firstRwidth", asb2 =
#'   "secondRwidth", ...).
#' 
#' @param linetype_segment a character string referring to the linetype used to
#'   link nearest neighbors in the global pool or a vector of character
#'   strings if several assemblages to plot. If more than one assemblage to
#'   plot, the vector should be formatted as: c(asb1 = "firstRlinetype", asb2 =
#'   "secondRlinetype", ...). 
#' 
#' @return A ggplot object with FOri index.
#' 
#' @author Camille Magneville and Sebastien Villeger
#' 
#' @export
#' 
#' @examples
#' \dontrun{
#' # Load Species*Traits dataframe:
#' data("fruits_traits", package = "mFD")
#' 
#' # Load Assemblages*Species dataframe:      
#' data("baskets_fruits_weights", package = "mFD") 
#' 
#' # Load Traits categories dataframe:
#' data("fruits_traits_cat", package = "mFD") 
#'  
#' # Compute functional distance 
#' sp_dist_fruits <- mFD::funct.dist(sp_tr         = fruits_traits,
#'                                   tr_cat        = fruits_traits_cat,
#'                                   metric        = "gower",
#'                                   scale_euclid  = "scale_center",
#'                                   ordinal_var   = "classic",
#'                                   weight_type   = "equal",
#'                                   stop_if_NA    = TRUE)
#'   
#' # Compute functional spaces quality to retrieve species coordinates matrix:
#' fspaces_quality_fruits <- mFD::quality.fspaces(sp_dist = sp_dist_fruits, 
#'  maxdim_pcoa         = 10,
#'  deviation_weighting = "absolute",
#'  fdist_scaling       = FALSE,
#'  fdendro             = "average")
#'  
#' # Retrieve species coordinates matrix:
#' sp_faxes_coord_fruits <- fspaces_quality_fruits$details_fspaces$sp_pc_coord
#' 
#' # Set faxes limits:
#' # set range of axes if c(NA, NA):
#'  range_sp_coord_fruits  <- range(sp_faxes_coord_fruits)
#'  range_faxes_lim <- range_sp_coord_fruits + 
#'  c(-1, 1)*(range_sp_coord_fruits[2] - 
#'  range_sp_coord_fruits[1]) * 0.05
#'  
#'  # Retrieve the background plot:
#'  ggplot_bg_fruits <- mFD::background.plot(
#'                                range_faxes = range_faxes_lim, 
#'                                faxes_nm    = c("PC 1", "PC 2"), 
#'                                color_bg    = "grey90") 
#'                                
#'  # Retrieve the matrix of species coordinates for "basket_1" and PC1 and PC2
#'  sp_filter <- mFD::sp.filter(asb_nm          = "basket_1", 
#'                              sp_faxes_coord = sp_faxes_coord_fruits, 
#'                              asb_sp_w       = baskets_fruits_weights)
#'  fruits_asb_sp_coord_b1 <- sp_filter$`species coordinates`
#'  fruits_asb_sp_coord2D_b1 <- fruits_asb_sp_coord_b1[, c("PC1", "PC2")]
#'                                
#'  # Use alpha.fd.multidim() function to get inputs to plot FIde:
#'  alpha_fd_indices_fruits <- mFD::alpha.fd.multidim(
#'   sp_faxes_coord   = sp_faxes_coord_fruits[, c("PC1", "PC2", "PC3", "PC4")],
#'   asb_sp_w         = baskets_fruits_weights,
#'   ind_vect         = c("fori"),
#'   scaling          = TRUE,
#'   check_input      = TRUE,
#'   details_returned = TRUE)
#'   
#'  # Retrieve nearest neighbor(s) names through alpha.fd.multidim outputs:
#'  fruits_asb_nn_pool_b1 <- 
#'          alpha_fd_indices_fruits$details$asb_nm_nn_pool["basket_1"]
#'
#'  # Retrieve FNND plot:
#'  fori_plot <- fori.plot(ggplot_bg = ggplot_bg_fruits,
#'            asb_sp_coord2D = list(basket_1 = fruits_asb_sp_coord2D_b1),
#'            asb_sp_relatw = list(basket_1 = fruits_asb_sp_relatw_b1),
#'            asb_nn_pool = fruits_asb_nn_pool_b1,
#'            pool_coord2D = sp_faxes_coord_fruits[, c("PC1", "PC2")],
#'            plot_pool = TRUE,
#'            plot_sp = TRUE,
#'            shape_sp = 16,
#'            color_sp = "red",
#'            fill_sp = "red",
#'            shape_pool = 4,
#'            size_pool = 2,
#'            color_pool = "grey",
#'            fill_pool = "grey",
#'            color_segment = list(basket_1 = "red"),
#'            width_segment = list(basket_1 = 1),
#'            linetype_segment = list(basket_1 = "solid"))
#'            
#'  fori_plot
#' }

fori.plot <- function(ggplot_bg,
                      asb_sp_coord2D,
                      asb_sp_relatw,
                      asb_nn_pool,
                      pool_coord2D,
                      plot_pool = TRUE,
                      plot_sp = TRUE,
                      shape_pool, size_pool, color_pool, fill_pool,
                      shape_sp, color_sp, fill_sp,
                      color_segment, width_segment, linetype_segment) {
  
  # names of assemblages:
  asb_nm <- names(asb_sp_coord2D)
  
  
  ## plotting layers ####
  
  # default plot is background:
  ggplot_fori <- ggplot_bg
  
  # plotting species of the pool if required:
  if (plot_pool) {
    ggplot_fori <- pool.plot(ggplot_bg = ggplot_fori,
                            sp_coord2D = pool_coord2D,
                            vertices_nD = NULL,
                            shape_pool = shape_pool, size_pool = size_pool,
                            color_pool = color_pool, fill_pool = fill_pool)
  }
  
  # plotting species if required:
  if (plot_sp) {
    ggplot_fori <- sp.plot(ggplot_bg = ggplot_fori,
                           asb_sp_coord2D = asb_sp_coord2D,
                           asb_vertices_nD = NULL,
                           asb_sp_relatw = asb_sp_relatw,
                           shape_sp = shape_sp,
                           color_sp = color_sp,
                           fill_sp = fill_sp)
  }
  
  
  # plotting nearest neighbour(s) from the pool (could be >1 per species):
  for (k in asb_nm) {
    
    k_nn <- asb_nn_pool[[k]]
    
    k_segments_xyxy <- data.frame(sp_f = NULL, sp_nn = NULL, x = NULL, 
                                  y = NULL, xend = NULL,  yend = NULL)
    
    for (i in names(k_nn)) {
      i_nn <- k_nn[[i]]
      k_segments_xyxy <- rbind(k_segments_xyxy,
                             data.frame(sp_f = rep(i, length(i_nn)),
                                        sp_nn = i_nn,
                                        x = pool_coord2D[i, 1],
                                        y = pool_coord2D[i, 2],
                                        xend = pool_coord2D[i_nn, 1],
                                        yend = pool_coord2D[i_nn, 2]))
    }
    
    x <- NULL
    y <- NULL
    xend <- NULL
    yend <- NULL
    ggplot_fori <- ggplot_fori +
      ggplot2::geom_segment(data = k_segments_xyxy,
                            ggplot2::aes(x = x , y = y, xend = xend, 
                                         yend = yend),
                            colour = color_segment[[k]],
                            size = width_segment[[k]],
                            linetype = linetype_segment[[k]],
                            arrow = grid::arrow(length = grid::unit(0.10,
                                                                    "inches"),
                                                ends = "last",
                                                type = "open"))
  }
  
  return(ggplot_fori)
}



#' Plot FSpe
#' 
#' This function plots FSpe index for a given pair of functional axes and for
#' one or several assemblages. It adds the mean position of species from the 
#' global pool and the distance of each species from the studied assemblage(s) 
#' on the background plot
#' 
#' @param ggplot_bg a ggplot object of the plot background retrieved through
#' the \code{\link{background.plot}} function.
#' 
#' @param asb_sp_coord2D a list of matrix (ncol = 2) with coordinates of 
#' species present in each assemblage for a given pair of functional axes.
#' 
#' @param asb_sp_relatw a list of vector gathering species relative weight in
#'   each assemblage. It can be retrieved through the
#'   \code{\link{alpha.fd.multidim}}. 
#' 
#' @param center_coord2D a list containing the coordinates of the center of the
#' global pool for two given functional axes 
#' 
#' @param pool_coord2D a list of matrix (ncol = 2) with coordinates of 
#' species present in the global pool for a given pair of functional axes.
#' 
#' @param plot_pool a logical value indicating whether species of each 
#' assemblage should be plotted or not. Default: `plot_pool = TRUE`.
#' 
#' @param plot_sp a logical value indicating whether species of each assemblage 
#' should be plotted or not. Default: `plot_sp = TRUE`
#' 
#' @param color_pool a R color name or an hexadecimal code referring to the 
#' color of the pool.  This color is also used for FRic convex hull color. 
#' Default: `color_pool = "#0072B2"`.
#' 
#' @param color_sp a R color name or an hexadecimal code referring to the color
#'   of species if one assemblage to plot or a vector of R color names or
#'   hexadecimal codes if several assemblages to plot. If more than one
#'   assemblage to plot, the vector should be formatted as: c(asb1 =
#'   "firstRcolorname", asb2 = "secondRcolorname", ...).
#' 
#' @param color_center a R color name or an hexadecimal code referring to the 
#' color of the center of the global pool. 
#' 
#' @param color_segment a R color name or an hexadecimal code referring to the
#'   color of the segments linking each species of a given assemblage to the
#'   center of functional space if one assemblage to plot or a vector of R color
#'   names or hexadecimal codes if several assemblages to plot. If more than one
#'   assemblage to plot, the vector should be formatted as: c(asb1 =
#'   "firstRcolorname", asb2 = "secondRcolorname", ...).
#' 
#' @param fill_pool a R color name or an hexadecimal code referring to the 
#' colour to fill species symbol (if \code{shape_sp} > 20) and the assemblage 
#' convex hull. 
#'  
#' @param fill_sp a R color name or an hexadecimal code referring to the color
#'   of species symbol filling (if \code{shape_sp} > 20) if one assemblage to
#'   plot or a vector of R color names or hexadecimal codes if several
#'   assemblages to plot. If more than one assemblage to plot, the vector should
#'   be formatted as: c(asb1 = "firstRcolorname", asb2 = "secondRcolorname",
#'   ...).
#'  
#' @param fill_center a R color name or an hexadecimal code referring to the 
#' colour to fill the center of the global pool (if \code{shape_sp} > 20). 
#' 
#' @param shape_pool a numeric value referring to the shape used to plot 
#'   species pool. 
#'  
#' @param shape_sp a numeric value referring to the shape of the symbol used for
#'   species plotting if one assemblage to plot or a vector numeric values if
#'   several assemblages to plot. If more than one assemblage to plot, the
#'   vector should be formatted as: c(asb1 = "firstRshape", asb2 =
#'   "secondRshape", ...). 
#'  
#' @param shape_center a numeric value referring to the shape used to plot the 
#' center of the global pool.
#' 
#' @param size_pool a numeric value referring to the size of species belonging 
#' to the global pool.
#' 
#' @param size_center a numeric value referring to the size of the center of 
#'   the global pool. 
#' 
#' @param width_segment a numeric value referring to the
#'   width of the segments linking each species of a given assemblage to the
#'   center of functional space if one assemblage to plot or a vector of R color
#'   names or hexadecimal codes if several assemblages to plot. If more than one
#'   assemblage to plot, the vector should be formatted as: c(asb1 =
#'   "firstRwidth", asb2 = "secondRwidth", ...).
#' 
#' @param linetype_segment a character string referring to the
#'   linetype of the segment linking each species of a given assemblage to the
#'   center of functional space if one assemblage to plot or a vector of R color
#'   names or hexadecimal codes if several assemblages to plot. If more than one
#'   assemblage to plot, the vector should be formatted as: c(asb1 =
#'   "firstRlinetype", asb2 = "secondRlinetype", ...).
#' 
#' @return A ggplot object with FSpe index on the background plot.
#' 
#' @author Camille Magneville and Sebastien Villeger
#' 
#' @export
#' 
#' @examples 
#' \dontrun{
#' # Load Species*Traits dataframe:
#' data("fruits_traits", package = "mFD")
#' 
#' # Load Assemblages*Species dataframe:      
#' data("baskets_fruits_weights", package = "mFD") 
#' 
#' # Load Traits categories dataframe:
#' data("fruits_traits_cat", package = "mFD") 
#'  
#' # Compute functional distance 
#' sp_dist_fruits <- mFD::funct.dist(sp_tr         = fruits_traits,
#'                                   tr_cat        = fruits_traits_cat,
#'                                   metric        = "gower",
#'                                   scale_euclid  = "scale_center",
#'                                   ordinal_var   = "classic",
#'                                   weight_type   = "equal",
#'                                   stop_if_NA    = TRUE)
#'   
#' # Compute functional spaces quality to retrieve species coordinates matrix:
#' fspaces_quality_fruits <- mFD::quality.fspaces(sp_dist = sp_dist_fruits, 
#'  maxdim_pcoa         = 10,
#'  deviation_weighting = "absolute",
#'  fdist_scaling       = FALSE,
#'  fdendro             = "average")
#'  
#' # Retrieve species coordinates matrix:
#' sp_faxes_coord_fruits <- fspaces_quality_fruits$details_fspaces$sp_pc_coord
#' 
#' # Set faxes limits:
#' # set range of axes if c(NA, NA):
#'  range_sp_coord_fruits  <- range(sp_faxes_coord_fruits)
#'  range_faxes_lim <- range_sp_coord_fruits + 
#'  c(-1, 1)*(range_sp_coord_fruits[2] - 
#'  range_sp_coord_fruits[1]) * 0.05
#'  
#'  # Retrieve the background plot:
#'  ggplot_bg_fruits <- mFD::background.plot(
#'                                range_faxes = range_faxes_lim, 
#'                                faxes_nm    = c("PC 1", "PC 2"), 
#'                                color_bg    = "grey90") 
#'                                
#'  # Retrieve the matrix of species coordinates for "basket_1" and PC1 and PC2
#'  sp_filter <- mFD::sp.filter(asb_nm          = "basket_1", 
#'                              sp_faxes_coord = sp_faxes_coord_fruits, 
#'                              asb_sp_w       = baskets_fruits_weights)
#'  fruits_asb_sp_coord_b1 <- sp_filter$`species coordinates`
#'  fruits_asb_sp_coord2D_b1 <- fruits_asb_sp_coord_b1[, c("PC1", "PC2")]
#'                                
#'  # Use alpha.fd.multidim() function to get inputs to plot FIde:
#'  alpha_fd_indices_fruits <- mFD::alpha.fd.multidim(
#'   sp_faxes_coord   = sp_faxes_coord_fruits[, c("PC1", "PC2", "PC3", "PC4")],
#'   asb_sp_w         = baskets_fruits_weights,
#'   ind_vect         = c("fspe"),
#'   scaling          = TRUE,
#'   check_input      = TRUE,
#'   details_returned = TRUE)
#'   
#'  # Retrieve nearest neighbor(s) names through alpha.fd.multidim outputs:
#'  fruits_center_coord2D <- 
#'          alpha_fd_indices_fruits$details$pool_O_coord[c("PC1", "PC2")]
#'
#'  
#'  # Retrieve FNND plot:
#'  fspe_plot <- fspe.plot(ggplot_bg = ggplot_bg_fruits,
#'            asb_sp_coord2D = list(basket_1 = fruits_asb_sp_coord2D_b1),
#'            asb_sp_relatw = list(basket_1 = fruits_asb_sp_relatw_b1),
#'            center_coord2D = fruits_center_coord2D,
#'            pool_coord2D = sp_faxes_coord_fruits[, c("PC1", "PC2")],
#'            plot_pool = TRUE,
#'            plot_sp = TRUE,
#'            shape_sp = 16,
#'            color_sp = "red",
#'            fill_sp = "red",
#'            shape_pool = 4,
#'            size_pool = 2,
#'            color_pool = "grey",
#'            fill_pool = "grey",
#'            color_center = "blue", 
#'            fill_center = "blue",
#'            shape_center = 18, 
#'            size_center = 3,
#'            color_segment = list(basket_1 = "red"),
#'            width_segment = list(basket_1 = 1),
#'            linetype_segment = list(basket_1 = "solid"))
#'            
#'  fspe_plot
#' }

fspe.plot <- function(ggplot_bg,
                      asb_sp_coord2D,
                      asb_sp_relatw,
                      center_coord2D,
                      pool_coord2D,
                      plot_pool = TRUE,
                      plot_sp = TRUE,
                      shape_pool, size_pool, color_pool, fill_pool,
                      shape_sp, color_sp, fill_sp,
                      color_center, fill_center,
                      shape_center, size_center,
                      color_segment, width_segment, linetype_segment) {
  
  # names of assemblages:
  asb_nm <- names(asb_sp_coord2D)
  
  ## plotting layers ####
  
  # default plot is background:
  ggplot_fspe <- ggplot_bg
  
  # plotting species of the pool if required:
  if (plot_pool) {
    ggplot_fspe <- pool.plot(ggplot_bg = ggplot_fspe,
                            sp_coord2D = pool_coord2D,
                            vertices_nD = NULL,
                            shape_pool = shape_pool, size_pool = size_pool,
                            color_pool = color_pool, fill_pool = fill_pool)
  }
  
  # plotting species if required:
  if(plot_sp) {
    ggplot_fspe <- sp.plot(ggplot_bg = ggplot_fspe,
                           asb_sp_coord2D = asb_sp_coord2D,
                           asb_vertices_nD = NULL,
                           asb_sp_relatw = asb_sp_relatw,
                           shape_sp = shape_sp,
                           color_sp = color_sp,
                           fill_sp = fill_sp)
  }
  
  # coordinates of center of functional space:
  center_xy <- data.frame(x = center_coord2D[1], y = center_coord2D[2],
                         row.names = NULL )
  
  
  # plotting distance to center of space:
  for (k in asb_nm) {
    
    # coordinates of segments to center of functional space:
    k_sptocenter_xyxy <- data.frame(x = asb_sp_coord2D[[k]][, 1],
                                  y = asb_sp_coord2D[[k]][, 2],
                                  xend = center_xy[1, 1],
                                  yend = center_xy[1, 2])
    # plotting segments:
    x <- NULL
    y <- NULL
    xend <- NULL
    yend <- NULL
    ggplot_fspe <- ggplot_fspe +
      ggplot2::geom_segment(data = k_sptocenter_xyxy,
                            ggplot2::aes(x = x , y = y, xend = xend, 
                                          yend = yend),
                            colour = color_segment[[k]],
                            size = width_segment[[k]],
                            linetype = linetype_segment[[k]])
  }
  
  # plotting center of space:
  ggplot_fspe <- ggplot_fspe +
    ggplot2::geom_point(data = center_xy, ggplot2::aes(x = x , y = y),
                        colour = color_center, fill = fill_center,
                        shape = shape_center, size = size_center)
  
  return(ggplot_fspe)
}

Try the mFD package in your browser

Any scripts or data that you put into this service are public.

mFD documentation built on May 29, 2024, 7:25 a.m.