marcomusy / vedo

A python module for scientific analysis of 3D data based on VTK and Numpy
https://vedo.embl.es
MIT License
2.04k stars 265 forks source link

Using `onclick` function to display node properties of a network #763

Open DeepaMahm opened 1 year ago

DeepaMahm commented 1 year ago

Hello @marcomusy ,

I'm exporting a network graph to html file and I would like to display the values of the graph nodes using the onclick method.

For instance, the time-series value of node 1 is stored in a dict, data['node1'] = [0,1,2,3,4,6].

I could use the export function to export the network in x3d format.

import networkx as nx
from vedo import *

G = nx.gnm_random_graph(n=5, m=10)
nxpos = nx.spring_layout(G, dim=3, seed=1)

nxpts = [nxpos[pt] for pt in sorted(nxpos)]
nx_lines = [(nxpts[i], nxpts[j]) for i, j in G.edges()]
pts = Points(nxpts, r=10).lighting('off')
edg_w = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

edg = []
for n in range(0, 10):
    line = Line(nx_lines[n]).lw(edg_w[n])
    edg.append(line)

plt = Plotter(N=1, size=(320, 240))
show(pts, *edg, axes=True, bg='w', title='plot')
plt.export('network.x3d', binary=False)

I had a look at the onclick method, but I am not sure how to implement it for my use case and display the time-series values corresponding to each node in a plot window. Example, if I select node 1 and node 2, I would like to see two curves displayed on the plot window (sample).

Could you please help me with this?

Thanks a lot for your time and kind attention

marcomusy commented 1 year ago

You mean you want this to end up in a html web server? It not possible (in vedo)! I´m not sure if you can do it by modifying the X3D file - but I'm not expert on that.

What your can do in vedo is to create an interactivity function like:

import networkx as nx
from vedo import *

def func(event): 
    if not event.actor:
        return
    c = get_color_name(event.actor.color())
    txt2d.text(f"RGB color is {c}")

G = nx.gnm_random_graph(n=5, m=10)
nxpos = nx.spring_layout(G, dim=3, seed=1)

nxpts = [nxpos[pt] for pt in sorted(nxpos)]
nx_lines = [(nxpts[i], nxpts[j]) for i, j in G.edges()]
pts = Points(nxpts, r=10).lighting('off')
edg_w = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

edg = []
for n in range(0, 10):
    line = Line(nx_lines[n]).lw(edg_w[n])
    line.pickable(True)
    line.color(n)
    edg.append(line)

txt2d = Text2D(font="Calco", s=2)

plt = Plotter(N=1, size=(320, 240))
plt.add_callback("on click", func)
plt.show(pts, *edg, txt2d, axes=True, bg='w', title='plot')

..but only within a python script.

DeepaMahm commented 1 year ago

Hello @marcomusy ,

Thanks a lot! This works great in python script. You mean you want this to end up in a html web server? It not possible (in vedo)!

Yes, I would like to do the same in a html web server. I tried to look into Cytoscape for this task. But this mostly supports only 2D networks.

I´m not sure if you can do it by modifying the X3D file

Thanks for the tip, I will surely check how this can be done.

Could you please suggest if there are other packages that I could check for doing these in html web server?

marcomusy commented 1 year ago

If you already have a set of simple points and lines maybe you can use k3d: https://github.com/K3D-tools/K3D-jupyter

DeepaMahm commented 1 year ago

Hello @marcomusy ,

We tried k3d . Unfortunately, it doesn't support click callback functionality for points and lines at this moment

Callbacks are supported for

k3d.marching_cubes
k3d.mesh
k3d.surface
k3d.texture
k3d.voxels
k3d.sparse_voxels
k3d.voxels_group

I would like to know if I can export the network that we create in vedo as a mesh object and use in k3d.

DeepaMahm commented 1 year ago

Hi @marcomusy ,

This is a kind reminder.

marcomusy commented 1 year ago

Hi @DeepaMahm sorry for the late reply. If you aim at serving this through the web and the whole thing is just 2D probably you should go for tools like plotly or altair...