Skip to content

Commit 7cf0ced

Browse files
committed
Move graphing etc to script not core library
1 parent d48c5bb commit 7cf0ced

10 files changed

Lines changed: 267 additions & 328 deletions

File tree

bin/pyreference_biotype.py

Lines changed: 228 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,24 @@
11
from __future__ import print_function, absolute_import
22

33
import HTSeq
4+
import abc
45
from argparse import ArgumentParser
56
from collections import Counter
7+
import csv
8+
import logging
9+
from matplotlib.backends.backend_agg import FigureCanvasAgg
10+
from matplotlib.cm import ScalarMappable
11+
from matplotlib.figure import Figure
12+
from matplotlib.patches import Rectangle
13+
import os
14+
from pyreference import Reference
15+
from pyreference.utils import iv_iterators
16+
from pyreference.utils.file_utils import name_from_file_name, file_or_file_name
17+
from pyreference.utils.genomics_utils import opposite_strand, format_chrom
618
import six
719
import sys
820

921
import numpy as np
10-
from pyreference import Reference
11-
from pyreference.utils import iv_iterators
12-
from pyreference.utils.csv_utils import write_csv_dict
13-
from pyreference.utils.file_utils import name_from_file_name
14-
from pyreference.utils.genomics_utils import opposite_strand, format_chrom
15-
from pyreference.utils.graphing import write_stacked_bar_graph, \
16-
write_individual_bar_graphs
1722

1823

1924
MAX_READ_LENGTH = 200
@@ -182,6 +187,222 @@ def main():
182187

183188

184189

