R/plot.R

#' @title plot a pkggraph object
#' @author Nikhil Singh
#' @description plot a pkggraph object
#' @param x plot object generated by \code{\link{neighborhood_graph}} or
#'   \code{\link{make_neighborhood_graph}}
#' @param ... additional arguments (See details)
#' @seealso \code{\link{neighborhood_graph}},
#'   \code{\link{make_neighborhood_graph}}, \code{\link{get_neighborhood}}
#' @details \itemize{ \item \code{background}: "black" or "white". Default is
#'   `black` \item \code{nodeImportance}: "in", "out" or "both", in - Node will
#'   be considered important(and increased size) if more incoming. out - Node
#'   will be considered important if more outgoing. both - Node importance will
#'   be calculated on both incoming and outgoing. True for all the nodes.
#'   Default is `both` \item \code{edgeLabel}: logical. TRUE if edge label has
#'   to be shown. Default is FALSE}
#' @examples
#' \dontrun{
#'   pkggraph::init(local = TRUE)
#'   plot_obj <- pkggraph::neighborhood_graph("hash")
#'   plot(plot_obj)
#'
#'   plot_obj <- pkggraph::neighborhood_graph("tidytext")
#'   plot(plot_obj
#'        , background     = "white"
#'        , nodeImportance = "out")
#'   plot_obj <- pkggraph::neighborhood_graph(c("hash","tokenizers")
#'                                            , interconnect = FALSE
#'                                            )
#'   plot(plot_obj,  background = "white")
#'   }
#' @export
# plot <- function(x, ...){
#   UseMethod("plot")
# }
plot.pkggraph <- function(x, ...) {

  graph_object <- x[[1]]

  if(inherits(x[[1]], "igraph")){
    network_object <- intergraph::asNetwork(graph_object)
  } else {
    network_object <- graph_object
  }

  # check if graph is empty
  if(network::network.size(network_object) == 0){
    stop("Graph is empty.")
  }

  arg_list        <- list(...)
  background      <- "black"
  nodeImportance  <- "both"
  edgeText        <- FALSE

  if("background" %in% names(arg_list)){
    background = arg_list$background
  }

  if("nodeImportance" %in% names(arg_list)){
    nodeImportance = arg_list$nodeImportance
  }

  if("edgeText" %in% names(arg_list)){
    edgeText = arg_list$edgeText
  }

  stopifnot(background %in% c("black", "white") && length(background) == 1)

  stopifnot(length(nodeImportance) == 1 &&
              nodeImportance %in% c("in", "out", "both", "none"))

  stopifnot(length(edgeText) == 1 &&
              edgeText %in% c(TRUE, FALSE))

  edgeColors <- RColorBrewer::brewer.pal(5,"Set1")
  names(edgeColors) <- c("Depends", "Imports", "LinkingTo", "Suggests", "Enhances")
  colScale <- scale_colour_manual(name = "grp", values = edgeColors)

  theme_def <- theme(
    axis.text = element_blank(),
    axis.title = element_blank(),
    panel.background = element_rect(fill = "grey25"),
    panel.grid = element_blank()
  )

  if(nodeImportance == "in"){
    cs <- Matrix::colSums(igraph::get.adjacency(graph_object))
    network::set.vertex.attribute(network_object, "importance", cs)
  }
  else if(nodeImportance == "out"){
    rs <- Matrix::rowSums(igraph::get.adjacency(graph_object))
    network::set.vertex.attribute(network_object, "importance", rs)
  }
  else if(nodeImportance == "both"){
    cs <- Matrix::colSums(igraph::get.adjacency(graph_object))
    rs <- Matrix::rowSums(igraph::get.adjacency(graph_object))

    network::set.vertex.attribute(network_object, "importance", cs + rs)

  }

  set.seed(1)
  suppressWarnings(
    base_plot <- ggplot2::ggplot(network_object, arrow.gap = 0.025
                                 , aes_string(x = "x"
                                              , y = "y"
                                              , xend = "xend"
                                              , yend = "yend"
                                 )) +
      geom_edges(arrow = arrow(length = unit(6, "pt")
                               , type = "closed"
                               , angle = 30)
                 , aes_string(color = "relation")
                 , curvature = 0.1) +
      geom_nodelabel_repel(aes_string(label = "vertex.names")
                           , box.padding = unit(0.1, "lines")) +
      guides(color = guide_legend("Relation")) +
      theme_facet() +
      theme(legend.justification = "top")
  )

  if(edgeText){
    base_plot <- base_plot +
      suppressWarnings(geom_edgetext_repel(aes_string(label = "relation")
                                           , color = "white"
                                           , fill = "grey25"
                                           , box.padding = unit(0, "lines")
                                           )
                       )
  }

  if(background == "black"){
    base_plot <- base_plot + theme_def
  }

  if(nodeImportance != "none"){
    base_plot <- base_plot + geom_nodes(color = "gold"
                                        , aes_string(size = "importance")
                                        , shape = 19
                                        , show.legend = FALSE
    )
  }
  else{
    base_plot <- base_plot + geom_nodes(color = "gold"
                                        , shape = 19
                                        , show.legend = FALSE
    )
  }

  base_plot + colScale
}
talegari/pkggraph documentation built on May 6, 2019, 10:50 a.m.