Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Display graph without saving using pydot

Tags:

python

pydot

Here's a simple solution using IPython:

from IPython.display import Image, display

def view_pydot(pdot):
    plt = Image(pdot.create_png())
    display(plt)

Example usage:

import networkx as nx
to_pdot = nx.drawing.nx_pydot.to_pydot
pdot = to_pdot(nx.complete_graph(5))
view_pydot(pdot)

You can render the image from pydot by calling GraphViz's dot without writing any files to the disk. Then just plot it. This can be done as follows:

import io

import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import networkx as nx

# create a `networkx` graph
g = nx.MultiDiGraph()
g.add_nodes_from([1,2])
g.add_edge(1, 2)

# convert from `networkx` to a `pydot` graph
pydot_graph = nx.drawing.nx_pydot.to_pydot(g)

# render the `pydot` by calling `dot`, no file saved to disk
png_str = pydot_graph.create_png(prog='dot')

# treat the DOT output as an image file
sio = io.BytesIO()
sio.write(png_str)
sio.seek(0)
img = mpimg.imread(sio)

# plot the image
imgplot = plt.imshow(img, aspect='equal')
plt.show()

This is particularly useful for directed graphs.

See also this pull request, which introduces such capabilities directly to networkx.


Based on this answer (how to show images in python), here's a few lines:

gr = ... <pydot.Dot instance> ...

import tempfile, Image
fout = tempfile.NamedTemporaryFile(suffix=".png")
gr.write(fout.name,format="png")
Image.open(fout.name).show()

Image is from the Python Imaging Library


This worked for me inside a Python 3 shell (requires the Pillow package):

import pydot
from PIL import Image
from io import BytesIO

graph = pydot.Dot(graph_type="digraph")
node = pydot.Node("Hello pydot!")
graph.add_node(node)

Image.open(BytesIO(graph.create_png())).show()

You can also add a method called _repr_html_ to an object with a pydot graph member to render a nice crisp SVG inside a Jupyter notebook:

class MyClass:
    def __init__(self, graph):
        self.graph = graph

    def _repr_html_(self):
        return self.graph.create_svg().decode("utf-8")

IPython.display.SVG method embeds an SVG into the display and can be used to display graph without saving to a file.

Here, keras.utils.model_to_dot is used to convert a Keras model to dot format.

from IPython.display import SVG
from tensorflow import keras

#Create a keras model.
model = keras.models.Sequential()
model.add(keras.layers.Dense(units=2, input_shape=(2,1), activation='relu'))
model.add(keras.layers.Dense(units=1, activation='relu'))

#model visualization
SVG(keras.utils.model_to_dot(model).create(prog='dot', format='svg'))