kitchensjn / tskit_arg_visualizer

Interactive visualization method for ancestral recombination graphs
MIT License
11 stars 3 forks source link

draw_nodes() overlaps samples if at different times #79

Open hyanwong opened 1 month ago

hyanwong commented 1 month ago

E.g.

ts = msprime.sim_ancestry([msprime.SampleSet(1, time=0, ploidy=1), msprime.SampleSet(1, time=1, ploidy=1)])
d3arg = tskit_arg_visualizer.D3ARG.from_ts(ts=ts)
d3arg.draw_node(node=2)

Which produces an ARG with nodes 0 and 1 overlapping:

Screenshot 2024-08-09 at 09 58 56

This doesn't happen with the simple .draw(), so I reckon the fix should be simple:

d3arg = tskit_arg_visualizer.D3ARG.from_ts(ts=ts)
d3arg.draw()
Screenshot 2024-08-09 at 10 03 49
kitchensjn commented 1 month ago

draw() and draw_node() have different rules for which node(s) get fixed positions. draw() fixes the the sample locations to separate them, whereas draw_node() fixes the focal node in the center (in this case node 2). The rest of the nodes slide freely, even if they are samples, which allows for this overlapping. First pass idea would fixing the positions of any tips - above and below the focal node - to separate things rather than fixing the focal node itself. This will require calculating a somewhat optimal tip ordering based on node distances on the Python side of things (the crux). Shouldn't need to modify any JavaScript code.

kitchensjn commented 1 month ago

To clarify, the reason why the tips don't overlap when they are at the same time is because the force simulations repels them away from each other. This force is two weak to push them apart when there is a separation in timing of the tips.