190+
'''
191+
Created on 22Jan.,2018
192+
193+
@author: dlawrence
194+
'''
195+
196+
197+
198+
199+
def axis_stacked_bar_graph(ax, largs, arrays, labels, colors):
200+
bottom = np.zeros(len(largs), dtype='i')
201+
for array, label, color in zip(arrays, labels, colors):
202+
lines = ax.bar(largs, array, label=label, color=color, bottom=bottom, linewidth=0)
203+
bottom += array
204+
205+
return lines
206+
207+
208+
def write_stacked_bar_graph(graph_image, largs, arrays, labels, colors, **kwargs):
209+
'''largs = x-values
210+
arrays = list of lists y-values
211+
labels = list of labels, same length as arrays
212+
colors = list of colors, same length as arrays
213+
214+
kwargs:
215+
extra_func = method called with args=(ax, fig, lines)
216+
legend_side_ratio : eg 0.1 - Shrink figure by this
217+
legend_kwargs : Passed to ax.legend
218+
'''
219+
logging.info("write_stacked_bar_graph: %s", graph_image)
220+
221+
title = kwargs.get("title")
222+
extra_func = kwargs.get("extra_func")
223+
subtitle = kwargs.get("subtitle")
224+
x_label = kwargs.get("x_label")
225+
y_label = kwargs.get("y_label")
226+
legend_side_ratio = kwargs.get("legend_side_ratio")
227+
228+
# Old kwargs, which we passed to legend
229+
legend_kwargs = {"loc" : kwargs.get("loc"),
230+
"title" : kwargs.get("legend_title"),
231+
"prop" : kwargs.get("legend_props", {})}
232+
# Overwrite with legend_kwargs
233+
legend_kwargs.update(kwargs.get("legend_kwargs", {}))
234+
235+
fig = Figure(dpi=300)
236+
fig.patch.set_facecolor('white')
237+
ax = fig.add_subplot(111)
238+
lines = axis_stacked_bar_graph(ax, largs, arrays, labels, colors)
239+
240+
if title:
241+
fig.suptitle(title, fontsize=18)
242+
if subtitle:
243+
ax.set_title(subtitle, fontsize=12)
244+
if extra_func:
245+
extra_func(ax, fig, lines)
246+
if x_label:
247+
ax.set_xlabel(x_label)
248+
if y_label:
249+
ax.set_ylabel(y_label)
250+
251+
ax.set_xlim(xmin=largs[0], xmax=largs[-1]+1)
252+
253+
if legend_side_ratio is not None:
254+
print("legend_side_ratio: %f" % legend_side_ratio)
255+
assert 0 < legend_side_ratio < 1, "legend_side_ratio: 0 < %f < 1" % legend_side_ratio
256+
257+
# Shrink current axis's height by legend_below_ratio on the bottom
258+
#ax = pyplot.axes()
259+
box = ax.get_position()
260+
print("Box w/h = (%f,%f)" % (box.width, box.height))
261+
262+
new_width = box.height * (1.0 - legend_side_ratio)
263+
new_position = [box.x0, box.y0,
264+
new_width, box.height]
265+
266+
ax.set_position(new_position)
267+
268+
box = ax.get_position()
269+
print("NEW Box w/h = (%f,%f)" % (box.width, box.height))
270+
271+
272+
print("**legend_kwargs = %s" % legend_kwargs)
273+
ax.legend(**legend_kwargs)
274+
275+
canvas = FigureCanvasAgg(fig)
276+
canvas.print_png(graph_image)
277+
278+
def write_individual_bar_graphs(graph_image, largs, arrays, labels, colors, **kwargs):
279+
''' same as write_stacked_bar_graph but writes out 1 plot per entry in array '''
280+
281+
(name_base, extension) = os.path.splitext(graph_image)
282+
283+
title = kwargs.get("title", "")
284+
y_label = kwargs.get("y_label", None)
285+
for array, label, color in zip(arrays, labels, colors):
286+
kwargs["title"] = "%s (%s)" % (title, label)
287+
kwargs["color"] = color
288+
289+
bargraph = BarGraph(largs, array)
290+
bargraph.y_label = y_label
291+
individual_graph_image = "%s.%s%s" % (name_base, label, extension) # extension still has dot
292+
bargraph.save(individual_graph_image)
293+
294+
295+
class GraphBase(object):
296+
__metaclass__ = abc.ABCMeta
297+
298+
def __init__(self, **kwargs):
299+
'''
300+
legend: [('label', 'color'), ('label2', 'color2')]
301+
'''
302+
self.title = kwargs.get("title")
303+
self.x_label = kwargs.get("x_label")
304+
self.y_label = kwargs.get("y_label")
305+
self.legend = kwargs.get('legend')
306+
self.plot_methods = [self.plot]
307+
308+
def decorations(self, ax):
309+
if self.title:
310+
ax.set_title(self.title)
311+
if self.x_label:
312+
ax.set_xlabel(self.x_label)
313+
if self.y_label:
314+
ax.set_ylabel(self.y_label)
315+
316+
@abc.abstractmethod
317+
def plot(self, ax):
318+
return
319+
320+
def post_plot(self, ax):
321+
if self.legend:
322+
patches = []
323+
labels = []
324+
for (name, color) in self.legend:
325+
labels.append(name)
326+
patches.append(Rectangle((0, 0), 1, 1, fc=color))
327+
328+
ax.legend(patches, labels, loc='upper left')
329+
330+
def figure(self, figure):
331+
''' a hook method if you want to do something about the figure '''
332+
pass
333+
334+
def get_figure_and_axis(self, dpi):
335+
figure = Figure(dpi=dpi)
336+
figure.patch.set_facecolor('white')
337+
ax = figure.add_subplot(1, 1, 1)
338+
return figure, ax
339+
340+
def save(self, filename_or_obj, dpi=None, file_type='png'):
341+
figure, ax = self.get_figure_and_axis(dpi)
342+
343+
self.decorations(ax)
344+
for plot in self.plot_methods:
345+
plot(ax) # Implementation
346+
self.post_plot(ax)
347+
self.figure(figure)
348+
349+
canvas = FigureCanvasAgg(figure)
350+
if file_type == 'png':
351+
canvas.print_png(filename_or_obj)
352+
elif file_type == 'pdf':
353+
canvas.print_pdf(filename_or_obj)
354+
355+
def draw_origin(self, ax):
356+
ax.axvline(c='black', lw=0.5)
357+
ax.axhline(c='black', lw=0.5)
358+
359+
def colorbar_from_cmap_array(self, figure, cmap, array):
360+
mappable = ScalarMappable(cmap=cmap)
361+
mappable.set_array(array)
362+
figure.colorbar(mappable)
363+
364+
365+
def write_csv_dict(csv_file, headers, rows, extrasaction=None, dialect=None):
366+
'''
367+
default dialect = 'excel', other dialect option: 'excel-tab'
368+
These are the same optional arguments as csv.DictWriter
369+
headers=keys for dicts
370+
rows=list of dicts
371+
'''
372+
373+
374+
if extrasaction is None:
375+
extrasaction = "raise"
376+
if dialect is None:
377+
dialect = 'excel'
378+
379+
f = file_or_file_name(csv_file, "wb")
380+
381+
writer = csv.DictWriter(f, headers, extrasaction=extrasaction, dialect=dialect)
382+
writer.writerow(dict(zip(headers, headers)))
383+
writer.writerows(rows)
384+
385+
386+
387+
class BarGraph(GraphBase):
388+
def __init__(self, x, y, **kwargs):
389+
super(BarGraph, self).__init__(**kwargs)
390+
self.x = x
391+
self.y = y
392+
self.labels = kwargs.get("labels")
393+
self.color = kwargs.get("color")
394+
395+
def plot(self, ax):
396+
width = 0.5
397+
398+
ax.set_xlim(xmin=self.x[0], xmax=self.x[-1]+1)
399+
ax.bar(self.x, self.y, width=width, color=self.color)
400+
401+
if self.labels:
402+
ax.set_xticks(self.x + width/2)
403+
ax.set_xticklabels(self.labels)
404+
405+
185406

