I have generated a 3D graph network using the following code and Mayavi has been used for visualization.
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import networkx as nx
from mayavi import mlab
pos = [[0.1, 2, 0.3], [40, 0.5, -10],
[0.1, -40, 0.3], [-49, 0.1, 2],
[10.3, 0.3, 0.4], [-109, 0.3, 0.4]]
pos = pd.DataFrame(pos, columns=['x', 'y', 'z'])
ed_ls = [(x, y) for x, y in zip(range(0, 5), range(1, 6))]
G = nx.Graph()
G.add_edges_from(ed_ls)
nx.draw(G)
plt.show()
# plot 3D in mayavi
edge_size = 0.2
edge_color = (0.8, 0.8, 0.8)
bgcolor = (0, 0, 0)
mlab.figure(1, bgcolor=bgcolor)
mlab.clf()
for i, e in enumerate(G.edges()):
# ----------------------------------------------------------------------------
# the x,y, and z co-ordinates are here
pts = mlab.points3d(pos['x'], pos['y'], pos['z'],
scale_mode='none',
scale_factor=1)
# ----------------------------------------------------------------------------
pts.mlab_source.dataset.lines = np.array(G.edges())
tube = mlab.pipeline.tube(pts, tube_radius=edge_size)
mlab.pipeline.surface(tube, color=edge_color)
mlab.show()
I would like to ask for suggestions on how to save this 3D graph in VTK format/ how to convert Networkx graph object to a VTK file for visualization in Paraview.
EDIT: I've tried to adapt the code available here for the input Networkx graph shared above. However, I am not able to obtain the output. I just get an empty window and the vtkpolyData is not plotted in the window.
"""
This code converts netwrokx graph to vtk polyData
ref: https://networkx.github.io/documentation/networkx-0.37/networkx.drawing.nx_vtk-pysrc.html
"""
import vtk
import pandas as pd
import networkx as nx
import matplotlib.pyplot as plt
from vtk.util.colors import banana, plum
def draw_nxvtk(G, node_pos):
"""
Draw networkx graph in 3d with nodes at node_pos.
See layout.py for functions that compute node positions.
node_pos is a dictionary keyed by vertex with a three-tuple
of x-y positions as the value.
The node color is plum.
The edge color is banana.
All the nodes are the same size.
"""
# set node positions
np={}
for n in G.nodes():
try:
np[n]=node_pos[n]
except nx.NetworkXError:
print("node %s doesn't have position"%n)
nodePoints = vtk.vtkPoints()
i=0
for (x,y,z) in np.values():
nodePoints.InsertPoint(i, x, y, z)
i=i+1
# Create a polydata to be glyphed.
inputData = vtk.vtkPolyData()
inputData.SetPoints(nodePoints)
# Use sphere as glyph source.
balls = vtk.vtkSphereSource()
balls.SetRadius(.05)
balls.SetPhiResolution(20)
balls.SetThetaResolution(20)
glyphPoints = vtk.vtkGlyph3D()
glyphPoints.SetInputData(inputData)
glyphPoints.SetSourceData(balls.GetOutput())
glyphMapper = vtk.vtkPolyDataMapper()
glyphMapper.SetInputData(glyphPoints.GetOutput())
glyph = vtk.vtkActor()
glyph.SetMapper(glyphMapper)
glyph.GetProperty().SetDiffuseColor(plum)
glyph.GetProperty().SetSpecular(.3)
glyph.GetProperty().SetSpecularPower(30)
# Generate the polyline for the spline.
points = vtk.vtkPoints()
edgeData = vtk.vtkPolyData()
# Edges
lines = vtk.vtkCellArray()
i = 0
for e in G.edges():
# The edge e can be a 2-tuple (Graph) or a 3-tuple (Xgraph)
u = e[0]
v = e[1]
if v in node_pos and u in node_pos:
lines.InsertNextCell(2)
for n in (u, v):
(x, y, z) = node_pos[n]
points.InsertPoint(i, x, y, z)
lines.InsertCellPoint(i)
i = i+1
edgeData.SetPoints(points)
edgeData.SetLines(lines)
# Add thickness to the resulting line.
Tubes = vtk.vtkTubeFilter()
Tubes.SetNumberOfSides(16)
Tubes.SetInputData(edgeData)
Tubes.SetRadius(.01)
#
profileMapper = vtk.vtkPolyDataMapper()
profileMapper.SetInputData(Tubes.GetOutput())
#
profile = vtk.vtkActor()
profile.SetMapper(profileMapper)
profile.GetProperty().SetDiffuseColor(banana)
profile.GetProperty().SetSpecular(.3)
profile.GetProperty().SetSpecularPower(30)
# Now create the RenderWindow, Renderer and Interactor
ren = vtk.vtkRenderer()
renWin = vtk.vtkRenderWindow()
renWin.AddRenderer(ren)
iren = vtk.vtkRenderWindowInteractor()
iren.SetRenderWindow(renWin)
# Add the actors
ren.AddActor(glyph)
ren.AddActor(profile)
renWin.SetSize(640, 640)
iren.Initialize()
renWin.Render()
iren.Start()
if __name__ == "__main__":
pos = [[0.1, 2, 0.3], [40, 0.5, -10],
[0.1, -40, 0.3], [-49, 0.1, 2],
[10.3, 0.3, 0.4], [-109, 0.3, 0.4]]
pos = pd.DataFrame(pos, columns=['x', 'y', 'z'])
pos_d = pos.T.to_dict(orient='list')
ed_ls = [(x, y) for x, y in zip(range(0, 5), range(1, 6))]
G = nx.Graph()
G.add_edges_from(ed_ls)
# nx.draw(G, with_labels=True, pos=nx.spring_layout(G))
# plt.show()
draw_nxvtk(G=G, node_pos=pos_d)
Suggestions on how to view the output with the polyData displayed while running the above code and how to save the vtkPolyData for importing in Paraview will be really helpful.