1

I am writing an algorithm to represent regression trees, using pydot module (an interface to Graphviz's Dot language). In the algorithm, lists of Edges and Nodes are made, and then they are represented - that is working fine.

But in some specific situations, I need to remove some of the Edges and Nodes, and that's where I am getting stuck. Here is part of the code:

import pydot
graph = pydot.Dot(graph_type='graph')

link4 = pydot.Edge(node10, node21, label=etiquetas[3])
link5 = pydot.Edge(node11, node22, label=etiquetas[4])
lista_links = [link4, link5]

# if some conditions are verified, then:
lista_links.remove(link5)

for link in lista_links:
graph.add_edge(link)
graph.write_png('teste.png')

I was expecting this code to work without any problem, but I get an error, saying:

AttributeError: 'NoneType' object has no attribute 'get_top_graph_type'

My only idea is, instead of removing the Nodes and Edges in some specific situations, to change the code and add only the Nodes and Edges after I define all the specific situations. But that would be a lot more work... (The code is much bigger than what I've shown you, and I have several specific situations that need to be considered).

I am curious why python behaves like this... Can somebody explain that to me, or give me any idea on how to change this behavior?

Thanks in advance, Carla

carla
  • 2,181
  • 19
  • 26

1 Answers1

1

At the surface, it seems that the problem is in Edges or Nodes without parent graph. So, the overall solution would be: do not allow nodes and edges hang around, always attach them to graph,and then remove from graph as needed.

spacediver
  • 1,483
  • 1
  • 11
  • 18
  • The exception occurs at line 821 of the file pydot.pyc in __eq__(self, edge) if self.get_parent_graph().get_top_graph_type() == 'graph': – carla Jul 15 '11 at 16:11
  • It is unclear from this, what your code does call, which leads to exception. Please provide the full stack, if you can. It seem that inside pydot the None values takes place of what the library expects to be an object (Edge, or something that has get_top_graph_type() method). – spacediver Jul 15 '11 at 16:15
  • At the surface, it seems that the problem is in Edges or Nodes without parent graph. So, the overall solution would be: do not allow nodes and edges hang around, always attach them to graph,and then remove from graph as needed. – spacediver Jul 15 '11 at 16:19
  • That could be a better solution! But how can I remove Edges or Nodes from a graph? – carla Jul 15 '11 at 16:26
  • from the pydot documentation it seems that graph has .del_node method, which deletes all nodes by name. So your task is to keep a list of the names of your nodes and edges (that is, plain strings) to be deleted later, and then just delete them. Please note that while deleting elements by name you will delete ALL the elements having that name -- so keep eye on names uniqueness. – spacediver Jul 15 '11 at 16:39
  • don't hesitate to select my answer if it really works for you :) – spacediver Jul 15 '11 at 18:26
  • it is not working :( the method graph.del_node(nodeXX) return 'False' for me. it is weird because the aspect of these nodes and edges that I want to remove change (they go to default aspect) but they are not deleted... – carla Jul 15 '11 at 22:27
  • Got it now. I was not using the .del_edge method properly. So I was deleting the nodes, but as the edges were not, the same nodes were automatically created, using the default style. The correct syntax of this method is graph.del_edge(source_node, destination_node). The syntax graph.del_edge(pydot.Edge object) doesn't work, although no error or warning is raised. – carla Jul 15 '11 at 23:11
  • _The syntax graph.del_edge(pydot.Edge object) doesn't work, although no error or warning is raised_. And should this syntax work? I cannot find this in the [documentation](http://code.google.com/p/pydot/downloads/detail?name=pydot.html&can=2&q=). That is the nature of python -- no types are checked at the compile time, and in this case, the `del_edge` function is written so that it silently does nothing upon receiving invalid parameter types. General recommendation would be: use the libraries according to documentation and enclosed examples, or peek inside the source to be sure. :) – spacediver Jul 16 '11 at 01:42