├── .gitignore ├── .travis.yml ├── Dockerfile ├── LICENSE ├── README.md ├── plot_coverage.py ├── setup.py ├── yeast_test.bam.depth.png ├── yeast_test_small.bam ├── yeast_test_small.bam.bai └── yeast_test_small.bam.depth.png /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | 5 | # C extensions 6 | *.so 7 | 8 | # Distribution / packaging 9 | .Python 10 | env/ 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | *.egg-info/ 23 | .installed.cfg 24 | *.egg 25 | 26 | # PyInstaller 27 | # Usually these files are written by a python script from a template 28 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 29 | *.manifest 30 | *.spec 31 | 32 | # Installer logs 33 | pip-log.txt 34 | pip-delete-this-directory.txt 35 | 36 | # Unit test / coverage reports 37 | htmlcov/ 38 | .tox/ 39 | .coverage 40 | .coverage.* 41 | .cache 42 | nosetests.xml 43 | coverage.xml 44 | *,cover 45 | 46 | # Translations 47 | *.mo 48 | *.pot 49 | 50 | # Django stuff: 51 | *.log 52 | 53 | # Sphinx documentation 54 | docs/_build/ 55 | 56 | # PyBuilder 57 | target/ 58 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: python 2 | 3 | python: 4 | # - "2.6" 5 | - "2.7" 6 | # - "3.3" 7 | # - "3.4" 8 | 9 | notifications: 10 | on_success: change 11 | on_failure: change 12 | 13 | # Miniconda-based setup of the Scipy stack based on 14 | # https://gist.github.com/dan-blanchard/7045057. 15 | 16 | # Setup anaconda 17 | before_install: 18 | - wget http://repo.continuum.io/miniconda/Miniconda-latest-Linux-x86_64.sh -O miniconda.sh 19 | - chmod +x miniconda.sh 20 | - ./miniconda.sh -b 21 | - export PATH=/home/travis/miniconda/bin:/home/travis/miniconda3/bin:$PATH 22 | - conda update --yes conda 23 | - conda create --yes -n condaenv python=$TRAVIS_PYTHON_VERSION 24 | - conda install --yes -n condaenv pip 25 | - source activate condaenv 26 | 27 | # Install packages 28 | install: 29 | - conda install --yes python=$TRAVIS_PYTHON_VERSION numpy pysam matplotlib seaborn pandas 30 | - python setup.py install 31 | 32 | script: python plot_coverage.py yeast_test_small.bam 33 | 34 | before_script: 35 | - pip install coveralls 36 | # - coverage run --source=census setup.py test 37 | 38 | sudo: false 39 | 40 | after_success: 41 | - coveralls 42 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ipython/scipystack 2 | 3 | MAINTAINER Matt Edwards 4 | 5 | RUN apt-get install -y nano 6 | 7 | RUN mkdir /root/genome_coverage_plotter 8 | WORKDIR /root/genome_coverage_plotter 9 | RUN git clone https://github.com/matted/genome_coverage_plotter.git . 10 | 11 | RUN curl -o miniconda.sh http://repo.continuum.io/miniconda/Miniconda-latest-Linux-x86_64.sh 12 | RUN chmod a+x miniconda.sh 13 | RUN ./miniconda.sh -b 14 | RUN /root/miniconda/bin/conda update --yes conda 15 | RUN /root/miniconda/bin/conda create --yes -n conda python=2.7 16 | RUN /root/miniconda/bin/conda install --yes python=2.7 numpy pysam matplotlib seaborn pandas 17 | 18 | ENV PATH /root/miniconda/bin/:$PATH 19 | 20 | RUN python setup.py install --quiet 21 | 22 | CMD echo "Please run plot_coverage.py." 23 | 24 | # Examples: 25 | # 26 | # Build the image: 27 | # docker build -t=matted/genome_coverage_plotter . 28 | # 29 | # Investigate the image: 30 | # docker run -t --rm=true -i matted/genome_coverage_plotter /bin/bash 31 | # 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Matt Edwards 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | genome_coverage_plotter 0.1 2 | ============== 3 | 4 | [![Build Status](https://travis-ci.org/matted/genome_coverage_plotter.svg?branch=master)](https://travis-ci.org/matted/genome_coverage_plotter) [![Coverage Status](https://coveralls.io/repos/matted/genome_coverage_plotter/badge.svg)](https://coveralls.io/r/matted/genome_coverage_plotter) 5 | 6 | Installation: 7 | == 8 | 9 | You can get genome_coverage_plotter by pulling it from git: 10 | 11 | git clone https://github.com/matted/genome_coverage_plotter.git 12 | 13 | To run genome_coverage_plotter, several Python packages are required. On a Ubuntu-like 14 | system, these commands will get the appropriate dependencies: 15 | 16 | sudo apt-get install python python-dev build-essential python-setuptools python-numpy python-scipy python-pylab python-pandas 17 | sudo easy_install pysam seaborn 18 | 19 | If you want the genome_coverage_plotter tools on your system path (and want to get the 20 | dependencies automatically), install it with: 21 | 22 | sudo python setup.py install 23 | 24 | There is also a Docker image that has genome_coverage_plotter and its dependencies 25 | preinstalled [here](https://registry.hub.docker.com/u/matted/genome-coverage-plotter/). 26 | 27 | Usage: 28 | == 29 | 30 | Run the script on a sorted, indexed bam file: 31 | 32 | python plot_coverage.py yeast_test_small.bam 33 | 34 | The output is: 35 | 36 | chromosome normalized_coverage 37 | chr10 1.0000 38 | chr11 1.0264 39 | chr12 1.0556 40 | chr13 1.0000 41 | chr14 1.0000 42 | chr15 0.9444 43 | chr16 1.0000 44 | chr1 0.8889 45 | chr2 1.0000 46 | chr3 1.0556 47 | chr4 1.0083 48 | chr5 1.0000 49 | chr6 1.0472 50 | chr7 1.0000 51 | chr8 1.0889 52 | chr9 0.8889 53 | 54 | And it creates an output plot image based on the input filename, like: 55 | 56 | ![example](https://raw.githubusercontent.com/matted/genome_coverage_plotter/master/yeast_test.bam.depth.png) 57 | 58 | The chromosomes are ordered based on their order in the input file. 59 | 60 | All the parameters and plot options are currently hardcoded. 61 | -------------------------------------------------------------------------------- /plot_coverage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # Required configuration for some grid computing environments: 4 | # import os 5 | # os.environ["MPLCONFIGDIR"] = "/scratch/tmp/" 6 | 7 | import matplotlib 8 | try: 9 | matplotlib.use("Agg") 10 | except ValueError: 11 | pass 12 | 13 | import numpy, sys, pylab, os.path, pysam, pandas, seaborn 14 | 15 | RES = 10000 16 | SKIP = 1000 17 | 18 | def parse(sam): 19 | for chromo, length in zip(sam.references, sam.lengths): 20 | depths = numpy.zeros(length + 1) 21 | for base in sam.pileup(chromo, stepper="all"): 22 | try: # ugly hack because the API changed (?) 23 | depths[base.reference_pos] += base.nsegments 24 | except AttributeError: 25 | depths[base.pos] += len(base.pileups) 26 | df = pandas.DataFrame(depths, index=numpy.arange(length + 1), columns=["depth"]) 27 | yield chromo, length, pandas.rolling_mean(df, window=RES) 28 | 29 | if __name__ == "__main__": 30 | if len(sys.argv) <= 1: 31 | print >>sys.stderr, "usage: python %s input.bam" % sys.argv[0] 32 | sys.exit(1) 33 | 34 | seaborn.set_style("white") 35 | sam = pysam.Samfile(sys.argv[1]) 36 | 37 | offset = 0 38 | y_text = None 39 | medians = {} 40 | all_depths = [] 41 | 42 | with seaborn.color_palette("husl", sam.nreferences): 43 | for chromo, length, counts in parse(sam): 44 | if "Un" in chromo or "random" in chromo or "hap" in chromo or "M" in chromo or "mt" in chromo: 45 | continue # skip weird chromosomes 46 | pylab.plot(counts.index.values[::SKIP] + offset, counts[counts.columns[0]].values[::SKIP], '.') 47 | if y_text is None: 48 | y_text = numpy.median(counts[counts.columns[0]]) 49 | pylab.text(offset + length*0.5, y_text, chromo, horizontalalignment="center", verticalalignment="center") 50 | offset += length 51 | 52 | medians[chromo] = numpy.median(counts[counts.columns[0]]) 53 | all_depths.extend(counts[counts.columns[0]][::SKIP]) 54 | 55 | # print normalized median coverages for aneuploidy analysis 56 | print "chromosome\tnormalized_coverage" 57 | for chromo in sam.references: 58 | if medians.has_key(chromo): 59 | print "%s\t%.4f" % (chromo, medians[chromo] / numpy.median(all_depths)) 60 | 61 | # draw some reference lines for identifying common aneuploidies 62 | for mult, color, label in [(1.5, '--', "2N (+/-1)"), 63 | (0.5, '--', None), 64 | (2.0, '-.', "1N (+/-1)"), 65 | (0.05, '-.', None), 66 | (1.3333, ':', "3N (+/-1)"), 67 | (0.6666, ':', None)]: 68 | pylab.axhline(numpy.median(all_depths) * mult, ls=color, color="k", lw=1, alpha=0.5, label=label) 69 | 70 | pylab.legend() 71 | pylab.xlabel("bp") 72 | pylab.ylabel("coverage (%d-bp averaged)" % RES) 73 | 74 | pylab.gca().set_xlim([0, offset+RES+1]) 75 | pylab.title(sys.argv[-1]) 76 | 77 | # pylab.show() 78 | pylab.gcf().set_size_inches(16,4) 79 | pylab.savefig("%s.depth.png" % os.path.basename(sam.filename)) 80 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from setuptools import setup 3 | 4 | setup(name="genome_coverage_plotter", 5 | version="0.1", 6 | description="Simple whole-genome coverage visualization.", 7 | author="Matt Edwards", 8 | author_email="matted@mit.edu", 9 | license="MIT", 10 | url="https://github.com/matted/genome_coverage_plotter", 11 | packages=[], 12 | scripts=["plot_coverage.py"], 13 | zip_safe=True, 14 | install_requires=["numpy", "pysam", "pandas", "seaborn", "matplotlib"], 15 | ) 16 | -------------------------------------------------------------------------------- /yeast_test.bam.depth.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matted-zz/genome_coverage_plotter/5cbfcdd6239c1c94e8ada0b1a050b0475939bd30/yeast_test.bam.depth.png -------------------------------------------------------------------------------- /yeast_test_small.bam: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matted-zz/genome_coverage_plotter/5cbfcdd6239c1c94e8ada0b1a050b0475939bd30/yeast_test_small.bam -------------------------------------------------------------------------------- /yeast_test_small.bam.bai: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matted-zz/genome_coverage_plotter/5cbfcdd6239c1c94e8ada0b1a050b0475939bd30/yeast_test_small.bam.bai -------------------------------------------------------------------------------- /yeast_test_small.bam.depth.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/matted-zz/genome_coverage_plotter/5cbfcdd6239c1c94e8ada0b1a050b0475939bd30/yeast_test_small.bam.depth.png --------------------------------------------------------------------------------