Recently, I am using ggraph
to create circular bundle graphs. I noticed that in ggraph::geom_conn_bundle()
, if I wanted to specify information such as the color of connections, they sometimes did not match the correct connections. For example, in the following ggraph, I wanted to create 3 connections between node pairs (30,74), (34,71) and (35,70), with colors "A", "B", "C" respectively (A = red, B = green, C = blue, as shown in ggplot 0).
ggraph 1: source nodes were permuted in the ascending order: (30,74), (34,71) and (35,70), with colors "A", "B", "C" respectively, I got the correct matching.
ggraph 2: within node group re-ordering along with their color information: (30,74), (35,70) and (34,71), with colors "A", "C", "B" respectively, I got a wrong matching of the colors to the connections.
ggraph 3: across node groups re-ordering along with their color information: (34,71), (35,70) and (30,74), with colors "B", "C", "A" respectively, I got a wrong matching of the colors to the connections.
ggraph 4: across node groups re-ordering along with their color information: (34,71), (30,74) and (35,70), with colors "B", "A", "C" respectively, I got another wrong matching of the colors to the connections.
It is somewhat hard to understand if I re-order the connections with their corresponding properties (e.g. color), I get different matching of connections and their properties. I spent quite an amount of time to figure out that this problem can be solved if I permute the source nodes group
in the ascending order and also the source nodes in the ascending order within each group
. But I think the connection mapping should work correctly with any order of connections provided. Could you please tell me what I'm not handling correctly?
ggplot 0: revealing default color mapping to "A", "B" and "C"
ggraph 1: connections (30,74), (34,71) and (35,70), with colors "A", "B", "C" respectively (ordered source nodes -> correct matching)
ggraph 2: connections (30,74), (35,70) and (34,71), with colors "A", "C", "B" respectively (intra-group reorder -> wrong matching)
ggraph 3: connections (34,71), (35,70) and (30,74), with colors "B", "C", "A" respectively (inter-group reorder -> wrong matching)
ggraph 4: connections (34,71), (30,74) and (35,70), with colors "B", "A", "C" respectively (another inter-group reorder -> wrong matching)
# Libraries
library(ggraph)
library(igraph)
library(tidyverse)
library(RColorBrewer)
# create a data frame giving the hierarchical structure of your individuals
set.seed(1234)
d1 <- data.frame(from="origin", to=paste("group", seq(1,10), sep=""))
d2 <- data.frame(from=rep(d1$to, each=10), to=paste("subgroup", seq(1,100), sep="_"))
edges <- rbind(d1, d2)
edges
# create a vertices data.frame. One line per object of our hierarchy
vertices <- data.frame(
name = unique(c(as.character(edges$from), as.character(edges$to))) ,
value = runif(111)
)
# Let's add a column with the group of each name. It will be useful later to color points
vertices$group <- edges$from[ match( vertices$name, edges$to ) ]
#Let's add information concerning the label we are going to add: angle, horizontal adjustement and potential flip
#calculate the ANGLE of the labels
vertices$id <- 1:nrow(vertices)
vertices
# Create a graph object
mygraph <- igraph::graph_from_data_frame( edges, vertices=vertices )
# See the color map with ggplot
tribble(~ y, ~ col,
2, "A",
1, "B",
0, "C") %>%
ggplot() +
geom_hline(aes(yintercept=y, color=col))
# Plot ggraph 1 with conn = 30-74 (color "A"), 34-71 (color "B"), 35-70 (color "C")
ggraph(mygraph, layout = 'dendrogram', circular = TRUE) +
geom_node_point(aes(filter = leaf, x = x*1.05, y=y*1.05, color = group), show.legend = FALSE) +
geom_conn_bundle(data = get_con(from = c(30, 34, 35), to = c(74, 71, 70), col = c("A", "B", "C")), alpha=1, aes(color=col), width = 0.9) +
geom_node_text(aes(x = x*1.1, y=y*1.1, filter = leaf, label=id, angle = node_angle(x, y)), size=2.5, alpha=1) +
theme_void() +
coord_fixed() +
theme(
# legend.position="none",
plot.margin=unit(c(0,0,0,0),"cm"),
) +
expand_limits(x = c(-1.2, 1.2), y = c(-1.2, 1.2))
# Plot ggraph 2 with conn = 30-74 (color "A"), 35-70 (color "C"), 34-71 (color "B")
ggraph(mygraph, layout = 'dendrogram', circular = TRUE) +
geom_node_point(aes(filter = leaf, x = x*1.05, y=y*1.05, color = group), show.legend = FALSE) +
geom_conn_bundle(data = get_con(from = c(30, 35, 34), to = c(74, 70, 71), col = c("A", "C", "B")), alpha=1, aes(color=col), width = 0.9) +
geom_node_text(aes(x = x*1.1, y=y*1.1, filter = leaf, label=id, angle = node_angle(x, y)), size=2.5, alpha=1) +
theme_void() +
coord_fixed() +
theme(
# legend.position="none",
plot.margin=unit(c(0,0,0,0),"cm"),
) +
expand_limits(x = c(-1.2, 1.2), y = c(-1.2, 1.2))
# Plot ggraph 3 with conn = 34-71 (color "B"), 35-70 (color "C"), 30-74 (color "A")
ggraph(mygraph, layout = 'dendrogram', circular = TRUE) +
geom_node_point(aes(filter = leaf, x = x*1.05, y=y*1.05, color = group), show.legend = FALSE) +
geom_conn_bundle(data = get_con(from = c(34, 35, 30), to = c(71, 70, 74), col = c("B", "C", "A")), alpha=1, aes(color=col), width = 0.9) +
geom_node_text(aes(x = x*1.1, y=y*1.1, filter = leaf, label=id, angle = node_angle(x, y)), size=2.5, alpha=1) +
theme_void() +
coord_fixed() +
theme(
# legend.position="none",
plot.margin=unit(c(0,0,0,0),"cm"),
) +
expand_limits(x = c(-1.2, 1.2), y = c(-1.2, 1.2))
# Plot ggraph 4 with conn = 34-71 (color "B"), 30-74 (color "A"), 35-70 (color "C")
ggraph(mygraph, layout = 'dendrogram', circular = TRUE) +
geom_node_point(aes(filter = leaf, x = x*1.05, y=y*1.05, color = group), show.legend = FALSE) +
geom_conn_bundle(data = get_con(from = c(34, 30, 35), to = c(71, 74, 70), col = c("B", "A", "C")), alpha=1, aes(color=col), width = 0.9) +
geom_node_text(aes(x = x*1.1, y=y*1.1, filter = leaf, label=id, angle = node_angle(x, y)), size=2.5, alpha=1) +
theme_void() +
coord_fixed() +
theme(
# legend.position="none",
plot.margin=unit(c(0,0,0,0),"cm"),
) +
expand_limits(x = c(-1.2, 1.2), y = c(-1.2, 1.2))
My session info:
R version 3.6.0 (2019-04-26)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows Server x64 (build 17763)
Matrix products: default
locale:
[1] LC_COLLATE=Chinese (Simplified)_China.936
[2] LC_CTYPE=Chinese (Simplified)_China.936
[3] LC_MONETARY=Chinese (Simplified)_China.936
[4] LC_NUMERIC=C
[5] LC_TIME=Chinese (Simplified)_China.936
attached base packages:
[1] stats4 parallel grid stats graphics grDevices utils
[8] datasets methods base
other attached packages:
[1] shiny_1.4.0 progress_1.2.2 RColorBrewer_1.1-2
[4] igraph_1.2.4.2 ggraph_2.0.3 OmicsDP_1.10.0
[7] xcms_3.6.2 MSnbase_2.10.1 ProtGenerics_1.20.0
[10] S4Vectors_0.22.1 mzR_2.18.0 Rcpp_1.0.3
[13] BiocParallel_1.18.1 Biobase_2.44.0 BiocGenerics_0.30.0
[16] impute_1.58.0 DMwR2_0.0.2 uuid_0.1-2
[19] mailR_0.4.1 wkb_0.3-0 openssl_1.4.1
[22] knitr_1.26 reshape2_1.4.3 RODBC_1.3-15
[25] fs_1.3.1 xml2_1.2.2 yaml_2.2.0
[28] jsonlite_1.6 data.table_1.12.8 pROC_1.16.1
[31] randomForest_4.6-14 xgboost_0.90.0.2 ggrepel_0.8.1
[34] gplots_3.0.1.1 ggbeeswarm_0.6.0 gridExtra_2.3
[37] ggplotify_0.0.4 forcats_0.5.0 stringr_1.4.0
[40] dplyr_1.0.0 purrr_0.3.3 readr_1.3.1
[43] tidyr_1.0.0 tibble_3.0.1 ggplot2_3.2.1
[46] tidyverse_1.3.0 magrittr_1.5
loaded via a namespace (and not attached):
[1] clipr_0.7.0 utf8_1.1.4 R.utils_2.9.2
[4] tidyselect_1.1.0 devtools_2.2.1 munsell_0.5.0
[7] codetools_0.2-16 preprocessCore_1.46.0 dials_0.0.6
[10] miniUI_0.1.1.1 withr_2.1.2 colorspace_1.4-1
[13] highr_0.8 rstudioapi_0.11 robustbase_0.93-5
[16] rJava_0.9-12 TTR_0.23-4 mzID_1.22.0
[19] labeling_0.3 polyclip_1.10-0 DiceDesign_1.8-1
[22] farver_2.0.1 rprojroot_1.3-2 vctrs_0.3.0
[25] generics_0.0.2 ipred_0.9-9 xfun_0.11
[28] R6_2.4.1 doParallel_1.0.15 graphlayouts_0.7.0
[31] bitops_1.0-6 lhs_1.0.2 gridGraphics_0.4-1
[34] assertthat_0.2.1 promises_1.1.0 scales_1.1.0
[37] nnet_7.3-12 beeswarm_0.2.3 gtable_0.3.0
[40] affy_1.62.0 processx_3.4.1 tidygraph_1.2.0
[43] timeDate_3043.102 rlang_0.4.6 workflows_0.1.1
[46] splines_3.6.0 lazyeval_0.2.2 ModelMetrics_1.2.2.1
[49] broom_0.5.6 BiocManager_1.30.10 modelr_0.1.6
[52] backports_1.1.5 httpuv_1.5.2 quantmod_0.4-15
[55] MassSpecWavelet_1.50.0 caret_6.0-85 usethis_1.5.1
[58] tools_3.6.0 lava_1.6.6 affyio_1.54.0
[61] ellipsis_0.3.0 sessioninfo_1.1.1 parsnip_0.1.1
[64] plyr_1.8.5 zlibbioc_1.30.0 ps_1.3.0
[67] prettyunits_1.0.2 rpart_4.1-15 viridis_0.5.1
[70] zoo_1.8-6 haven_2.2.0 reprex_0.3.0
[73] RANN_2.6.1 GPfit_1.0-8 pcaMethods_1.76.0
[76] whisker_0.4 packrat_0.5.0 pkgload_1.0.2
[79] xtable_1.8-4 mime_0.8 hms_0.5.2
[82] evaluate_0.14 XML_3.98-1.20 readxl_1.3.1
[85] IRanges_2.18.3 testthat_2.3.1 compiler_3.6.0
[88] KernSmooth_2.23-15 ncdf4_1.17 crayon_1.3.4
[91] R.oo_1.23.0 htmltools_0.4.0 later_1.0.0
[94] lubridate_1.7.4 DBI_1.1.0 tweenr_1.0.1
[97] dbplyr_1.4.2 MASS_7.3-51.4 Matrix_1.2-17
[100] cli_2.0.2 vsn_3.52.0 R.methodsS3_1.7.1
[103] gdata_2.18.0 gower_0.2.1 pkgconfig_2.0.3
[106] rvcheck_0.1.6 sp_1.3-2 recipes_0.1.9
[109] MALDIquant_1.19.3 foreach_1.4.7 vipor_0.4.5
[112] multtest_2.40.0 prodlim_2019.11.13 rvest_0.3.5
[115] callr_3.4.0 digest_0.6.23 rmarkdown_2.0
[118] cellranger_1.1.0 curl_4.0 gtools_3.8.1
[121] lifecycle_0.2.0 nlme_3.1-143 desc_1.2.0
[124] viridisLite_0.3.0 askpass_1.1 limma_3.40.6
[127] fansi_0.4.0 pillar_1.4.3 lattice_0.20-38
[130] pkgbuild_1.0.6 fastmap_1.0.1 httr_1.4.1
[133] DEoptimR_1.0-8 survival_2.44-1.1 remotes_2.1.0
[136] glue_1.4.1 xts_0.11-2 iterators_1.0.12
[139] ggforce_0.3.1 class_7.3-15 stringi_1.4.3
[142] memoise_1.1.0 caTools_1.17.1.2
I agree with you that the order of the items in the connect dataframe should not impact the color/transparency of the connections being made. I thought that reordering the connect dataframe in an ascending order had solved the issue for me, but not quite, some connections are still colored wrong. I just submitted a new issue regarding this.
I agree with you that the order of the items in the connect dataframe should not impact the color/transparency of the connections being made. I thought that reordering the connect dataframe in an ascending order had solved the issue for me, but not quite, some connections are still colored wrong. I just submitted a new issue regarding this.
Thanks for bringing attention to this issue. Simply sorting the names of source nodes does NOT necessarily solve the problem. What I discovered for correct mapping is that you first need to permute the source nodes group
in the ascending order and then the source nodes in the ascending order within each group
. I spent quite an amount of time figuring this out, and hope this can help.
Thanks zhuxr11, do you mean ordering them in the vertices and the hierarchy files? I am trying to figure this out too. I have a reproducible example in stackoverflow here.
Thanks zhuxr11, do you mean ordering them in the vertices and the hierarchy files? I am trying to figure this out too. I have a reproducible example in stackoverflow here.
Let's look at an example. If the nodes in the vertex data.frame is defined as (for safety, I suggest arrange the group
in the ascending order, since I did not explore whether this has an effect on property mapping):
name group
C group_1
B group_1
A group_2
And you have a connection like this:
from to weight
B A 0.5
A C 0.6
C B 0.3
Now look at column from
. Since C and B are from group_1, they should go before A, which is from group_2. And within group_1, B should go before C (in the alphabetical order). In this sense, you can try following order:
from to weight
B A 0.5
C B 0.3
A C 0.6
Not sure whether this can help or not.
aaaaaha, I understand what you mean now. Zhuxr11 you are a life saver! I will try this out now and let you know how it went. Many many thanks!
aaaaaha, I understand what you mean now. Zhuxr11 you are a life saver! I will try this out now and let you know how it went. Many many thanks!
My pleasure~
Happy to report your solution worked beautifully :)
Most helpful comment
Let's look at an example. If the nodes in the vertex data.frame is defined as (for safety, I suggest arrange the
group
in the ascending order, since I did not explore whether this has an effect on property mapping):And you have a connection like this:
Now look at column
from
. Since C and B are from group_1, they should go before A, which is from group_2. And within group_1, B should go before C (in the alphabetical order). In this sense, you can try following order:Not sure whether this can help or not.