Question

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.

Was it helpful?

Solution

According to the sources if you call draw method of AGraph object while path parameter is omitted (or set to None) it will return data instead saving to a file. Do not forget to specify format paramater.

OTHER TIPS

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)

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

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top