blob: f5d5cd105354b974f6b17c744dfd3b936b5d2bf7 [file] [log] [blame]
Jacob Biesingerc4083582013-07-08 13:55:59 -07001#!/usr/bin/env python
2"""
3Convert a graph to graphviz format and run `dot` on it.
4
5Kmer sequences are included
6"""
7
8__author__ = "Jacob Biesinger"
9__copyright__ = "Copyright 2009-2013, The Regents of the University of California"
10__license__ = "Apache"
11
12
13import sys
14import os
15import glob
16import re
17import string
18
19import pydot
20
21
22element_re = re.compile(r"\d+,\d+|\w+")
23#edge_colors = dict(FF='black', FR='red', RF='blue', RR='gray')
24edge_colors = dict(FF='#DD1E2F', FR='#EBB035', RF='#06A2CB', RR='#218559')
25
26def reverse_complement(kmer, _table=string.maketrans('ACGT', 'TGCA')):
27 return string.translate(kmer, _table)[::-1]
28
29def add_legend(graph):
30 legend = pydot.Subgraph('cluster_legend', splines='line', rankdir='LR', label='legend', rank='min')
31 for i, (edgetype, edgecolor) in enumerate(sorted(edge_colors.items())):
32 legend.add_node(pydot.Node('legend_0_' + str(i), label='', shape='point'))
33 legend.add_node(pydot.Node('legend_1_' + str(i), label='', shape='point'))
34 legend.add_edge(pydot.Edge('legend_0_' + str(i), 'legend_1_' + str(i), label=edgetype, color=edgecolor))
35 graph.add_subgraph(legend)
36 return graph
37
38def graph_from_file(filename, legend=True, kmers=True, flag=True):
39 graph_name = os.path.split(filename)[1].replace('.', '_')
40 graph = pydot.Dot(graph_name, graph_type='digraph', rankdir='LR', splines='ortho', weight='2')
41 if legend:
42 add_legend(graph)
43
44 # annoyingly, order matters. add nodes before any edges or else properties aren't set right
45 nodes = {}
46 edges = []
47 for line in open(filename):
48 nodeid, ff, fr, rf, rr, kmer, flag = map(element_re.findall, line.strip().split('\t'))
49 nodeid, kmer, flag = nodeid[0], kmer[0], flag[0]
50 readid = nodeid.split(',')[0]
51 flag = '--%s' % flag if flag else ''
52 FF_kmer = '<TR><TD BGCOLOR="%s">%s</TD></TR>' % (edge_colors['FF'], kmer) if kmers else ''
53 RR_kmer = '<TR><TD BGCOLOR="%s">%s</TD></TR>' % (edge_colors['RR'], reverse_complement(kmer)) if kmers else ''
54 node_label = r'''<<FONT POINT-SIZE="10"><TABLE ALIGN="CENTER" BORDER="0" CELLBORDER="0" CELLSPACING="0">
Jacob Biesingerc4083582013-07-08 13:55:59 -070055 <TR><TD>{nodeid}{flag}</TD></TR>
Jake Biesinger67e67aa2013-07-10 11:45:39 -070056 {FF_kmer}
Jacob Biesingerc4083582013-07-08 13:55:59 -070057 {RR_kmer}
58 </TABLE></FONT>>'''.format(**locals())
59 node = pydot.Node(nodeid, rank=readid, group=readid, label=node_label)
60 nodes.setdefault(readid, []).append(node)
61 for edgename, edgelist in [('FF', ff), ('FR', fr), ('RF', rf), ('RR', rr)]:
62 for e in edgelist:
63 edges.append(pydot.Edge(nodeid, e, color=edge_colors[edgename]))
64
65 for readid, subnodes in nodes.items():
66 subg = pydot.Subgraph('cluster_' + readid, fillcolor='lightgray')
67 for node in subnodes:
68 subg.add_node(node)
69 graph.add_subgraph(subg)
70
71 for e in edges:
72 graph.add_edge(e)
73
74 return graph
75
76def recursive_plot(topdir, suffix='.txt'):
77 "Recursively plot any files matching `suffix`"
78 def matches(f):
79 return os.path.isfile(f) and f.endswith(suffix)
80
81 for root, dirnames, filenames in os.walk(topdir):
82 for filename in filter(matches, filenames):
83 try:
84 graph = graph_from_file(os.path.join(root, filename))
85 except Exception:
86 raise
87 else:
88 graph.write_png(f + '.png')
89
90
91def main(args):
92 for f in args:
93 try:
94 graph = graph_from_file(f)
95 except Exception as e:
96 raise
97 else:
98 graph.write_png(f + '.png')
99
100if __name__ == '__main__':
101 main(sys.argv[1:])