making a 3D graph


Hi . I have created this plot using Kamada kawai layout. Is there any way to manipulate it by rotating it(3D) and by zooming in and out of the edges ?
I attached the code of the vertices and edges and the plotting function

def buildgraphwithmotiondetector(g):
    # 0
    g.add_vertex('NW0')
    g.add_vertex('NW0NE')
    g.add_vertex('NE0')
    g.add_vertex('NE0SE')
    g.add_vertex('SE0')
    g.add_vertex('SE0SW')
    g.add_vertex('SW0')
    g.add_vertex('SW0NW')
    # 0-1
    g.add_vertex('NW0NW1')
    g.add_vertex('NE0NE1')
    g.add_vertex('SE0SE1')
    g.add_vertex('SW0SW1')
    # 1
    g.add_vertex('NW1')
    g.add_vertex('NW1NE')
    g.add_vertex('NE1')
    g.add_vertex('NE1SE')
    g.add_vertex('SE1')
    g.add_vertex('SE1SW')
    g.add_vertex('SW1')
    g.add_vertex('SW1NW')
    # 1-2
    g.add_vertex('NW1NW2')
    g.add_vertex('NE1NE2')
    g.add_vertex('SE1SE2')
    g.add_vertex('SW1SW2')
    # 2
    g.add_vertex('NW2')
    g.add_vertex('NW2NE')
    g.add_vertex('NE2')
    g.add_vertex('NE2SE')
    g.add_vertex('SE2')
    g.add_vertex('SE2SW')
    g.add_vertex('SW2')
    g.add_vertex('SW2NW')

    # 2-3
    g.add_vertex('NW2NW3')
    g.add_vertex('NE2NE3')
    g.add_vertex('SE2SE3')
    g.add_vertex('SW2SW3')
    # 3
    g.add_vertex('NW3')
    g.add_vertex('NW3NE')
    g.add_vertex('NE3')
    g.add_vertex('NE3SE')
    g.add_vertex('SE3')
    g.add_vertex('SE3SW')
    g.add_vertex('SW3')
    g.add_vertex('SW3NW')


    g.vs["SMOKE"] = [False, False, False, False, False, False, False, False,
                     False, False, False, False, True, False, False, False]
    g.vs["MotionFloors"] = [
                      False, False, False, False,#0-1 floor
                      False, False, False, False,#1-2 floor
                      False, False, False, False]#2-3 floor                    
    g.vs["MotionExit"] = [False, False, False, False, False, False, False, False,
                      False, False, False, False, False, False, False, False]
    g.vs["TMP"] = [False, False, False, False, False, False, False, False,
                   False, False, False, False, False, False, False, False]
    # 0
    g.add_edge('NW0', 'NW0NE')['width']=5
    g.add_edge('NW0NE', 'NE0')
    g.add_edge('NE0', 'NE0SE')
    g.add_edge('NE0SE', 'SE0')
    g.add_edge('SE0', 'SE0SW')
    g.add_edge('SE0SW', 'SW0')
    g.add_edge('SW0', 'SW0NW')
    g.add_edge('SW0NW', 'NW0')
    # 0-1
    g.add_edge('NW0', 'NW0NW1')
    g.add_edge('NW0NW1', 'NW1')
    g.add_edge('NE0', 'NE0NE1')
    g.add_edge('NE0NE1', 'NE1')
    g.add_edge('SW0', 'SW0SW1')
    g.add_edge('SW0SW1', 'SW1')
    g.add_edge('SE0', 'SE0SE1')
    g.add_edge('SE0SE1', 'SE1')
    # 1
    g.add_edge('NW1', 'NW1NE')
    g.add_edge('NW1NE', 'NE1')
    g.add_edge('NE1', 'NE1SE')
    g.add_edge('NE1SE', 'SW1')
    g.add_edge('SE1', 'SE1SW')
    g.add_edge('SE1SW', 'SW1')
    g.add_edge('SW1', 'SW1NW')
    g.add_edge('SW1NW', 'NW1')
    # 1-2
    g.add_edge('NW1', 'NW1NW2')
    g.add_edge('NW1NW2', 'NW2')
    g.add_edge('NE1', 'NE1NE2')
    g.add_edge('NE1NE2', 'NE2')
    g.add_edge('SW1', 'SW1SW2')
    g.add_edge('SW1SW2', 'SW2')
    g.add_edge('SE1', 'SE1SE2')
    g.add_edge('SE1SE2', 'SE2')

    # 2
    g.add_edge('NW2', 'NW2NE')
    g.add_edge('NW2NE', 'NE2')
    g.add_edge('NE2', 'NE2SE')
    g.add_edge('NE2SE', 'SW2')
    g.add_edge('SE2', 'SE2SW')
    g.add_edge('SE2SW', 'SW2')
    g.add_edge('SW2', 'SW2NW')
    g.add_edge('SW2NW', 'NW2')
    # 2-3
    g.add_edge('NW2', 'NW2NW3')
    g.add_edge('NW2NW3', 'NW3')
    g.add_edge('NE2', 'NE2NE3')
    g.add_edge('NE2NE3', 'NE3')
    g.add_edge('SW2', 'SW2SW3')
    g.add_edge('SW2SW3', 'SW3')
    g.add_edge('SE2', 'SE2SE3')
    g.add_edge('SE2SE3', 'SE3')

    # 3
    g.add_edge('NW3', 'NW3NE')
    g.add_edge('NW3NE', 'NE3')
    g.add_edge('NE3', 'NE3SE')
    g.add_edge('NE3SE', 'SW3')
    g.add_edge('SE3', 'SE3SW')
    g.add_edge('SE3SW', 'SW3')
    g.add_edge('SW3', 'SW3NW')
    g.add_edge('SW3NW', 'NW3')


