christophergandrud / networkD3

D3 JavaScript Network Graphs from R
http://christophergandrud.github.io/networkD3
652 stars 268 forks source link

Feature request: Phylogram with already written D3 code #14

Closed apapanico closed 7 years ago

apapanico commented 9 years ago

Hey, I am doing a hierarchical clustering with a few hundred objects and I'm trying to find a nifty way to visualize the clustering and allow someone to play around with parameters and possibly zoom in and out. I've just started looking into how to make a Phylogram and I think it might be a good addition to networkD3. The following are examples of the d3 already implemented:

I have literally zero experience with javascript and d3 so I have absolutely no idea what I'm doing. I'm just trying to replicate what's been done already in networkD3 and patch in the stuff above.

The basic issues:

  1. Considering that newick.js is already written, really it comes down to just passing the newick string. In R, ape::write.tree does that to a phylo object.
  2. Other than that, it's just piecing together the htmlwidgets components I guess. I think I have the necessary .R file together but the .js file for htmlwidgets is harder for me to figure out. For one, since the code for the phylogram is already written, it'd be nice to just call the functions but I just don't see how it's done.

With the js already written, how hard is it to get this up and running with the htmlwidgets?

jjallaire commented 9 years ago

@timelyportfolio and @christophergandrud, do you think this should be a new standalone htmlwidget or is it logically a part of networkD3?

christophergandrud commented 9 years ago

Thematically I think it makes sense. A phylogram is just a more linear representation of what treeNetwork does.

abresler commented 9 years ago

This will be great, can't wait. Also want to see if there is an interactive library that could fit visualizing topological data algos like SOM and Kohonen

Alex Bresler

ASBC LLLC asbcllc.com 917-455-0239

abresler@asbcllc.com @abresler On Jan 14, 2015 10:44 AM, "Christopher Gandrud" notifications@github.com wrote:

Thematically I think it makes sense. A phylogram is just a more linear representation of what treeNetwork does.

— Reply to this email directly or view it on GitHub https://github.com/christophergandrud/networkD3/issues/14#issuecomment-69935583 .

timelyportfolio commented 9 years ago

@christophergandrud @jjallaire I have spent quite a bit of time trying to determine some guidelines or best practices for this, especially considering at the end of the year, I could have > 52 widgets. Some early thoughts I had regarding packaging widgets involved similarities in :

  1. type of visualization
  2. field of study
  3. similar Javascript dependencies
  4. symbiotic features
  5. type of parameters/inputs, such as diagram in DiagrammeR for both mermaid and graphviz
  6. interest of the package author in support and ongoing maintenance

In this case, although the phylogram is not a d3-plugin as the rest of the networkD3 plots, I still think it fits quite cleanly in the networkD3, but 6 would be my biggest driver. I'll be happy to take a shot at adding this if you would like.

abresler commented 9 years ago

God 2015 is going to be amazing for R

Alex Bresler

ASBC LLLC asbcllc.com 917-455-0239

abresler@asbcllc.com @abresler On Jan 15, 2015 5:21 PM, "timelyportfolio" notifications@github.com wrote:

@christophergandrud https://github.com/christophergandrud @jjallaire https://github.com/jjallaire I have spent quite a bit of time trying to determine some guidelines or best practices for this, especially considering at the end of the year, I could have > 52 widgets. Some early thoughts I had regarding packaging widgets involved similarities in :

  1. type of visualization
  2. field of study
  3. similar Javascript dependencies
  4. symbiotic features
  5. type of parameters/inputs, such as diagram in DiagrammeR for both mermaid and graphviz

— Reply to this email directly or view it on GitHub https://github.com/christophergandrud/networkD3/issues/14#issuecomment-70173709 .

christophergandrud commented 9 years ago

@timelyportfolio That is a really nice framework for thinking about this. Thanks for spelling it out.

I'm completely happy with you giving this a shot.

timelyportfolio commented 9 years ago

ok, maybe I'll make it next week's widget http://buildingwidgets.com :)

christophergandrud commented 9 years ago

:+1:

timelyportfolio commented 9 years ago

You can test, spectate, help, track progress in this branch. I went with the d3.phylonator.js, but it is buggy due to new d3 behavior and with some of its events. I worked through most to get a very rough first draft.

My test was this:

devtools::install_github("timelyportfolio/networkD3@feature/phylogram")

library(networkD3)

phyloNetwork("((A7RLM8:0.6571,(B3SBJ1:0.60468,B3SB47:1.39873):0.32942):0.0564,(C3YZV6:0.63868,(B7PB18:1.48452,((Q9I9H8:0.00775,A5WVJ8:0.00101):0.44669,(Q6GNU6:0.41674,((E1BR73:0.00015,E1BS49:0.00017):0.26544,((D2HE46:0.04922,(O14727:0.00017,A7E2A2:0.00089):0.05297):0.02176,((O88879:0.0026,(A2RRK8:0.00015,Q5DU30:0.00088):0.00017):0.02035,(Q8VI66:0.00344,(D3ZA56:0.09057,Q9EPV5:0.00017):0.00098):0.02368):0.0708):0.15795):0.09069):0.11555):0.43916):0.18436):0.11567):0")

