我正在尝试使用python graph_tool创建一个交互式图形。该图将显示一条从源顶点到目标顶点的最短路径,该路径由鼠标指向,方法是将边缘颜色从灰色更改为橙色。
我想知道当我将鼠标悬停在顶点上时如何禁用相邻顶点的红色突出显示,因为它隐藏了边缘颜色。
例如,当鼠标悬停在顶点2上时,到目标顶点6的路径是2-> 1-> 6,但是到2-> 1的路径被红色突出显示隐藏。
我想widget
默认情况下会突出显示。当我在代码中插入以下内容时,高亮显示将被禁用,如右图所示。
widget.highlight=False
但是,此代码显然不正确,因为它会导致以下错误:
AttributeError Traceback (most recent call last)
/usr/lib/python3/dist-packages/graph_tool/draw/gtk_draw.py in draw(self, da, cr)
596 eprops["color"] = self.highlight_color
597
--> 598 self.highlight.fa = self.selected.fa
599 infect_vertex_property(GraphView(self.g, directed=False),
600 self.highlight, [True])
AttributeError: 'bool' object has no attribute 'fa'
我的工作代码如下所示。它很大程度上依赖于graph_tool项目站点(https://graph-tool.skewed.de/static/doc/demos/animation/animation.html)上的示例代码。
def intaractive_graph():
from gi.repository import Gtk, Gdk
import sys
offscreen=sys.argv[1]=='offscreen' if len(sys.argv) > 1 else False
# generate a graph (the code is omitted here)
g=generate_graph()
# graph layout
pos=gt.fruchterman_reingold_layout(g, n_iter=1000)
# color vectors
gray=[0.179, 0.203,0.210, 0.8]
orange=[0.807843137254902, 0.3607843137254902, 0.0, 1.0]
# edge color
ecolor=g.new_edge_property("vector<double>")
for e in g.edges(): ecolor[e]=gray
win=gt.GraphWindow(g, pos=pos, geometry=(800, 800),
vertex_text=g.vertex_index,
vertex_shape=g.vertex_properties['Shape'],
vertex_fill_color=g.vertex_properties['Color'],
edge_color=ecolor)
count=0
def update_bfs(widget, event, old_src=None):
global g, count, win
# check if hovering point is on a vertex and get the vertex index (src)
src=widget.picked
if src is None: return True
if isinstance(src, gt.PropertyMap):
src=[v for v in g.vertices() if src[v]]
if len(src)==0: return True
src=src[0]
# exit when the src is unchanged
if src==old_src: return True
old_src=src
# get the edge list of the shortest path
vlist, elist=gt.shortest_path(g, src, g.vertex(6))
elist=[e for e in elist]
# reset all edge color
for e in g.edges(): ecolor[e]=gray
# show the shortest path in orange
for e in g.edges():
if e in elist:
ecolor[e]=orange
widget.regenerate_surface()
widget.queue_draw()
#widget.highlight=False <-- This disables highlight, but causes an error
if offscreen:
print('offscrean')
window=widget.get_window()
pixbuf=Gdk.pixbuf_get_from_window(window, 0, 0, 500, 400)
pixbuf.savev(r'./frames/bfs%06d.png' % count, 'png', [], [])
count+=1
win.graph.connect('motion_notify_event', update_bfs)
win.connect('delete_event', Gtk.main_quit)
win.show_all()
Gtk.main()
intaractive_graph()