# Cone Trees: map a graph onto geometric shape

## Question

Is it possible to map a Graph onto a geometric object such as a Cone?

## Motivation

Visualizing large trees can be tedious, especially when limited to the confines of the printed page. One way individuals have come to highlight certain aspects thereof is via the cone tree:

Thus I want to be able to recreate something similar in Mathematica. Unfortunately I am very unfamiliar with manipulating Graphic objects. So I would greatly appreciate your assistance.

Making a cone is simple enough:

Graphics3D[Cone[]]


Similarly so is making a tree (example from the TreePlot documentation):

TreePlot[{1 -> 4, 1 -> 6, 1 -> 8, 2 -> 6, 3 -> 8, 4 -> 5, 7 -> 8}]


Thoughts?

To lay out a graph on a cone, you start by laying it out in a circular way. Then you add an appropriate "z coordinate" to each node position, proportionally to its distance form the centre.

This is done using the "RadialEmbedding" GraphLayout.

Example:

tree = Graph@EdgeList@KaryTree[2^6 - 1, 2]


The Graph@EdgeList@ part is to change the internal representation of this graph and work around some bugs ... otherwise some of the functions below (such as the Graph3D line) would fail.

layout = SetProperty[tree, GraphLayout -> "RadialEmbedding"]


Should you need to set the root vertex for this layout, do so using GraphLayout -> {"RadialEmbedding", "RootVertex" -> 1}.

You can see using Show[layout, Frame -> True, FrameTicks -> True] that {0,0} is not in the centre. We want it in the centre. So we subtract the coordinates of the root vertex from each vertex coordinate. In this case the root vertex happens to be the first one.

coord = GraphEmbedding[layout];
coord = # - First[coord] & /@ coord;


Now we can put it in 3D on a cone:

Graph3D[tree, VertexCoordinates -> ({#1, #2, -Norm[{#1, #2}]} & @@@ coord)]


The IGraph/M package also has a similar but not fully identical layout algorithm.

<<IGraphM

layout = IGLayoutReingoldTilfordCircular[tree, "RootVertices" -> {1}]

coord = GraphEmbedding[layout]


This function always places the root vertex at {0,0}.

You can construct graphs using Graph3D with proper layouts:

edges = EdgeList@KaryTree[2^6 - 1, 2];

Graph3D[edges,
GraphLayout -> {"RadialEmbedding", "LayerSizeFunction" -> (-# &)}]


Graph3D[edges, GraphLayout -> "BalloonEmbedding"]
`