186407
if __name__ == '__main__':
187408
main()
Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
1-
#!/usr/bin/env python3
1+
#!/usr/bin/env python
22

33
from __future__ import print_function, absolute_import
44

55
import HTSeq
66
from collections import defaultdict
77
import gzip
88
import json
9-
import sys
10-
9+
import os
1110
from pyreference.settings import CHROM, START, END, STRAND, IS_CODING, CODING_FEATURES, \
1211
PYREFERENCE_JSON_VERSION_KEY, PYREFERENCE_JSON_VERSION
1312
from pyreference.utils.file_utils import name_from_file_name
13+
import sys
1414

1515

1616
class SetEncoder(json.JSONEncoder):
@@ -75,7 +75,8 @@ def add_UTR_features(transcripts_by_id, transcript_cds_by_id):
7575

7676
def main():
7777
if len(sys.argv) != 2:
78-
print(sys.stderr, "Usage: %s reference.gtf" % sys.argv[0])
78+
script_name = os.path.basename(__file__)
79+
print("Usage: %s reference.gtf" % script_name, file=sys.stderr)
7980
sys.exit(1)
8081

8182
gtf_file = sys.argv[1]

bin/test_reference.py

Lines changed: 0 additions & 55 deletions
This file was deleted.

pyreference/__init__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
from __future__ import absolute_import
22

3-
from .transcript import *
43
from .gene import *
4+
from .mirna import *
55
from .reference import *
6+
from .referenceargparse import *
7+
from .transcript import *
68

79

pyreference/mirna.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
11
'''
2-
Created on 23Jan.,2018
32
4-
@author: dlawrence
5-
'''
3+
ACRF Cancer Genomics Facility
64
7-
'''
5+
Created on 23Jan.,2018
86
97
@see http://www.mirbase.org/
108
11-
Created on Sep 6, 2012
12-
139
@author: dlawrence
1410
'''
1511

0 commit comments

Comments
 (0)