I'll probably have a go with the one from the bl.ocks and also Jason Davies version.

timelyportfolio commented 9 years ago

before I forget, I wanted to add this http://www.jsphylosvg.com/ as another possible library for producing these and strangely there is little info about it. I found this https://github.com/guyleonard/jsPhyloSVG

timelyportfolio commented 9 years ago

also, should definitely work integrate with the ape package and see this book http://ape-package.ird.fr/APER.html and one more reference http://www.phytools.org/eqg/Exercise_3.2/

timelyportfolio commented 9 years ago

As I work through this, it seems better to work on a tree network and dendrogram to be more generic than a phylogram, since this does not currently exist within networkD3. @christophergandrud, you ok with this?

christophergandrud commented 9 years ago

Sounds reasonable to me.

timelyportfolio commented 9 years ago

Ok, I built an ugly implementation with examples here and code. @christophergandrud and @apapanico, any opinions on this? The phylogram code to me looks much nicer but lacks the pan/zoom and hover interactivity of phylonator. Collapsible is missing in both, but shouldn't be that hard to implement.

jsPhyloSVG is also pretty with minimal interactivity, but seems to have been abandoned. I think it might be used as an example for multiple formats and tests.

apapanico commented 9 years ago

@timelyportfolio Looks rad to me. Also, I get the sense Phylogram is just a term for a Dendrogram used in a certain fields. I guess the crux of it was that the classic js dendrograms didn't have a branch length parameter and this phylogram implementation did. And of course in hierarchical clustering, the branch length is an important component of the visualization.

Cool to see the (very simple) phyloNetwork.js code. I need to compare with what I had tried.

timelyportfolio commented 9 years ago

well, before comparing, let me get it in respectable format :) Certainly don't want to propagate bad practice.

timelyportfolio commented 9 years ago

I think I'll now start on a generic dendrogram/tree and circle back to the phylogram special case.

timelyportfolio commented 9 years ago

@christophergandrud it seems treeNetwork could be modified to build more tree layouts than Reingold-Tilford Tree. Would this be ok, or would you rather other layouts be in a separate function than treeNetwork?

timelyportfolio commented 9 years ago

while on the topic of dendrograms, I also thought it interesting that I discovered dendextend has a non-exported d3dendrogram feature.

cjyetman commented 7 years ago

Would using diagonalNetwork() if it had an argument like linkType = "elbow" as in dendroNetwork() achieve the desired result? If so, completion of #171 will probably be a sufficient substitute.

cjyetman commented 7 years ago

this can be roughly achieved with the new treeNetwork function...

data <- read.csv(header = T, stringsAsFactors = F, text = '
nodeId,parentId,name,height
0,,,0
1,0,,0.00555
2,1,,0.04732
3,2,Crotalus_oreganus_oreganus_cytochrome_b,0.05532
4,2,Crotalus_horridus_cytochrome_b,0.10598
5,1,,0.06255
6,5,Thamnophis_elegans_terrestris_cytochrome_b,0.06621
7,5,Thamnophis_atratus_cytochrome_b,0.06427
8,0,,0.05762
9,8,Pituophis_catenifer_vertebralis_cytochrome_b,0.06314
10,8,Lampropeltis_getula_cytochrome_b,0.07797
11,0,,0.00779
12,11,Hypsiglena_torquata_cytochrome_b,0.06125
13,11,,0.01037
14,13,Diadophis_punctatus_cytochrome_b,0.07523
15,13,Contia_tenuis_cytochrome_b,0.06379
')
data$height <- 1 - data$height
treeNetwork(data, linkType = 'elbow', defaults = c(nodeStroke = 'yellowGreen', linkWidth = 3))
cjyetman commented 7 years ago

and as_treenetdf calculates height when converting hclust and ape::phylo objects... examples...

library(ape)
tree <- ape::rtree(n = 20)
plot(tree, edge.width = 2)

library(networkD3)
treeNetwork(tree, linkType = 'elbow')
hc <- stats::hclust(stats::dist(USArrests), "ave")

library(networkD3)
treeNetwork(hc, linkType = 'elbow')
cjyetman commented 7 years ago

I believe that the customizability of the new treeNetwork function enables sufficient replication of a phylogram through...

  1. use of the node 'height' column in the 'native' treenetdf format
  2. as_treenetdf() ability to calculate 'height' for ape::phylo and hclust objects during conversion
  3. linktype = 'elbow' argument, and other possible customizations

Closing this issue as the overall concept is now possible. If there are specific bugs or improvements to be made, let's open new issues for them.