data("multi_test", package = "MetaNet")
data("c_net", package = "MetaNet")
# build a multi-network
multi1 <- multi_net_build(list(Microbiome = micro, Metabolome = metab, Transcriptome = transc))
# v_group is default, three different table
plot(multi1)
# set vertex_class
multi1_with_anno <- c_net_set(multi1, micro_g, metab_g, transc_g, vertex_class = c("Phylum", "kingdom", "type"))
# set vertex_size
multi1_with_anno <- c_net_set(multi1_with_anno,
data.frame("Abundance1" = colSums(micro)),
data.frame("Abundance2" = colSums(metab)),
data.frame("Abundance3" = colSums(transc)),
vertex_size = paste0("Abundance", 1:3)
)
plot(multi1_with_anno)
4 Visualization
MetaNet
supports basic R plot and provides some interfaces for other software (Gephi
, Cytoscape
, ggplot2
, networkD3
) to visualize, while there are also a lot of layout methods for better display.
4.1 Basic plot
Set attributes
As we mentioned before, there are some internal attributes have been set when building network, which are related to the network visualization (Table 3.1). So we can use c_net_set()
to custom these attributes fitting to our research needs.
Give the network various annotate tables and determine which columns use to set, we can give the columns name (one or more) to vertex_group
, vertex_class
, vertex_size
, edge_type
, edge_class
, edge_width
.
And the colors, linetypes, shapes and legends will be assigned automatically, just use plot()
to get the basic metanet figure. For more details to customize the plot, refer to Table 4.1.
Plot setting
If you want to custom the network plot flexibility, use the c_net_plot()
which contains many flexible arguments. The arguments of c_net_plot()
are listed below:
c_net_plot()
arguments.
Arguments | Description |
---|---|
coors | 1. cooridnates dataframe, 2. layout function (e.g. as_star(), as_tree(), in_circle(), nicely()... see help(c_net_lay)) |
vertex.color | color of nodes, receive vector (1. length same to number of nodes; 2. length same to numbers of v_class; 3. named verctor like c(A="red",B="blue")) |
vertex. shape | shape of nodes, receive vector (1. length same to number of nodes; 2. length same to numbers of v_group; 3. named verctor like c(v_group1="circle",B="square"))shape list: none, circle, square, csquare, rectangle, crectangle, vrectangle, pie, raster, or sphere |
vertex.size | size of nodes, receive numerical vector (length same to number of nodes)please use mmscale to control vertex.size, don't be too large. |
vertex_size_range | the vertex size range, e.g. c(1,10) |
labels_num | show how many labels,>1 indicates number, |
vertex.label | the label of nodes, NA indicates no label |
vertex.label.family | label font family |
vertex.label.font | label font, 1 plain, 2 bold, 3 italic, 4 bold italic, 5 symbol |
vertex.label.cex | label size |
vertex.label.dist | distance from label to nodes |
vertex.label.degree | 0:right, pi: left, pi/2:below, -pi/2:above |
vertex.frame.color | color of nodes frame |
plot_module | use module as the v_class |
mark_module | logical, mark the modules? |
mark_color | mark color |
mark_alpha | mark fill alpha, default 0.3 |
module_label | show module label? |
module_label_cex | module label cex |
module_label_color | module label color |
module_label_just | module label just, default c(0.5,0.5) |
edge.color | color of edges, receive vector (1. length same to number of edges; 2. length same to numbers of e_type; 3. named verctor like c(A="red",B="blue")) |
edge.width | width of edge, receive numerical vector (length same to number of edges)please use mmscale to control vertex.size, don't be too large. |
edge_width_range | the edge width range, e.g. c(1,10) |
edge.lty | linetype of edge, receive vector (1. length same to number of edges; 2. length same to numbers of e_class; 3. named verctor like c(A="red",B="blue")) |
edge.arrow.size | arrow size for directed network |
edge.arrow.width | arrow width for directed network |
arrow.mode | arrow mode, 0 no arrow, 1 back, 2 forward, 3 both |
edge.label | the label of edges, NA indicates no label |
edge.label.family | label font family |
edge.label.font | label font, 1 plain, 2 bold, 3 italic, 4 bold italic, 5 symbol |
edge.label.cex | label size |
edge.label.x | label x-axis |
edge.label.y | label y-axis |
edge.label.color | label color |
edge.curved | The curvature of the body, on a scale of 0-1, FALSE means 0, TRUE means 0.5 |
legend | show any legend? FALSE means close all legends |
legend_cex | character expansion factor relative to current par('cex'), default: 1 |
legend_position | legend_position, default: c(left_leg_x=-1.9,left_leg_y=1,right_leg_x=1.2,right_leg_y=1) |
legend_number | add numbers in legend? (v_class number, e_type number...) |
lty_legend, lty_legend_title, lty_legend_order | show lty_legend? and the title, the oreder of legend receives a vector |
size_legend, size_legend_tiltle | show size_legend? and the title |
edge_legend, edge_legend_title, edge_legend_order | show edge_legend? and the title, the order of legend receives a vector |
width_legend, width_legend_title | show width_legend? and the title |
color_legend, color_legend_order | show col_legend? and the title, the order of legend receives a vector |
group_legend_title, group_legend_order | the title of group, the order of legend receives a vector |
margin | margin, a vector whose length =4 |
rescale | scale the coors to [-1,1], default T |
asp | y/x ratio |
frame | if T, add frame |
main | the main title of graph |
sub | subtitle |
xlab | x-axis label |
ylab | y-axis label |
seed | random seed, default:1234, make sure each plot is the same |
params_list | a list of parameters, e.g. list(edge_legend = TRUE, lty_legend = FALSE), when the parameter is duplicated, the format argument will be used rather than the argument in params_list |
For example, we can use c_net_plot()
to plot the network with annotation and set the color, size, width, legend, etc.
c_net_plot(multi1_with_anno,
labels_num = 5, vertex.color = get_cols(11, "col1"), vertex_size_range = c(3, 10), vertex.label.color = "red",
edge_width_range = c(0.5, 3), edge.color = c("orange", "green4"), edge.curved = 0.5,
legend = T, legend_number = T, group_legend_order = c("Microbiome", "Metabolome", "Transcriptome"),
group_legend_title = c("Phylum", "Metabolome", "Transcriptome"),
edge_legend_title = "Correlation", edge_legend_order = c("positive", "negative"),
size_legend = T, size_legend_title = "Abundance",
width_legend = T, width_legend_title = "abs(r)",
lty_legend = T, lty_legend_title = "Omics relationship"
)
params_list
is a special argument in c_net_plot()
, it is a list contains parameters, it is very convenient to use it to plot a series of network with same attributes.
node_colors <- setNames(get_cols(9, "col1"), unique(V(multi1_with_anno)$v_class))
params_list <- list(
labels_num = 5,
vertex.color = node_colors, vertex_size_range = c(3, 10), vertex.label.color = "red",
edge_width_range = c(0.5, 3), edge.color = c("orange", "green4"), edge.curved = 0.5,
legend = T, legend_number = T, group_legend_order = c("Microbiome", "Metabolome", "Transcriptome"),
group_legend_title = c("Phylum", "Metabolome", "Transcriptome"),
edge_legend_title = "Correlation", edge_legend_order = c("positive", "negative"),
size_legend = T, size_legend_title = "Abundance",
width_legend = T, width_legend_title = "abs(r)",
lty_legend = T, lty_legend_title = "Omics relationship"
)
c_net_plot(multi1_with_anno, params_list = params_list)
# build another multi-network
multi1_with_anno2 <- c_net_filter(multi1_with_anno, v_group %in% c("Microbiome", "Metabolome")) %>%
c_net_filter(., e_class == "intra", mode = "e")
c_net_plot(multi1_with_anno2, params_list = params_list)
4.2 Layout
Layout is an important part of network visualization, a good layout will present information clearly.
So, in MetaNet
, we always use a coors
object to store the coordinates of a layout.
The coors
is a list contains two elements: coors$coors
and coors$curved
. coors$coors
is a three-columns data.frame contains “name”, “X”, “Y”. coors$curved
is a three-columns data.frame contains “from”, “to”, “curved” or NULL.
Basic layout
Use c_net_layout()
to get coordinates with specific layout methods.
c_net_layout(co_net2, method = in_circle()) -> coors
c_net_plot(co_net2, coors)
The method can be one of
as_line()
,as_arc()
,as_polygon()
,as_polyarc()
,as_polycircle()
,as_circle_tree()
.layouts in igraph:
in_circle()
,nicely()
,on_grid()
,on_sphere()
,randomly()
,with_dh()
,with_fr()
,with_gem()
,with_graphopt()
,with_kk()
,with_lgl()
,with_mds()
, seeigraph::layout_()
.layouts in ggraph: a character, “auto”, “backbone”, “centrality”, “circlepack”, “dendrogram”, “eigen”, “focus”, “hive”, “igraph”, “linear”, “manual”, “matrix”, “partition”, “pmds”, “stress”, “treemap”, “unrooted”. see
ggraph::create_layout()
.
Code
go <- erdos.renyi.game(30, 0.25)
# get a metanet
go <- c_net_update(go)
layout_methods <- list(
as_star(), as_tree(), in_circle(), nicely(),
on_grid(), on_sphere(), randomly(), with_dh(),
with_fr(), with_gem(), with_graphopt(), with_kk(),
with_lgl(), with_mds(), as_line(), as_arc(),
as_polygon(), as_polyarc(), as_polycircle(), as_circle_tree()
)
names(layout_methods) <- c(
"as_star ", "as_tree ", "in_circle ", "nicely ",
"on_grid ", "on_sphere ", "randomly ", "with_dh ",
"with_fr ", "with_gem ", "with_graphopt ", "with_kk ",
"with_lgl ", "with_mds", "as_line", "as_arc",
"as_polygon", "as_polyarc", "as_polycircle", "as_circle_tree"
)
par(mfrow = c(5, 4))
for (i in names(layout_methods)) {
plot(go, layout_methods[[i]], legend = F, main = i, labels_num = 0)
}
And for each method, you can add some arguments in it:
The as_polygon()
is interesting: it can draw a network in a polygon shape, and you can change the edge numbers of the polygon.
as_polygon()
in c_net_layout
Group layout
Beside the c_net_layout()
, we provide an advanced layout method for a network with group variable: g_layout()
. It is easy to use g_layout()
to control each group position and layout of each group.
g_layout()
is a very useful function to layout a network with group variable when we have a multi-omics network (Chapter 7) or module network (Section 5.4).
- First, assign a group variable.
- Give a
layout1
for group position, one of 1.a dataframe or matrix: rowname is group, two columns are X and Y 2.function: layout method forc_net_layout()
default: in_circle() - Adjust the
zoom1
oflayout1
. - Give a
layout2
(layout method forc_net_layout()
) for each group layout, or use a list contains functions match each group. - Adjust the
zoom2
oflayout2
, you can use a vector to adjust each group zoom. - use
show_big_layout = T
to see thelayout1
distribution.
par(mfrow = c(2, 1))
# set circle layout for each group
g_layout(multi1_with_anno,
group = "v_group", layout1 = in_circle(),
zoom1 = 10, layout2 = in_circle(), zoom2 = 5
) -> g_coors
plot(multi1_with_anno, coors = g_coors)
# set different layout for each group
g_layout(multi1_with_anno,
group = "v_group", layout1 = in_circle(), zoom1 = 10,
layout2 = list(in_circle(), with_fr(), as_polygon()), zoom2 = 3:5
) -> g_coors
plot(multi1_with_anno, coors = g_coors)
g_layout()
As layout1
also receive a matrix or data.frame, so we can use the group skeleton of network to adjust the layout1
.
data("c_net", package = "MetaNet")
g_layout(co_net,
group = "v_class", layout1 = in_circle(), zoom1 = 10,
layout2 = in_circle(), zoom2 = c(1, 5, 2, 1, 3, 7)
) -> g_coors
plot(co_net, coors = g_coors)
# firstly get the skeleton plot
get_group_skeleton(co_net, "v_class") %>% clean_igraph() -> s_net
# then use tkplot to do manual adjustment.
x <- igraph::tkplot(s_net)
# Here: Move nodes within the tkplot window to a layout you like!
da <- igraph::tkplot.getcoords(x)
# close the window
igraph::tkplot.close(x)
# pass the `da` to layout1
g_layout(co_net,
group = "v_class", layout1 = da, zoom1 = 20,
layout2 = in_circle(), zoom2 = c(1, 4, 2, 1, 3, 5)
) -> g_coors
plot(co_net, coors = g_coors)
g_layout()
provides a high degree of customization, you can adjust the layout according to different needs.
Besides, there are also some good default group layout methods: - g_layout_circlepack()
- g_layout_treemap()
- g_layout_backbone()
- g_layout_stress()
- g_layout_polyarc()
- g_layout_polygon()
- g_layout_polycircle()
E(co_net)$color <- rep("grey", length(E(co_net)))
plot(co_net,
coors = g_layout_circlepack(co_net, group = "v_class"),
legend = F, labels_num = 0, main = "g_layout_circlepack"
)
plot(co_net,
coors = g_layout_treemap(co_net, group = "v_class"),
legend = F, labels_num = 0, main = "g_layout_treemap"
)
plot(co_net,
coors = g_layout_backbone(co_net, group = "v_class"),
legend = F, labels_num = 0, main = "g_layout_backbone"
)
plot(co_net,
coors = g_layout_stress(co_net, group = "v_class"),
legend = F, labels_num = 0, main = "g_layout_stress"
)
plot(co_net,
coors = g_layout_polyarc(co_net, group = "v_class"),
legend = F, labels_num = 0, main = "g_layout_polyarc"
)
plot(co_net,
coors = g_layout_polygon(co_net, group = "v_class"),
legend = F, labels_num = 0, main = "g_layout_polygon"
)
plot(co_net,
coors = g_layout_polycircle(co_net, group = "v_class"),
legend = F, labels_num = 0, main = "g_layout_polycircle"
)
4.3 Other styles
It is also easy to transfer the basic plot to other styles, like ggplot2
, Gephi
, Cytoscape
, and NetworkD3
.
ggplot2
If you are more familiar with ggplot2
, use the function as.ggig()
transfer the basic R plot to ggplot2 style, so that you can use some convenient function like labs()
, theme()
, ggsave()
, and cowplot::plot_grid()
to make better figure.
as.ggig(multi1_with_anno) -> ggig
plot(ggig)
Gephi
If you are dealing with some big dataset, We recommend to use Gephi
to make layout. We provide a interface to Gephi by graphml
format file, you can use the algorithm in Gephi
then export a graphml file.
plot(co_net)
c_net_save(co_net, filename = "test", format = "graphml")
# then input test.graphml to Gephi and do a layout
# and export a graphml file from Gephi: test2.graphml, So you can re-draw it in MetaNet
input_gephi("test2.graphml") -> gephi
c_net_plot(co_net, coors = gephi$coors, legend_number = T, group_legend_title = "Phylum")
Cytoscape
Cytoscape is also a pretty software for network visualization which contains lots of plugins.
Use the “data.frame” format to transfer network.
c_net_save(co_net, filename = "test", format = "data.frame")
# then input test_nodes.csv and test_edge.csv to Cytoscape.
NetworkD3
NetworkD3 can produce interactive network plot based on JavaScript, the output object is a htmlwidgets which are suitable for website.
netD3plot(multi1_with_anno)
4.4 Intersting plot
There are some interesting plot in MetaNet
, like venn_net
, twocol_edgelist
, df2net_tree
, and olympic_rings_net
.
- Venn plot
- Two columns edge list
twocol <- data.frame(
"col1" = sample(letters, 30, replace = TRUE),
"col2" = sample(c("A", "B"), 30, replace = TRUE)
)
twocol_net <- twocol_edgelist(twocol)
c_net_plot(twocol_net, g_layout_polygon(twocol_net))
- Dataframe to network tree
data("otutab", package = "pcutils")
cbind(taxonomy, num = rowSums(otutab))[1:20, ] -> test
df2net_tree(test) -> ttt
par(mfrow = c(1, 2))
plot(ttt, edge_legend = F, main = "Tree network", legend_position = c(left_leg_x = -1.3))
plot(ttt, coors = as_circle_tree(), legend = F, main = "Circle tree network")
- Olympic rings plot
olympic_rings_net()