pretty printing graphs
Scherer, Bill
Bill.Scherer at verizonwireless.com
Mon Jul 28 13:27:43 EDT 2003
On Mon, 28 Jul 2003, John Hunter wrote:
>
> I have a tree structure (directed acyclic graph), where each node can
> represent itself as a multi-line string that is not very wide (eg, 10
> chars per line). I would like to print the graph like
>
> C
> C1 C2
> C1a C1b C2a C2b
[P&M]
John -
Do you strictly require plain text output? If not, look into
graphiz. It's fairly easy to generate dot files from python and
then generate output in postscript or in a bitmap format (jpg,
png, etc) using the graphiz tools.
graphiz can be had from http://www.graphviz.org
There is a python interface to graphviz available from
http://www.cs.brown.edu/~er/software , but I have not used it.
graphviz's output is customizable to some extant, and looks
rather nice.
HTH,
Bill
>
> Where C, C1, etc.. are the multiline string blocks referred to above.
> Does anybody know of a tool that can do this. Here is an example,
> somewhat long because I have to create the multiline strings.
>
> from __future__ import division, generators
>
> def enumerate(seq):
> "Waiting for python 2.3"
> for i in range(len(seq)):
> yield i, seq[i]
>
> class O:
>
> def __init__(self, text):
> self.text = text
> def __str__(self):
> return self.text
>
> class Node:
> def __init__(self, o):
> self.node = o
> self.children = []
>
> def __str__(self):
> s = ''
> #s += str(self.node) + '\n\n'
> if len(self.children)==0: return s
> childStrs = [str(child.node) for child in self.children]
>
> lines = [[] for tmp in childStrs]
> for lineNum, t in enumerate(childStrs):
> lines[lineNum].extend(t.split('\n'))
>
> maxLines = max([len(l) for l in lines])
> sep = ' '
> for lineNum in range(maxLines):
> row = ''
> for childNum in range(len(childStrs)):
> row += lines[childNum][lineNum] + sep
> s += row + '\n'
> s += '\n\n'
> for l in self.children:
> s += str(l)
> return s
>
>
>
> n0 = Node(O("""1 2 3 0
> 1 2 3 4
> 1 2 1 5
> 1 2 1 1
> 4 3 2 2
> 4 3 2 7
> 2 3 2 3
> 2 3 2 9"""))
>
>
> n1 = Node(O("""1 2 3 0
> 1 2 3 4
> 1 2 1 5
> 1 2 1 1
> ----------
> 1 1 0 0"""))
>
> n2 = Node(O("""4 3 2 2
> 4 3 2 7
> 2 3 2 3
> 2 3 2 9
> ----------
> 0 1 1 0"""))
>
>
>
> n1a = Node(O("""1 2 1 5
> 1 2 1 1
> ----------
> 1 1 1 0"""))
>
> n1b = Node(O("""1 2 3 0
> 1 2 3 4
> ----------
> 1 1 1 0"""))
>
> n2a = Node(O("""2 3 2 3
> 2 3 2 9
> ----------
> 1 1 1 0"""))
>
> n2b = Node(O("""4 3 2 2
> 4 3 2 7
> ----------
> 1 1 1 0"""))
>
>
> n0.children.extend([n1, n2])
> n1.children.extend([n1a, n1b])
> n2.children.extend([n2a, n2b])
> print n0
>
> Which prints:
>
> 1 2 3 0 4 3 2 2
> 1 2 3 4 4 3 2 7
> 1 2 1 5 2 3 2 3
> 1 2 1 1 2 3 2 9
> ---------- ----------
> 1 1 0 0 0 1 1 0
>
>
> 1 2 1 5 1 2 3 0
> 1 2 1 1 1 2 3 4
> ---------- ----------
> 1 1 1 0 1 1 1 0
>
>
> 2 3 2 3 4 3 2 2
> 2 3 2 9 4 3 2 7
> ---------- ----------
> 1 1 1 0 1 1 1 0
>
>
> This does part of the work, printing the child nodes on the same rows,
> but doesn't the hierarchical part very well. What I would like is
> something like this:
>
> 1 2 3 0
> 1 2 3 4
> 1 2 1 5
> 1 2 1 1
> 4 3 2 2
> 4 3 2 7
> 2 3 2 3
> 2 3 2 9
>
> 1 2 3 0 4 3 2 2
> 1 2 3 4 4 3 2 7
> 1 2 1 5 2 3 2 3
> 1 2 1 1 2 3 2 9
> ---------- ----------
> 1 1 0 0 0 1 1 0
>
>
> 1 2 1 5 1 2 3 0 2 3 2 3 4 3 2 2
> 1 2 1 1 1 2 3 4 2 3 2 9 4 3 2 7
> ---------- ---------- ---------- ----------
> 1 1 1 0 1 1 1 0 1 1 1 0 1 1 1 0
>
>
> Thanks,
> John Hunter
>
>
--
Bill.Scherer at Verizon Wireless
RHCE 807101044903581
More information about the Python-list
mailing list