显示图形而不使用 pydot 保存
Posted
技术标签:
【中文标题】显示图形而不使用 pydot 保存【英文标题】:Display graph without saving using pydot 【发布时间】:2011-06-03 13:48:34 【问题描述】:我正在尝试使用 pydot 显示一个简单的图表。
我的问题是,有什么方法可以在不将其写入文件的情况下显示图形,因为目前我使用 write 函数首先绘制,然后必须使用 Image 模块来显示文件。
但是有什么方法可以直接将图形打印在屏幕上而不保存??
另外,作为一个更新,我想在同一个问题中问我观察到,虽然当我使用 Image 模块的 show 命令时图像会很快保存,但要看到图像需要相当长的时间...... . 有时我也会收到无法打开图像的错误,因为它被删除或保存在不可用的位置,这是不正确的,因为我将它保存在我的桌面.....有谁知道发生了什么并且在那里加载图像的更快方法.....
非常感谢....
【问题讨论】:
相关:***.com/questions/10379448/… 相关但适用于 pygraphviz:***.com/questions/18608316/… 我也很想知道如何在 pygraphviz 中进行操作。 【参考方案1】:这是一个使用 IPython 的简单解决方案:
from IPython.display import Image, display
def view_pydot(pdot):
plt = Image(pdot.create_png())
display(plt)
示例用法:
import networkx as nx
to_pdot = nx.drawing.nx_pydot.to_pydot
pdot = to_pdot(nx.complete_graph(5))
view_pydot(pdot)
【讨论】:
这应该是公认的答案。正是我所需要的:使用控制台(例如 spyder)立即用尽可能少的行显示图表【参考方案2】:您可以通过调用GraphViz
的dot
从pydot
渲染图像,而无需将任何文件写入磁盘。然后只是绘制它。这可以按如下方式完成:
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()
这对于有向图特别有用。
另请参阅此pull request,它将此类功能直接介绍给networkx
。
【讨论】:
作为一个快速附录,如果你在笔记本中,你可以直接使用Image(png_str)
(来自IPython.display
)渲染png_str
(字节)。
在本次改编中做了一些小调整:github.com/EricCousineau-TRI/repro/blob/… 感谢发布此代码! (最后只使用了pydot
,因为它能够处理这种情况下感兴趣的图。)
@EricCousineau 根据g = pydot.graph_from_dot_data(dot_text)
的声明,您似乎使用的是较旧的pydot
版本。请注意,从pydot == 1.2.3
开始,函数graph_from_dot_data
在所有情况下都返回list
(在以前的版本中,它在单例时返回一个图形)。另见this comment、github.com/erocarrera/pydot/blob/…、github.com/erocarrera/pydot/blob/…。
啊,谢谢! (更新:github.com/EricCousineau-TRI/repro/blob/51e8020/python/…)
有没有办法同时保留图像中的边缘标签?【参考方案3】:
基于this answer(如何在python中显示图像),这里有几行:
gr = ... <pydot.Dot instance> ...
import tempfile, Image
fout = tempfile.NamedTemporaryFile(suffix=".png")
gr.write(fout.name,format="png")
Image.open(fout.name).show()
Image
来自Python Imaging Library
【讨论】:
截至 2019 年 3 月,Python Imaging Library 大部分被Pillow取代【参考方案4】:这在 Python 3 shell 中对我有用(需要 Pillow
包):
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()
您还可以将名为 _repr_html_
的方法添加到具有 pydot graph
成员的对象中,以在 Jupyter 笔记本中呈现漂亮清晰的 SVG:
class MyClass:
def __init__(self, graph):
self.graph = graph
def _repr_html_(self):
return self.graph.create_svg().decode("utf-8")
【讨论】:
【参考方案5】:IPython.display.SVG 方法将 SVG 嵌入到显示中,可用于显示图形而无需保存到文件。
这里,keras.utils.model_to_dot 用于将 Keras 模型转换为点格式。
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'))
【讨论】:
【参考方案6】:恐怕pydot
使用graphviz
来渲染图形。即,它运行可执行文件并加载生成的图像。
底线 - 不,您无法避免创建文件。
【讨论】:
johntex 提供了解决方案 查看我的解决方案。它很简单并且避免创建文件:) 虽然在技术上是正确的,但答案并没有帮助。您必须创建文件,但不必写入磁盘。查看此问题的其他答案..【参考方案7】:它也适用于AGraph Class
https://pygraphviz.github.io/documentation/latest/reference/agraph.html#pygraphviz.AGraph.draw
如果 path 为 None,则结果作为 Bytes 对象返回。
所以,只需省略此参数即可返回图像数据而不将其保存到磁盘
使用
from networkx.drawing.nx_agraph import graphviz_layout, to_agraph
g = nx.Graph()
...
A = to_agraph(g)
A.draw()
https://networkx.org/documentation/stable/reference/drawing.html#module-networkx.drawing.nx_agraph
为了显示保存为字节对象的结果图像:
# create image without saving to disk
img = A.draw(format='png')
image = Image.open(BytesIO(img))
image.show(title="Graph")
需要
from PIL import Image
from io import BytesIO
【讨论】:
对我来说,这并没有打开一个带有图形图片的窗口...... 现在我扩展了我的答案并包含了一个代码 sn-p 来显示图表。img
是生成的“字节对象”,可以显示或以其他方式处理。在这个例子中,我演示了如何在不保存到磁盘的情况下显示它以上是关于显示图形而不使用 pydot 保存的主要内容,如果未能解决你的问题,请参考以下文章
不能使用 matplotlib.use('Agg'),图形总是显示在屏幕上
在 ipython 中调用 pylab.savefig 而不显示