OpenCog Framework  Branch: master, revision 6f0b7fc776b08468cf1b74aa9db028f387b4f0c0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
viz_graph.py
Go to the documentation of this file.
1 ##
2 # @file viz_graph.py
3 # @brief
4 # @author Dingjie.Wang
5 # @version 1.0
6 # @date 2012-07-31
7 
8 import networkx as nx
9 from collections import defaultdict
10 from m_util import log
11 
12 
13 class Tree(object):
14  """docstring for Tree"""
15  def __init__(self, op, children = []):
16  assert type(op) != type(None)
17  self._op = op
18  self._children = children
19 
20  def is_leaf(self):
21  '''docstring for is_leaf'''
22  return True if self._children else False
23 
24  def get_op(self):
25  return self._op
26 
27  def set_op(self, value):
28  self._op = value
29  op = property(get_op, set_op)
30 
31  def get_children(self):
32  return self._children
33  def set_children(self, value):
34  self._children = value
35  children = property(get_children, set_children)
36 
37  def __str__(self):
38  if self.is_leaf():
39  return str(self.op)
40  else:
41  return '(' + str(self.op) + ' '+ ' '.join(map(str, self.children)) + ')'
42 
43  def __repr__(self):
44  return str(self)
45 
46 #def trees_to_forest( trees ):
47  #'''docstring for trees_to_forest'''
48  #assert type(trees) == list
49  #return Tree("forest", trees)
50 
51 def tree_to_viz_graphic(tree, graph):
52  ''' transfer a simpler and more efficient tree StructureNode
53  to Viz_Graph for visualisation purpose
54  '''
55  if tree.children:
56  # inner node
57  assert isinstance(tree.op, str)
58  for i, child in enumerate(tree.children):
59  # make name of tree node unique
60  child_name = graph.unique_id(child.op)
61  child.op = child_name
62  child_name = tree_to_viz_graphic(child, graph)
63  graph.add_edge(tree.op, child_name, order = i)
64  return tree.op
65  else:
66  # leaf node
67  return tree.op
68 
69 
70 
71 import pygephi
73 
74  def __init__(self):
75  self.gephi = pygephi.JSONClient('http://localhost:8080/workspace0', autoflush=True)
76  self.gephi.clean()
77  self.default_node_attr = {'size':10, 'r':0.0, 'g':0.0, 'b':1.0, 'x':1}
78  self.default_edge_attr = { }
79 
80  #def start(self):
81  #pass
82 
83  #def stop(self):
84  #pass
85  def write(self, filename = None):
86  pass
87 
88  def output_node(self, node_id, **attr):
89  if attr:
90  self.gephi.add_node(str(node_id), label=attr.get('label', None), **attr)
91  else:
92  self.gephi.add_node(str(node_id), label=attr.get('label', None), **self.default_node_attr)
93 
94  def output_edge(self, source, target, **attr):
95  edge_id = attr.get('edge_id',None)
96  assert edge_id
97  self.gephi.add_edge(str(edge_id), source, target, attr.get("directed", None), label = attr.get("label", None))
98 
99 class Dotty_Output(object):
100  """docstring for Dot_output"""
101  def __init__(self):
102  self.body = ""
103 
104  def output_node(self, node_id, **attr):
105  '''docstring for output_node'''
106  line = '"%s" '% str(node_id)
107  if attr:
108  line += "[%s]"
109  str_attr = ""
110  try:
111  str_attr += "color=%s," % attr['color']
112  except Exception:
113  pass
114  try:
115  str_attr += "shape=%s," % attr['shape']
116  except Exception:
117  pass
118  try:
119  str_attr += "style=%s," % attr['style']
120  except Exception:
121  pass
122  str_attr = str_attr.strip(',')
123  line = line % str_attr
124  self.body += line + ";\n"
125 
126  def output_edge(self, source, target, **attr):
127  line = '"%s" -> "%s" ' %(str(source), str(target))
128  if attr:
129  line += "[%s]"
130  str_attr = ""
131  try:
132  str_attr += "color=%s," % attr['color']
133  except Exception:
134  pass
135 
136  try:
137  str_attr += "color=%s," % attr['attr']['color']
138  except Exception:
139  pass
140  try:
141  str_attr += "shape=%s," % attr['shape']
142  except Exception:
143  pass
144 
145  try:
146  str_attr += "shape=%s," % attr['attr']['shape']
147  except Exception:
148  pass
149  try:
150  str_attr += "style=%s," % attr['style']
151  except Exception:
152  pass
153 
154  try:
155  str_attr += 'label="%s",' % attr['attr']['style']
156  except Exception:
157  pass
158  try:
159  str_attr += 'label="%s",' % attr['order']
160  except Exception:
161  pass
162  try:
163  str_attr += 'label="%s",' % attr['attr']['order']
164  except Exception:
165  pass
166  str_attr = str_attr.strip(',')
167  line = line % str_attr
168  self.body += line + ";\n"
169 
170  def write(self, filename):
171  '''docstring for write'''
172  try:
173  f = open(filename,'w')
174  content = '''
175  digraph visualisation{
176  node[style = filled]
177  %s
178  }
179  '''
180  content = content % self.body
181  f.write(content)
182  except IOError:
183  log.error("can't write dot file: %s" % filename)
184  finally:
185  f.close()
186 
187 class Viz_Graph(object):
188  """ a wrapper to networkx, which work as a graph drawer"""
189  def __init__(self, viz = Dotty_Output()):
190  self._nx_graph = nx.DiGraph()
191  self.viz = viz
192  self.no_nodes = defaultdict(int)
193 
194  def add_edge(self, source, target, **attr):
195  self._nx_graph.add_edge(str(source), str(target))
196  if attr:
197  self.set_edge_attr(str(source), str(target), **attr)
198  # should use carefully
199  def add_edge_unique(self, source, target, **attr):
200  '''docstring for add_edge_unique'''
201  source = self.unique_id(source)
202  target = self.unique_id(target)
203  self.add_edge(source, target, **attr)
204 
205  # should use carefully, help to get a unique node id
206  # when display link.type_name, it will make add an number behind to make it unique
207  def unique_id(self, node):
208  ''' supposed to added this node later'''
209  node = str(node)
210  self.no_nodes[node] += 1
211  no_node = self.no_nodes[node]
212  if no_node > 1:
213  # have node with id source already, make it unique
214  node = node + "[%s]" % str(no_node)
215  return node
216 
217  def reset_unique(self):
218  '''docstring for reset_unique_no'''
219  self.no_nodes.clear()
220 
221  def add_node(self, node_id, **attr):
222  self._nx_graph.add_node(str(node_id))
223  for key, value in attr.items():
224  self._nx_graph.node[str(node_id)][key] = value
225 
226  def output_node(self, node_id):
227  '''docstring for output_node'''
228  assert self.viz and callable(getattr(self.viz, "output_node"))
229  self.viz.output_node(str(node_id))
230 
231  def output_edge(self, edge_id, source, target):
232  '''docstring for output_edge'''
233  assert self.viz and callable(getattr(self.viz, "output_edge"))
234  self.viz.output_edge(str(edge_id), str(source), str(target))
235 
236  def neighbors(self, node_id):
237  '''return a list of node's neighbors'''
238  return self._nx_graph.neighbors(str(node_id))
239 
240  def set_node_attr(self, node_id, **attr):
241  for key, value in attr.items():
242  self._nx_graph.node[str(node_id)][key] = value
243 
244  def get_node_attr(self, node_id):
245  return self._nx_graph.node[str(node_id)]
246 
247  def set_edge_attr(self, source, target, **attr):
248  for key, value in attr.items():
249  self._nx_graph[str(source)][str(target)][key] = value
250 
251  def get_edge_attr(self, source, target):
252  #return self._nx_graph.node[id]
253  return self._nx_graph[str(source)][str(target)]
254  def number_of_nodes(self):
255  '''docstring for number_of_nodes'''
256  return self._nx_graph.number_of_nodes()
257 
258  def write(self, filename):
259  """ draw the graph"""
260  assert self.viz
261  # output nodes
262  for node in self._nx_graph.nodes():
263  attr_dict = self._nx_graph.node[str(node)]
264  self.viz.output_node(node, attr = attr_dict)
265 
266  # output edges
267  for edge in self._nx_graph.edges():
268  attr_dict = self._nx_graph.edge[edge[0]][edge[1]]
269  self.viz.output_edge(edge[0], edge[1], attr = attr_dict)
270  self.viz.write(filename)
271 
272  #def write_json(self, root,parent = None):
273  #""" write to a javascript library"""
274  #data = '''{
275  #"id": "%s",
276  #"name" : "%s",
277  #"data": {
278  #"band": "%s",
279  #"relation": "member of band"
280  #},
281  #"children":[%s] } '''
282  #children = ""
283  #for child in self._nx_graph.neighbors(root):
284  #str_child = self.write_json(child,root)
285  #if str_child:
286  #temp = "%s," %(str_child)
287  #children += temp
288  #if children:
289  #children = children[0:len(children) - 1 ]
290  #return data %(root,root,parent,children)
291 
292  def clear(self):
293  """docstring for clear"""
294  self._nx_graph.clear()
295  self.reset_unique()
296 
297 class Graph_Abserver(object):
298  """ abstract class that help to abserve the graph according to the given filter imfo"""
299  def __init__(self, source, e_types, n_types, inheritance = True):
300  self.source = source
301  self.valid_edge_types = e_types
302  self.valid_node_types = n_types
303  self.graph = Viz_Graph()
304  self.inheritance = inheritance
305 
306 
307  def write(self, filename):
308  '''docstring for write_dot'''
309  self.graph.write(filename)
310 
311  def filter_graph(self):
312  '''docstring for run()'''
313  # add edges of valid type
314  # iterate over valid edges
315  for e_type in self.valid_edge_types:
316  edges = self._get_edges(e_type)
317  for edge in edges:
318  nodes = self._nodes_from_edge(edge)
319  # none empty edges!
320  if len(nodes) > 0:
321  if self.valid_edge(edge,nodes):
322  self.graph.add_edge(str(nodes[0]), str(nodes[1]))
323  # add edge attribute
324 
325  # abstract fuctions must be institated
326  def graph_info(self):
327  '''docstring for graph_info'''
328  #nodes = { }
329  #for e_type in self.valid_edge_types:
330  #edges = self._get_edges(e_type)
331  #for edge in edges:
332  #nodes = self._nodes_from_edge(edge)
333  ## none empty edges!
334  #if len(nodes) > 0:
335  #if self.valid_edge(edge,nodes):
336  #self.edge_types.setdefault(self._edge_type(edge), 0)
337  #self.edge_types[self._edge_type(edge)] += 1
338  #nodes[self._node_type(nodes[0])].append(nodes[0].)
339 
340  #self.graph.add_edge(nodes[0], nodes[1])
341  pass
342 
343  def _nodes_from_edge(self,edge):
344  pass
345 
346  def _get_edges(self,e_type):
347  '''type of e_type should be consistency with valid_edge_types '''
348  pass
349  def _edge_type(self,edge):
350  '''type of edge should be consistency with valid_edge_types '''
351  return edge.type
352 
353  def _node_type(self,node):
354  '''type of node should be consistency with valid_node_types '''
355  return node.type
356  # end
357  def _edge_is_a(self, source, target):
358  '''type of source and target is consistency with valid_edge_types '''
359  return source == target
360 
361  def _node_is_a(self, source, target):
362  '''type of source and target is consistency with valid_node_types '''
363  return source == target
364 
365 
366  def valid_edge(self,edge,nodes):
367  """make sure the type edge and it targets are required type,
368  if one of the target is invalid, then the edge is invalid
369  """
370  assert len(self.valid_edge_types) and len(self.valid_node_types) > 0
371  #import pdb
372  #pdb.set_trace()
373  for arg in self.valid_edge_types:
374  if self._edge_is_a(self._edge_type(edge), arg):
375  break
376  else:
377  # invalid edge
378  return False
379  #determine if the outs of link is required node type
380  for node in nodes:
381  for arg in self.valid_node_types:
382  if self._node_is_a(self._node_type(node), arg):
383  break
384  else:
385  # invalid node
386  return False
387  return True
388 __all__ = ["Dotty_Output","Gephi_Output", "Tree", "tree_to_viz_graphic", "Graph_Abserver" ]
def tree_to_viz_graphic
Definition: viz_graph.py:51
def set_children
Definition: viz_graph.py:33
def get_children
Definition: viz_graph.py:31