1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
|
#!/usr/bin/env python
"""
Given 3 files, creates a 3-way Venn diagram of intersections using the Google \
Chart API; see :mod:`pybedtools.contrib.venn_maker` for more flexibility.
The values in the diagram assume:
* unstranded intersections
* no features that are nested inside larger features
"""
import argparse
import sys
import pybedtools
import urllib
def venn_gchart(a, b, c=None, colors=None, labels=None, size="300x300"):
"""
a, b, and c are filenames to BED-like files.
*colors* is a list of 3 hex colors
*labels* is a list of 3 labels
*outfn* is the output PNG you want to create.
*size* is the size in pixels for the PNG
"""
a = pybedtools.BedTool(a)
b = pybedtools.BedTool(b)
if c:
c = pybedtools.BedTool(c)
# The order of values is meaningful to the API, see
# http://code.google.com/apis/chart/docs/gallery/venn_charts.html
if c:
vals = [
len(a),
len(b),
len(c),
len(a + b),
len(a + c),
len(b + c),
len(a + b + c),
]
else:
# insert 0 for size of 3rd circle.
vals = [len(a), len(b), 0, len(a + b)]
labels = labels[:2]
# API doesn't seem to like large numbers, so get fractions instead, then
# join make a comma-separated list of values.
mx = float(max(vals))
vals = [round(i / mx, 4) for i in vals]
valstr = ",".join(map(str, vals))
data = {"cht": "v", "chs": size, "chd": "t:" + valstr}
# Add the optional data, if specified
if labels:
data["chdl"] = "|".join(labels)
if colors:
data["chco"] = ",".join(colors)
return data
def gchart(data, outfn="out.png"):
"""
Sends data to Google Chart API
"""
data = urllib.parse.urlencode(data)
binary_data = data.encode("UTF-8")
url = "https://chart.googleapis.com/chart?"
# Request and get the PNG
req = urllib.request.Request(url, binary_data)
print(url + data)
response = urllib.request.urlopen(req)
f = open(outfn, "w")
f.write(response.read())
f.close()
def main():
"""Create a 3-way Venn diagram using Google Charts API
"""
op = argparse.ArgumentParser(description=__doc__, prog=sys.argv[0])
op.add_argument("-a", help="File to use for the left-most circle")
op.add_argument("-b", help="File to use for the right-most circle")
op.add_argument("-c", help="File to use for the bottom circle")
op.add_argument(
"--colors",
help="Optional comma-separated list of hex "
"colors for circles a, b, and c. E.g. %(default)s",
default="00FF00,FF0000,0000FF",
)
op.add_argument(
"--labels",
help="Optional comma-separated list of labels for a, b, and c",
default="a,b,c",
)
op.add_argument(
"--size",
default="300x300",
help="Optional size of PNG, in pixels. Default is " '"%(default)s"',
)
op.add_argument(
"-o", default="out.png", help="Output file to save as, in PNG format"
)
op.add_argument(
"--test", action="store_true", help="run test, overriding all other options."
)
options = op.parse_args()
reqd_args = ["a", "b"]
if not options.test:
for ra in reqd_args:
if not getattr(options, ra):
op.print_help()
sys.stderr.write('Missing required arg "%s"\n' % ra)
sys.exit(1)
if options.test:
# Example data
pybedtools.bedtool.random.seed(1)
a = pybedtools.example_bedtool("rmsk.hg18.chr21.small.bed")
b = pybedtools.example_bedtool("venn.b.bed")
c = pybedtools.example_bedtool("venn.c.bed")
options.a = a.fn
options.b = b.fn
options.c = c.fn
options.colors = "00FF00,FF0000,0000FF"
options.o = "out.png"
options.labels = "a,b,c"
data = venn_gchart(
a=options.a,
b=options.b,
c=options.c,
colors=options.colors.split(","),
labels=options.labels.split(","),
size=options.size,
)
gchart(data, outfn=options.o)
if __name__ == "__main__":
import doctest
if doctest.testmod(optionflags=doctest.ELLIPSIS).failed == 0:
main()
|