File size: 4,103 Bytes
6e36aae
 
 
20ea453
 
 
 
 
 
6e36aae
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5cf679d
6e36aae
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9136930
 
6e36aae
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
aa5f6af
6e36aae
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
import igraph as ig
import plotly.graph_objects as go

import gradio as gr
import plotly.graph_objects as go
import os
from collections import defaultdict
import igraph as ig

# Let's create a list of edges with a binary tree structure up to depth 6
# A binary tree has a structure where each node has two children, often referred to as left and right child.
# We will assume that the topmost node (root) has an index 0.

class binNode():
    def __init__(self, id) -> None:
        self.id = id
        self.child1 = None
        self.child2 = None

def create_binary_tree_edges(depth):
    edges = []

    # build binary tree
    id = 0
    root = binNode(id)
    prev = [root]
    for _ in range(depth):
        new_prev = []
        for node in prev:
            id += 1
            node.child1 = binNode(id)
            edges.append((node.id, node.child1.id))
            id += 1
            node.child2 = binNode(id)
            edges.append((node.id, node.child2.id))
            new_prev += [node.child1, node.child2]
        prev = new_prev

    return edges



def plot_tree_using_igraph():
    # Define the edges in a tree structure
    # edges = [(0, 1), (0, 2), (1, 3), (1, 4), (2, 5), (2, 6)]
    edges = create_binary_tree_edges(8)
    # edges = [(str(n1), str(n2)) for (n1, n2) in edges]

    print(edges)
    
    # Create an igraph Graph from the edge list
    g = ig.Graph(edges, directed=True)
    
    # Validate the root index
    if g.vcount() > 0:  # Check if the graph has any vertices
        root_vertex_id = 0  # This assumes that vertex '0' is the root
    else:
        print("The graph has no vertices.")
        return None

    # Use the Reingold-Tilford layout to position the nodes
    try:
        layout = g.layout_reingold_tilford(root=None)  # Correct root specification
    except Exception as e:
        print(f"Error computing layout: {e}")
        return None

    # Edge traces
    edge_x = []
    edge_y = []
    for edge in edges:
        start_idx, end_idx = edge
        x0, y0 = layout.coords[start_idx]
        x1, y1 = layout.coords[end_idx]
        edge_x.extend([x0, x1, None])
        edge_y.extend([-y0, -y1, None])  # y values are inverted to make the tree top-down

    edge_trace = go.Scatter(
        x=edge_x, y=edge_y,
        line=dict(width=0.5, color='#888'),
        hoverinfo='none',
        mode='lines')

    # Node traces
    node_x = [pos[0] for pos in layout.coords]
    node_y = [-pos[1] for pos in layout.coords]  # y values are inverted

    node_trace = go.Scatter(
        x=node_x, y=node_y,
        text=["Node {}".format(i) for i in range(len(layout.coords))],
        mode='markers+text',
        hoverinfo='text',
        marker=dict(
            showscale=False,
            size=10,
            color='LightSkyBlue'
        ),
        textposition="bottom center"
    )

    # Create a Plotly figure
    fig = go.Figure(data=[edge_trace, node_trace],
                    layout=go.Layout(
                        title='<b>Tree Layout with iGraph and Plotly</b>',
                        titlefont_size=16,
                        showlegend=False,
                        hovermode='closest',
                        margin=dict(b=0, l=0, r=0, t=50),
                        xaxis=dict(showgrid=False, zeroline=False, showticklabels=False),
                        yaxis=dict(showgrid=False, zeroline=False, showticklabels=False),
                        # height=600,
                        # width=600,
                        annotations=[dict(
                            showarrow=False,
                            xref="paper", yref="paper",
                            x=0.005, y=-0.002 )]
                    ))

    return fig

# Try generating the figure
# fig = plot_tree_using_igraph()
# print(fig)
# # if fig is not None:
# #     fig.show()

# from plotly.offline import plot
# plot(fig)

with gr.Blocks() as demo:

    gr.Markdown("## Interactive Tree and Image Display")
    with gr.Row():
        tree_output = gr.Plot(plot_tree_using_igraph, scale=2)  # Connect the function directly


demo.launch()