def buildplotgraph(g):
    
    # 0
    g.add_vertex('NW0')
    g.add_vertex('NE0')
    g.add_vertex('SW0')
    g.add_vertex('SE0')
    g.add_vertex('NW1')
    g.add_vertex('NE1')
    g.add_vertex('SW1')
    g.add_vertex('SE1')
    g.add_vertex('NW2')
    g.add_vertex('NE2')
    g.add_vertex('SW2')
    g.add_vertex('SE2')
    g.add_vertex('NW3')
    g.add_vertex('NE3')
    g.add_vertex('SW3')
    g.add_vertex('SE3')
    g.vs["SMOKE"] = [False, False, False, False, False, False, False, False,
                     False, False, False, False, False, False, False, False]
    g.vs["color"] = ['white', 'white', 'white', 'white', 'white', 'white', 'white',
                     'white','white', 'white', 'white', 'white', 'white', 'white', 'white']
    
    g.vs["Motion"] = [False, False, False, False, False, False, False, False,
                      False, False, False, False, False, False, False, False]
    g.vs["TMP"] = [False, False, False, False, False, False, False, False,
                   False, False, False, False, False, False, False, False]
    
    

    g.add_edge('NW0', 'NE0')
    g.add_edge('NE0', 'SW0')
    g.add_edge('SW0', 'SE0')
    g.add_edge('SE0', 'NW0')
    # 1
    g.add_edge('NW0', 'NW1')
    g.add_edge('NE0', 'NE1')
    g.add_edge('SW0', 'SW1')
    g.add_edge('SE0', 'SE1')
    g.add_edge('NW1', 'NE1')
    g.add_edge('NE1', 'SW1')
    g.add_edge('SW1', 'SE1')
    g.add_edge('SE1', 'NW1')
    # 2
    g.add_edge('NW1', 'NW2')
    g.add_edge('NE1', 'NE2')
    g.add_edge('SW1', 'SW2')
    g.add_edge('SE1', 'SE2')
    g.add_edge('NW2', 'NE2')
    g.add_edge('NE2', 'SW2')
    g.add_edge('SW2', 'SE2')
    g.add_edge('SE2', 'NW2')
    # 3
    g.add_edge('NW2', 'NW3')
    g.add_edge('NE2', 'NE3')
    g.add_edge('SW2', 'SW3')
    g.add_edge('SE2', 'SE3')
    g.add_edge('NW3', 'NE3')
    g.add_edge('NE3', 'SW3')
    g.add_edge('SW3', 'SE3')
    g.add_edge('SE3', 'NW3')


def drawfinalgraph(g,ax,mylock,string="",fromFlash=False):

    if (fromFlash==False):
        mylock.acquire()
    try:
        layout = g.layout_kamada_kawai()
        layout.rotate(190)
        ig.plot(
            g,
            target=ax,
            layout=layout,
            vertex_color=g.vs["color"],
            vertex_label=range(g.vcount()),
            vertex_size=0.3,
            edge_width=10,
            edge_curved=[False,False,False,False,0.5,-0.4,-0.4,0.5,False,False,False,False,0.5,-0.4,-0.4,0.5,False,False,False,False,0.5,-0.4,-0.4,0.5,False,False,False,False],
            edge_color=g.es["edge_color"],
        )

I’m not sure what you mean by “manipulating” it, but igraph is not an interactive graph visualization tool so you won’t be able to manipulate it in real-time. You can take the layout object (which is basically a list of coordinates) and you can modify the coordinates from code if you want to, but note that it’s not 3D so you won’t be able to rotate it in 3D either.