Does pygraphviz allow for you to render an image to a variable? I would like to serve up dynamic images via a webpage without having to render the graphs to disk.
- 
                    if you had code that worked do you mind sharing it with us? If your code works great show us your greatness! ;) – Charlie Parker May 07 '21 at 16:39
3 Answers
According to the source code if you call the draw() method of an AGraph object while omitting the path argument (or setting it to None) it will return a bytes object instead of saving to a file. Do not forget to specify the format parameter.
For example, assuming that you already have an AGraph object named A, and you want to plot this graph, you could do this:
from IPython.display import Image, display
img_bytes = A.draw(format="png")
img = Image(img_bytes)
display(img)
 
    
    - 2,195
- 2
- 17
- 14
 
    
    - 24,271
- 5
- 48
- 65
- 
                    3do you have a code example we can copy paste (and see it working)? – Charlie Parker May 07 '21 at 16:38
I couldn't find a way to do this without a file being involved, so I created this handy function:
import matplotlib.image as mpimg
import matplotlib.pyplot as plt
import networkx as nx
import pygraphviz
def plot_network(G: nx.DiGraph):
  ag = nx.nx_agraph.to_agraph(G)
  ag.layout(prog="dot")
  temp = tempfile.NamedTemporaryFile(delete=False)
  tempname = temp.name + ".png"
  ag.draw(tempname)
  img = mpimg.imread(tempname)
  plt.imshow(img)
  plt.show()
  os.remove(tempname)
 
    
    - 56,349
- 34
- 180
- 251
I think is is what you want:
# https://stackoverflow.com/questions/28533111/plotting-networkx-graph-with-node-labels-defaulting-to-node-name
import dgl
import numpy as np
import torch
import networkx as nx
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
from pathlib import Path
g = dgl.graph(([0, 0, 0, 0, 0], [1, 2, 3, 4, 5]), num_nodes=6)
print(f'{g=}')
print(f'{g.edges()=}')
# Since the actual graph is undirected, we convert it for visualization purpose.
g = g.to_networkx().to_undirected()
print(f'{g=}')
# relabel
int2label = {0: "app", 1: "cons", 2: "with", 3: "app3", 4: "app4", 5: "app5"}
g = nx.relabel_nodes(g, int2label)
# https://networkx.org/documentation/stable/reference/drawing.html#module-networkx.drawing.layout
g = nx.nx_agraph.to_agraph(g)
print(f'{g=}')
print(f'{g.string()=}')
# draw
g.layout()
g.draw("file.png")
# https://stackoverflow.com/questions/20597088/display-a-png-image-from-python-on-mint-15-linux
img = mpimg.imread('file.png')
plt.imshow(img)
plt.show()
# remove file https://stackoverflow.com/questions/6996603/how-to-delete-a-file-or-folder
Path('./file.png').expanduser().unlink()
# import os
# os.remove('./file.png')
you basically need to render the graph object explicitly from the file and then delete it (unfortunately idk of a better answer). For more details check out my long discussion on why I think pygraphviz is the way to go (and not networkx) for visualizing: https://stackoverflow.com/a/67439711/1601580
 
    
    - 5,884
- 57
- 198
- 323
