Diff of /R/3-4.other_plot.R [000000] .. [13df9a]

Switch to unified view

a b/R/3-4.other_plot.R
1
# ========4.1.other_plot========
2
#
3
#' Transfer an igraph object to a ggig
4
#'
5
#' @param go igraph or meatnet
6
#' @param coors coordinates for nodes,columns: name, X, Y
7
#'
8
#' @return ggig object
9
#' @export
10
#' @family plot
11
#' @examples
12
#' as.ggig(co_net, coors = c_net_layout(co_net)) -> ggig
13
#' plot(ggig)
14
#' as.ggig(multi1, coors = c_net_layout(multi1)) -> ggig
15
#' plot(ggig, labels_num = 0.3)
16
as.ggig <- function(go, coors = NULL) {
17
  list(n_index = get_n(go), v_index = get_v(go), e_index = get_e(go)) -> net_par_res
18
19
  if (is.null(coors)) coors <- c_net_layout(go)
20
  coors <- get_coors(coors, go)
21
22
  # add coors
23
  coors <- coors[, 1:3] %>% na.omit()
24
  net_par_res$v_index %<>% dplyr::left_join(., coors, by = "name", suffix = c("", ".1"))
25
  net_par_res$e_index %<>% dplyr::left_join(., coors, by = c("from" = "name")) %>%
26
    dplyr::rename(X1 = "X", Y1 = "Y") %>%
27
    dplyr::left_join(., coors, by = c("to" = "name")) %>%
28
    dplyr::rename(X2 = "X", Y2 = "Y")
29
30
  class(net_par_res) <- c("ggig", "list")
31
  return(net_par_res)
32
}
33
34
#' Plot a ggig
35
#'
36
#' @param x ggig object
37
#' @inheritParams c_net_plot
38
#'
39
#' @family plot
40
#' @return ggplot
41
#' @exportS3Method
42
#' @method plot ggig
43
plot.ggig <- function(x, coors = NULL, ..., labels_num = NULL,
44
                      vertex_size_range = NULL, edge_width_range = NULL,
45
                      plot_module = FALSE,
46
                      mark_module = FALSE, mark_color = NULL, mark_alpha = 0.3,
47
                      module_label = FALSE, module_label_cex = 2, module_label_color = "black",
48
                      module_label_just = c(0.5, 0.5),
49
                      legend_number = FALSE, legend = TRUE, legend_cex = 1,
50
                      legend_position = c(left_leg_x = -2, left_leg_y = 1, right_leg_x = 1.2, right_leg_y = 1),
51
                      group_legend_title = NULL, group_legend_order = NULL,
52
                      color_legend = TRUE, color_legend_order = NULL,
53
                      size_legend = FALSE, size_legend_title = "Node Size",
54
                      edge_legend = TRUE, edge_legend_title = "Edge type", edge_legend_order = NULL,
55
                      width_legend = FALSE, width_legend_title = "Edge width",
56
                      lty_legend = FALSE, lty_legend_title = "Edge class", lty_legend_order = NULL,
57
                      params_list = NULL,
58
                      seed = 1234) {
59
  if (!is.null(params_list)) {
60
    as.list(match.call()[-1]) -> set_params_list
61
    set_params_list[["params_list"]] <- NULL
62
    for (i in seq_along(params_list)) {
63
      if (names(params_list)[i] %in% names(set_params_list)) {
64
        message("The parameter `", names(params_list)[i], "` is duplicated, the format argument will be used.")
65
      }
66
    }
67
    pcutils::update_param(params_list, set_params_list) -> set_params_list
68
    do.call(c_net_plot, set_params_list)
69
    return(invisible())
70
  }
71
72
  rename <- size <- color <- e_type <- lty <- e_class <- v_class <- shape <- X1 <- Y1 <- X2 <- Y2 <- width <- X <- Y <- label <- NULL
73
  edge_width_text <- NULL
74
75
  ggig <- x
76
  ggig$v_index -> tmp_v
77
  ggig$e_index -> tmp_e
78
79
  set.seed(seed)
80
  # get coordinates
81
  if (!is.null(coors)) {
82
    tmp_v$X <- tmp_v$Y <- NULL
83
    tmp_e$X1 <- tmp_e$X2 <- tmp_e$Y1 <- tmp_e$Y2 <- NULL
84
    # add coors
85
    tmp_v %<>% dplyr::left_join(., coors, by = "name", suffix = c("", ".1"))
86
    tmp_e %<>% dplyr::left_join(., coors, by = c("from" = "name")) %>%
87
      rename(X1 = "X", Y1 = "Y") %>%
88
      dplyr::left_join(., coors, by = c("to" = "name")) %>%
89
      rename(X2 = "X", Y2 = "Y")
90
  }
91
92
  # get network type
93
  main <- get_net_main(ggig$n_index)
94
95
  # scale the size and width
96
  scale_size_width(tmp_v, tmp_e, vertex_size_range, edge_width_range)
97
98
  # new shapes
99
  tmp_v$shape <- tidai(tmp_v$v_group, 21:26)
100
101
  # some custom parameters
102
  some_custom_paras(tmp_v, tmp_e, ...)
103
104
  # show labels
105
  tmp_v <- get_show_labels(tmp_v, labels_num)
106
107
  if (TRUE) {
108
    tmp_e$e_type <- pcutils::change_fac_lev(tmp_e$e_type, edge_legend_order)
109
    edges <- levels(tmp_e$e_type)
110
    edge_cols <- dplyr::distinct(tmp_e, color, e_type)
111
    edge_cols <- setNames(edge_cols$color, edge_cols$e_type)
112
    if (legend_number) {
113
      eee <- table(tmp_e$e_type)
114
      edge_text <- paste(edges, eee[edges], sep = ": ")
115
    } else {
116
      edge_text <- edges
117
    }
118
  }
119
120
  if (TRUE) {
121
    edges1 <- levels(factor(tmp_e$e_class))
122
    edge_ltys <- dplyr::distinct(tmp_e, lty, e_class)
123
    edge_ltys <- setNames(edge_ltys$lty, edge_ltys$e_class)
124
125
    if (legend_number) {
126
      eee <- table(tmp_e$e_class)
127
      lty_text <- paste(edges1, eee[edges1], sep = ": ")
128
    } else {
129
      lty_text <- edges1
130
    }
131
  }
132
133
  if (TRUE) {
134
    vgroups <- pcutils::change_fac_lev(tmp_v$v_group, group_legend_order)
135
136
    node_size_text <- c(
137
      paste(lapply(node_size_text[levels(vgroups)], \(i)round(i[1], 3)), collapse = "/ "),
138
      paste(lapply(node_size_text[levels(vgroups)], \(i)round(i[2], 3)), collapse = "/ ")
139
    )
140
141
    new_f <- c()
142
    for (g_i in levels(vgroups)) {
143
      tmp_v1 <- tmp_v[tmp_v$v_group == g_i, c("v_class", "color", "shape")]
144
      tmp_f <- pcutils::change_fac_lev(tmp_v1$v_class, color_legend_order)
145
      new_f <- c(new_f, levels(tmp_f))
146
    }
147
148
    tmp_v$v_class <- pcutils::change_fac_lev(tmp_v$v_class, new_f)
149
    vclass <- levels(tmp_v$v_class)
150
151
    node_cols <- dplyr::distinct(tmp_v, color, v_class)
152
    node_cols <- setNames(node_cols$color, node_cols$v_class)
153
    node_shapes <- dplyr::distinct(tmp_v, shape, v_class)
154
    node_shapes <- setNames(node_shapes$shape, node_shapes$v_class)
155
156
    if (legend_number) {
157
      eee <- table(tmp_v$v_class)
158
      le_text <- paste(vclass, eee[vclass], sep = ": ")
159
    } else {
160
      le_text <- vclass
161
    }
162
  }
163
164
  p <- ggplot() +
165
    geom_segment(aes(
166
      x = X1, y = Y1, xend = X2, yend = Y2, color = e_type,
167
      linewidth = width, linetype = e_class
168
    ), data = tmp_e, alpha = 0.7) + # draw edges
169
    scale_color_manual(
170
      name = edge_legend_title, values = edge_cols,
171
      label = edge_text, guide = ifelse(edge_legend, "legend", "none")
172
    ) + # edge colors
173
    scale_linetype_manual(
174
      name = lty_legend_title, values = edge_ltys,
175
      label = lty_text, guide = ifelse(lty_legend, "legend", "none")
176
    ) + # edge linetype
177
    scale_linewidth(
178
      name = width_legend_title, breaks = c(min(tmp_e$width), max(tmp_e$width)), range = c(0.5, 1),
179
      labels = edge_width_text, guide = ifelse(width_legend, "legend", "none")
180
    )
181
182
  p1 <- p +
183
    geom_point(aes(X, Y, fill = v_class, size = size, shape = v_class), data = tmp_v) + # draw nodes
184
    # scale_shape_manual(values =setNames(default_v_shape[node_shapes],vclass))+#node shape
185
    scale_shape_manual(values = node_shapes) +
186
    scale_fill_manual(
187
      name = group_legend_title, values = node_cols[vclass],
188
      labels = le_text, guide = ifelse(color_legend, "legend", "none")
189
    ) + # node color
190
    scale_size(
191
      name = size_legend_title, breaks = c(min(tmp_v$size), max(tmp_v$size)),
192
      labels = node_size_text, guide = ifelse(size_legend, "legend", "none")
193
    ) + # node size
194
195
    ggnewscale::new_scale("size") +
196
    geom_text(aes(X, Y, size = size, label = label), col = "black", data = tmp_v, show.legend = FALSE) +
197
    scale_size(range = c(1, 3), guide = "none") +
198
    guides(
199
      fill = guide_legend(override.aes = list(shape = node_shapes[vclass])),
200
      shape = "none"
201
    )
202
203
  p2 <- p1 + labs(title = main) +
204
    scale_x_continuous(breaks = NULL) + scale_y_continuous(breaks = NULL) +
205
    coord_fixed(ratio = 1) +
206
    theme(panel.background = element_blank()) +
207
    theme(axis.title.x = element_blank(), axis.title.y = element_blank()) +
208
    theme(
209
      legend.background = element_rect(colour = NA),
210
      legend.box.background = element_rect(colour = NA),
211
      legend.key = element_rect(fill = NA)
212
    ) +
213
    theme(panel.background = element_rect(fill = "white", colour = NA)) +
214
    theme(panel.grid.minor = element_blank(), panel.grid.major = element_blank())
215
216
  if (!legend) {
217
    return(p2 + theme(legend.position = "none"))
218
  }
219
220
  p2
221
}
222
223
224
#' Input a graphml file exported by Gephi
225
#'
226
#' @param file graphml file exported by Gephi
227
#' @family plot
228
#' @return list contains the igraph object and coordinates
229
#'
230
#' @export
231
input_gephi <- function(file) {
232
  X <- Y <- code <- NULL
233
  igraph::read.graph(file, format = "graphml") -> gephi
234
  get_v(gephi) -> tmp_v
235
  # extract coors
236
  if (!all(c("x", "y", "r", "g", "b", "id") %in% colnames(tmp_v))) {
237
    stop("This file is not exported by Gephi, please use igraph::read.graph()")
238
  }
239
  coors <- tmp_v[, c("x", "y")]
240
  coors <- data.frame(name = tmp_v$label, X = coors[, 1], Y = coors[, 2])
241
  class(coors) <- "coors"
242
  coors <- rescale_coors(coors)
243
244
  # transform color
245
  pcutils::rgb2code(tmp_v[, c("r", "g", "b")]) %>% dplyr::pull(code) -> tmp_v$color
246
  if ("cor" %in% edge.attributes(gephi)) {
247
    E(gephi)$color <- ifelse(E(gephi)$cor > 0, "#48A4F0", "#E85D5D")
248
  } else {
249
    E(gephi)$color <- "#48A4F0"
250
  }
251
  # scale size
252
  tmp_v$size <- pcutils::mmscale(tmp_v$size, 1, 5)
253
  E(gephi)$width <- pcutils::mmscale(E(gephi)$width, 0.05, 0.2)
254
  # delete
255
  tmp_v %>%
256
    dplyr::select(-c("label", "x", "y", "r", "g", "b", "id")) %>%
257
    as.list() -> vertex.attributes(gephi)
258
  edge.attributes(gephi)["Edge Label"] <- edge.attributes(gephi)["id"] <- NULL
259
260
  gephi <- c_net_update(gephi, initialize = TRUE)
261
  igraph::graph_attr(gephi, "coors") <- coors
262
  return(list(go = gephi, coors = coors))
263
}
264
265
266
#' Input a cyjs file exported by Cytoscape
267
#'
268
#' @param file cyjs file exported by Cytoscape
269
#' @family plot
270
#' @return list contains the igraph object and coordinates
271
#'
272
#' @export
273
input_cytoscape <- function(file) {
274
  c_net_load(file, format = "cyjs") -> cyto
275
276
  get_v(cyto) -> tmp_v
277
  coors <- tmp_v[, c("x", "y")]
278
  coors <- data.frame(name = tmp_v$name, X = coors[, 1], Y = coors[, 2])
279
280
  class(coors) <- "coors"
281
  coors <- rescale_coors(coors)
282
283
  cyto <- c_net_update(cyto, initialize = TRUE)
284
  igraph::graph_attr(cyto, "coors") <- coors
285
  return(list(go = cyto, coors = coors))
286
}
287
288
289
#' plot use networkD3
290
#'
291
#' @param go metanet
292
#' @param v_class which attributes use to be v_class
293
#' @param ... see \code{\link[networkD3]{forceNetwork}}
294
#' @return D3 plot
295
#' @export
296
#' @family plot
297
#' @examples
298
#' data("c_net")
299
#' plot(co_net2)
300
#' if (requireNamespace("networkD3")) {
301
#'   netD3plot(co_net2)
302
#' }
303
netD3plot <- function(go, v_class = "v_class", ...) {
304
  flag <- "y"
305
  if (length(V(go)) > 200) {
306
    message("Too big network, recommend using Gephi to layout,still use networkD3?")
307
    flag <- readline("yes/no(y/n):")
308
  }
309
  if (tolower(flag) %in% c("yes", "y")) {
310
    lib_ps("networkD3", library = FALSE)
311
    go <- c_net_set(go, vertex_class = v_class)
312
    get_v(go) -> tmp_v
313
    nodes <- tmp_v[, c("name", "v_class", "size", "color")]
314
    colnames(nodes) <- c("name", "group", "size", "color")
315
    nodes$size <- pcutils::mmscale(nodes$size, 2, 40)
316
317
    colors <- unique(nodes$color)
318
319
    get_e(go) -> tmp_e
320
    links <- tmp_e[, c("from", "to", "width", "color")]
321
    links$width <- pcutils::mmscale(links$width, 0.5, 1.5)
322
    # give ids
323
    links$IDsource <- match(links$from, nodes$name) - 1
324
    links$IDtarget <- match(links$to, nodes$name) - 1
325
    # Create force directed network plot
326
    networkD3::forceNetwork(
327
      Links = links, Nodes = nodes,
328
      Source = "IDsource", Target = "IDtarget", linkColour = links$color, linkDistance = 20,
329
      linkWidth = networkD3::JS("function(d) { return (d.width); }"), charge = -5,
330
      NodeID = "name", Group = "group", Nodesize = "size",
331
      colourScale = networkD3::JS(paste0("d3.scaleOrdinal([`", paste(colors, collapse = "`,`"), "`])")), legend = TRUE, ...
332
    )
333
  }
334
}
335
336
MetaNet_theme <- {
337
  ggplot2::theme_classic(base_size = 13) + ggplot2::theme(
338
    axis.text = element_text(color = "black"),
339
    plot.margin = grid::unit(rep(0.5, 4), "lines"),
340
    strip.background = ggplot2::element_rect(fill = NA)
341
  )
342
}
343
344
#' Venn network
345
#'
346
#' @param tab data.frame (row is elements, column is group), or a list (names is group, value is elements)
347
#'
348
#' @return plot
349
#' @export
350
#' @family plot
351
#' @examples
352
#' data(otutab, package = "pcutils")
353
#' tab <- otutab[400:485, 1:3]
354
#' venn_net(tab) -> v_net
355
#' plot(v_net)
356
venn_net <- function(tab) {
357
  # pcutils:::venn_cal(tab)->vennlist
358
  tab[is.na(tab)] <- 0
359
  edgelist <- data.frame()
360
  if (is.data.frame(tab)) {
361
    groupss <- colnames(tab)
362
    for (i in groupss) {
363
      if (sum(tab[, i] > 0) > 0) edgelist <- rbind(edgelist, data.frame(Group = i, elements = rownames(tab)[tab[, i] > 0]))
364
    }
365
  } else if (all(class(tab) == "list")) {
366
    vennlist <- tab
367
    groupss <- names(vennlist)
368
    for (i in groupss) {
369
      if (length(vennlist[[i]] > 0)) edgelist <- rbind(edgelist, data.frame(Group = i, elements = vennlist[[i]]))
370
    }
371
  } else {
372
    stop("wrong input tab")
373
  }
374
375
  nodelist <- rbind(
376
    data.frame(name = groupss, v_group = "Group", v_class = paste0("Group: ", groupss)),
377
    data.frame(name = unique(edgelist$elements), v_group = "elements", v_class = "elements")
378
  )
379
  venn_net <- c_net_from_edgelist(edgelist, vertex_df = nodelist)
380
  graph.attributes(venn_net)$n_type <- "venn"
381
  all_group <- get_e(venn_net)[, c("from", "to")] %>%
382
    pcutils::squash("from") %>%
383
    dplyr::rename(name = "to", all_group = "from")
384
  venn_net <- c_net_set(venn_net, all_group, vertex_class = "all_group", edge_type = "from")
385
  venn_net
386
}
387
388
389
#' Quick build a metanet from two columns table
390
#'
391
#' @param edgelist two columns table (no elements exist in two columns at same time)
392
#'
393
#' @return metanet
394
#' @export
395
#' @family plot
396
#' @examples
397
#' twocol <- data.frame(
398
#'   "col1" = sample(letters, 30, replace = TRUE),
399
#'   "col2" = sample(c("A", "B"), 30, replace = TRUE)
400
#' )
401
#' twocol_net <- twocol_edgelist(twocol)
402
#' plot(twocol_net)
403
#' c_net_plot(twocol_net, g_layout_polygon(twocol_net))
404
twocol_edgelist <- function(edgelist) {
405
  if (any(edgelist[, 1] %in% edgelist[, 2])) stop("Must no elements exist in two columns at same time")
406
  nodelist <- rbind(
407
    data.frame(name = unique(edgelist[, 1]), v_group = names(edgelist)[1], v_class = names(edgelist)[1]),
408
    data.frame(name = unique(edgelist[, 2]), v_group = names(edgelist)[2], v_class = names(edgelist)[2])
409
  )
410
  venn_net <- c_net_from_edgelist(edgelist, vertex_df = nodelist)
411
  graph.attributes(venn_net)$n_type <- "twocol"
412
  # venn_net=c_net_set(venn_net,edge_type = "from")
413
  venn_net
414
}
415
416
417
#' Transform a dataframe to a network edgelist.
418
#'
419
#' @param test df
420
#' @param fun default: sum
421
#'
422
#' @return metanet
423
#' @export
424
#'
425
#' @examples
426
#' data("otutab", package = "pcutils")
427
#' cbind(taxonomy, num = rowSums(otutab))[1:20, ] -> test
428
#' df2net_tree(test) -> ttt
429
#' plot(ttt)
430
#' if (requireNamespace("ggraph")) plot(ttt, coors = as_circle_tree())
431
df2net_tree <- function(test, fun = sum) {
432
  flag <- FALSE
433
  if (!is.numeric(test[, ncol(test)])) {
434
    test$num <- 1
435
  } else {
436
    flag <- TRUE
437
    name <- colnames(test)[ncol(test)]
438
  }
439
  nc <- ncol(test)
440
  if (nc < 3) stop("as least 3-columns dataframe")
441
442
  link <- pcutils::df2link(test, fun = fun)
443
444
  nodes <- link$nodes
445
  links <- link$links
446
  if (flag) {
447
    colnames(links)[3] <- colnames(nodes)[3] <- name
448
  } else {
449
    name <- "weight"
450
  }
451
452
  # c_net_from_edgelist(as.data.frame(links),vertex = nodes)
453
  net <- igraph::graph_from_data_frame(as.data.frame(links), vertices = nodes)
454
  net <- c_net_set(net, vertex_class = "level", vertex_size = name, edge_width = name)
455
  net <- c_net_update(net, initialize = TRUE, verbose = FALSE)
456
  graph_attr(net, "coors") <- c_net_layout(net, as_tree())
457
  net
458
}
459
460
#' Plot olympic rings using network
461
#'
462
#' @return network plot
463
#' @export
464
#' @family plot
465
#' @examples
466
#' olympic_rings_net()
467
olympic_rings_net <- function() {
468
  r <- 1
469
  pensize <- r / 6
470
  rings_data <- data.frame(
471
    x = c(-2 * (r + pensize), -(r + pensize), 0, (r + pensize), 2 * (r + pensize)),
472
    y = c(r, 0, r, 0, r),
473
    color = c("#0081C8", "#FCB131", "#000000", "#00A651", "#EE334E")
474
  )
475
  g1 <- module_net(module_number = 5, n_node_in_module = 30)
476
  plot(g1,
477
    coors = g_layout(g1, layout1 = rings_data[, 1:2], zoom1 = 1.2, zoom2 = 0.5),
478
    rescale = FALSE, legend = FALSE, main = "Olympic Rings", vertex.frame.color = NA,
479
    edge.width = 0, vertex.color = setNames(rings_data$color, 1:5), vertex.size = 7
480
  )
481
}