methplotlib 0.20.0__tar.gz → 0.21.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. methplotlib-0.21.2/LICENSE +21 -0
  2. methplotlib-0.21.2/PKG-INFO +93 -0
  3. {methplotlib-0.20.0 → methplotlib-0.21.2}/README.md +8 -3
  4. {methplotlib-0.20.0 → methplotlib-0.21.2}/README.rst +9 -11
  5. {methplotlib-0.20.0 → methplotlib-0.21.2}/methplotlib/annotation.py +53 -40
  6. methplotlib-0.21.2/methplotlib/import_methylation.py +482 -0
  7. {methplotlib-0.20.0 → methplotlib-0.21.2}/methplotlib/methplotlib.py +88 -56
  8. methplotlib-0.21.2/methplotlib/plots.py +456 -0
  9. {methplotlib-0.20.0 → methplotlib-0.21.2}/methplotlib/utils.py +140 -98
  10. methplotlib-0.21.2/methplotlib/version.py +1 -0
  11. methplotlib-0.21.2/methplotlib.egg-info/PKG-INFO +93 -0
  12. {methplotlib-0.20.0 → methplotlib-0.21.2}/methplotlib.egg-info/SOURCES.txt +1 -0
  13. {methplotlib-0.20.0 → methplotlib-0.21.2}/methplotlib.egg-info/entry_points.txt +0 -1
  14. {methplotlib-0.20.0 → methplotlib-0.21.2}/methplotlib.egg-info/requires.txt +1 -1
  15. methplotlib-0.21.2/scripts/calculate_methylation_frequency.py +144 -0
  16. methplotlib-0.21.2/setup.py +57 -0
  17. methplotlib-0.20.0/PKG-INFO +0 -88
  18. methplotlib-0.20.0/methplotlib/import_methylation.py +0 -305
  19. methplotlib-0.20.0/methplotlib/plots.py +0 -384
  20. methplotlib-0.20.0/methplotlib/version.py +0 -1
  21. methplotlib-0.20.0/methplotlib.egg-info/PKG-INFO +0 -88
  22. methplotlib-0.20.0/scripts/calculate_methylation_frequency.py +0 -94
  23. methplotlib-0.20.0/setup.py +0 -51
  24. {methplotlib-0.20.0 → methplotlib-0.21.2}/MANIFEST.in +0 -0
  25. {methplotlib-0.20.0 → methplotlib-0.21.2}/methplotlib/__init__.py +0 -0
  26. {methplotlib-0.20.0 → methplotlib-0.21.2}/methplotlib/differential/__init__.py +0 -0
  27. {methplotlib-0.20.0 → methplotlib-0.21.2}/methplotlib/differential/differential.py +0 -0
  28. {methplotlib-0.20.0 → methplotlib-0.21.2}/methplotlib/helpers.py +0 -0
  29. {methplotlib-0.20.0 → methplotlib-0.21.2}/methplotlib/qc.py +0 -0
  30. {methplotlib-0.20.0 → methplotlib-0.21.2}/methplotlib.egg-info/dependency_links.txt +0 -0
  31. {methplotlib-0.20.0 → methplotlib-0.21.2}/methplotlib.egg-info/top_level.txt +0 -0
  32. {methplotlib-0.20.0 → methplotlib-0.21.2}/scripts/__init__.py +0 -0
  33. {methplotlib-0.20.0 → methplotlib-0.21.2}/scripts/allele_specific_modification +0 -0
  34. {methplotlib-0.20.0 → methplotlib-0.21.2}/scripts/annotate_calls_by_phase.py +0 -0
  35. {methplotlib-0.20.0 → methplotlib-0.21.2}/scripts/differential_modification +0 -0
  36. {methplotlib-0.20.0 → methplotlib-0.21.2}/scripts/genome-wide-QC.py +0 -0
  37. {methplotlib-0.20.0 → methplotlib-0.21.2}/scripts/sorting_and_multiple_testing_correction.py +0 -0
  38. {methplotlib-0.20.0 → methplotlib-0.21.2}/scripts/split_calls_by_longshot_phase.py +0 -0
  39. {methplotlib-0.20.0 → methplotlib-0.21.2}/scripts/split_calls_by_phase.py +0 -0
  40. {methplotlib-0.20.0 → methplotlib-0.21.2}/setup.cfg +0 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2018 Wouter De Coster
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.
@@ -0,0 +1,93 @@
1
+ Metadata-Version: 2.1
2
+ Name: methplotlib
3
+ Version: 0.21.2
4
+ Summary: Plot methylation data obtained from nanopolish
5
+ Home-page: https://github.com/wdecoster/methplotlib
6
+ Author: Wouter De Coster
7
+ Author-email: decosterwouter@gmail.com
8
+ License: MIT
9
+ Keywords: nanopore
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Intended Audience :: Science/Research
12
+ Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.3
16
+ Classifier: Programming Language :: Python :: 3.4
17
+ Classifier: Programming Language :: Python :: 3.5
18
+ Requires-Python: >=3
19
+ Description-Content-Type: text/markdown
20
+ License-File: LICENSE
21
+
22
+ [![Anaconda-Server Badge](https://anaconda.org/bioconda/methplotlib/badges/version.svg)](https://anaconda.org/bioconda/methplotlib)
23
+ [![Anaconda-Server Badge](https://anaconda.org/bioconda/methplotlib/badges/license.svg)](https://anaconda.org/bioconda/methplotlib)
24
+
25
+ # METHPLOTLIB
26
+
27
+ This script generates a browser view on a window using data from
28
+ i) [nanopolish](https://github.com/jts/nanopolish), either as methylation calls or methylation frequencies (as processed by calculate_methylation_frequency.py). The methylation calls can additionally be phased using scripts/annotate_calls_by_phase.and scripts/split_calls_by_phase.py
29
+ ii) [nanocompore](https://github.com/tleonardi/nanocompore)
30
+ iii) in ont-cram format with MM/ML tags according to the SAM specifications
31
+ iv) in bedgraph format
32
+
33
+ ## INSTALLATION
34
+
35
+ Creating a new conda environment:
36
+ `conda create -n methplotlib methplotlib`
37
+
38
+ Or using pip:
39
+ `pip install methplotlib`
40
+
41
+
42
+
43
+ ## USAGE
44
+ ```
45
+ methplotlib [-h] [-v] -m METHYLATION [METHYLATION ...] -n NAMES
46
+ [NAMES ...] -w WINDOW [-g GTF] [-b BED] [-f FASTA]
47
+ [--simplify] [--split] [--static STATIC] [--smooth SMOOTH]
48
+ [--dotsize DOTSIZE] [--example] [-o OUTFILE] [-q QCFILE]
49
+
50
+ plotting nanopolish methylation calls or frequency
51
+
52
+ optional arguments:
53
+ -h, --help show this help message and exit
54
+ -v, --version Print version and exit.
55
+ -m, --methylation METHYLATION [METHYLATION ...]
56
+ data in nanopolish, nanocompore, ont-cram or bedgraph
57
+ format
58
+ -n, --names NAMES [NAMES ...]
59
+ names of datasets in --methylation
60
+ -w, --window WINDOW window (region) to which the visualisation has to be restricted
61
+ -g, --gtf GTF add annotation based on a gtf file
62
+ -b, --bed BED add annotation based on a bed file
63
+ -f, --fasta FASTA required when --window is an entire chromosome, contig or transcript
64
+ --simplify simplify annotation track to show genes rather than transcripts
65
+ --split split, rather than overlay the methylation tracks
66
+ --static Make a static image of the browser window (filename)
67
+ --binary Make the nanopolish plot ignorning log likelihood nuances
68
+ --smooth Rolling window size for averaging frequency values (int)
69
+ --dotsize Control the size of dots in the per read plots (int)
70
+ --example Show example command and exit.
71
+ -o, --outfile OUTFILE File to write results to. Default:
72
+ methylation_browser_{chr}_{start}_{end}.html. Use
73
+ {region} as a shorthand for {chr}_{start}_{end} in the
74
+ filename. Missing paths will be created.
75
+ -q, --qcfile QCFILE File to write the qc report to. Default: The path in
76
+ outfile prefixed with qc_, default is qc_report_methyl
77
+ ation_browser_{chr}_{start}_{end}.html. Use {region}
78
+ as a shorthand for {chr}_{start}_{end} in the
79
+ filename. Missing paths will be created.
80
+
81
+ ```
82
+
83
+ ## Snakemake workflow
84
+ For streamlining nanopolish a Snakefile is included (using snakemake). The workflow uses a config file, of which an example is in this repository.
85
+
86
+ ## Example data
87
+ The `examples` folder contains calls and frequencies for the human ACTB gene from PromethION sequencing of NA19240. An example command is available.
88
+
89
+ ## Companion scripts
90
+ The `scripts` folder contains scripts for phasing modification calls in haplotypes based on [WhatsHap](https://whatshap.readthedocs.io/en/latest/) phasing, allele specific modification testing for phased data and differential modification testing across subjects.
91
+
92
+ ## TO DO - CONTRIBUTIONS WELCOME
93
+ - Outlier detection (in windows) across samples
@@ -1,5 +1,3 @@
1
- [![Build Status](https://travis-ci.com/wdecoster/methplotlib.svg?branch=master)](https://travis-ci.com/wdecoster/methplotlib)
2
- [![Anaconda-Server Badge](https://anaconda.org/bioconda/methplotlib/badges/installer/conda.svg)](https://conda.anaconda.org/bioconda)
3
1
  [![Anaconda-Server Badge](https://anaconda.org/bioconda/methplotlib/badges/version.svg)](https://anaconda.org/bioconda/methplotlib)
4
2
  [![Anaconda-Server Badge](https://anaconda.org/bioconda/methplotlib/badges/license.svg)](https://anaconda.org/bioconda/methplotlib)
5
3
 
@@ -8,12 +6,19 @@
8
6
  This script generates a browser view on a window using data from
9
7
  i) [nanopolish](https://github.com/jts/nanopolish), either as methylation calls or methylation frequencies (as processed by calculate_methylation_frequency.py). The methylation calls can additionally be phased using scripts/annotate_calls_by_phase.and scripts/split_calls_by_phase.py
10
8
  ii) [nanocompore](https://github.com/tleonardi/nanocompore)
11
- iii) in ont-cram format with MM/MP tags according to the SAM specifications and converted using e.g. [this script](https://github.com/kpalin/gcf52ref/blob/f5_to_usam/scripts/extract_methylation_fast5_to_sam.py)
9
+ iii) in ont-cram format with MM/ML tags according to the SAM specifications
12
10
  iv) in bedgraph format
13
11
 
14
12
  ## INSTALLATION
13
+
14
+ Creating a new conda environment:
15
+ `conda create -n methplotlib methplotlib`
16
+
17
+ Or using pip:
15
18
  `pip install methplotlib`
16
19
 
20
+
21
+
17
22
  ## USAGE
18
23
  ```
19
24
  methplotlib [-h] [-v] -m METHYLATION [METHYLATION ...] -n NAMES
@@ -1,5 +1,4 @@
1
- |Build Status| |Anaconda-Server Badge| |Anaconda-Server Badge|
2
- |Anaconda-Server Badge|
1
+ |Anaconda-Server Badge| |image1|
3
2
 
4
3
  METHPLOTLIB
5
4
  ===========
@@ -11,15 +10,18 @@ METHPLOTLIB
11
10
  additionally be phased using scripts/annotate_calls_by_phase.and
12
11
  scripts/split_calls_by_phase.py
13
12
  | ii) `nanocompore <https://github.com/tleonardi/nanocompore>`__
14
- | iii) in ont-cram format with MM/MP tags according to the SAM
15
- specifications and converted using e.g. `this
16
- script <https://github.com/kpalin/gcf52ref/blob/f5_to_usam/scripts/extract_methylation_fast5_to_sam.py>`__
13
+ | iii) in ont-cram format with MM/ML tags according to the SAM
14
+ specifications
17
15
  | iv) in bedgraph format
18
16
 
19
17
  INSTALLATION
20
18
  ------------
21
19
 
22
- ``pip install methplotlib``
20
+ | Creating a new conda environment:
21
+ | ``conda create -n methplotlib methplotlib``
22
+
23
+ | Or using pip:
24
+ | ``pip install methplotlib``
23
25
 
24
26
  USAGE
25
27
  -----
@@ -90,11 +92,7 @@ TO DO - CONTRIBUTIONS WELCOME
90
92
 
91
93
  - Outlier detection (in windows) across samples
92
94
 
93
- .. |Build Status| image:: https://travis-ci.com/wdecoster/methplotlib.svg?branch=master
94
- :target: https://travis-ci.com/wdecoster/methplotlib
95
- .. |Anaconda-Server Badge| image:: https://anaconda.org/bioconda/methplotlib/badges/installer/conda.svg
96
- :target: https://conda.anaconda.org/bioconda
97
95
  .. |Anaconda-Server Badge| image:: https://anaconda.org/bioconda/methplotlib/badges/version.svg
98
96
  :target: https://anaconda.org/bioconda/methplotlib
99
- .. |Anaconda-Server Badge| image:: https://anaconda.org/bioconda/methplotlib/badges/license.svg
97
+ .. |image1| image:: https://anaconda.org/bioconda/methplotlib/badges/license.svg
100
98
  :target: https://anaconda.org/bioconda/methplotlib
@@ -24,16 +24,15 @@ def open_gtf(gtff):
24
24
  Open the gtf, using gzip if it's compressed
25
25
  based on extension
26
26
  """
27
- return gzip.open(gtff, 'rt') if gtff.endswith('.gz') else open(gtff)
27
+ return gzip.open(gtff, "rt") if gtff.endswith(".gz") else open(gtff)
28
28
 
29
29
 
30
30
  def good_record(line, chromosome):
31
- '''
31
+ """
32
32
  Filtering on the gtf lines
33
33
  by checking for right chromosome and right feature type
34
- '''
35
- if line.startswith(chromosome) \
36
- and line.split('\t')[2] in ['exon', 'gene']:
34
+ """
35
+ if line.startswith(str(chromosome)) and line.split("\t")[2] in ["exon", "gene"]:
37
36
  return True
38
37
  else:
39
38
  return False
@@ -43,7 +42,7 @@ def get_features(gtfline, type="gtf"):
43
42
  """
44
43
  Extract the desirable features from a gtf record
45
44
  """
46
- chromosome, _, _, begin, end, _, strand, _, attributes = gtfline.split('\t')
45
+ chromosome, _, _, begin, end, _, strand, _, attributes = gtfline.split("\t")
47
46
  gene, transcript = parse_attributes(attributes.rstrip(), type=type)
48
47
  return [chromosome, int(begin), int(end), strand, gene, transcript]
49
48
 
@@ -53,25 +52,28 @@ def parse_attributes(attributes, type="gtf"):
53
52
  Parse the attributes string of gtf record
54
53
  Return the values corresponding to gene_name and transcript_id
55
54
  """
56
- attribute_delimiter = {'gtf': '; ', 'gff': ';'}
57
- kv_delimiter = {'gtf': ' ', 'gff': '='}
58
- info = {i.split(kv_delimiter[type])[0]: i.split(kv_delimiter[type])[1].replace('"', '')
59
- for i in attributes.split(attribute_delimiter[type])
60
- if i.startswith(('gene_name', 'transcript_id', 'locus_tag'))}
55
+ attribute_delimiter = {"gtf": "; ", "gff": ";"}
56
+ kv_delimiter = {"gtf": " ", "gff": "="}
57
+ info = {
58
+ i.split(kv_delimiter[type])[0]: i.split(kv_delimiter[type])[1].replace('"', "")
59
+ for i in attributes.split(attribute_delimiter[type])
60
+ if i.startswith(("gene_name", "transcript_id", "locus_tag"))
61
+ }
61
62
  if "gene_name" in info.keys():
62
63
  return info.get("gene_name"), info.get("transcript_id")
63
64
  else:
64
65
  return info.get("locus_tag"), info.get("locus_tag")
65
66
 
66
67
 
67
- def transcripts_in_window(df, window, feature='transcript'):
68
+ def transcripts_in_window(df, window, feature="transcript"):
68
69
  """
69
70
  Return the transcript names for which
70
71
  either the end or the begin of an exon is within the window
71
72
  """
72
- return df.loc[df['begin'].between(window.begin, window.end)
73
- | df['end'].between(window.begin, window.end), feature] \
74
- .unique()
73
+ return df.loc[
74
+ df["begin"].between(window.begin, window.end) | df["end"].between(window.begin, window.end),
75
+ feature,
76
+ ].unique()
75
77
 
76
78
 
77
79
  def assign_colors_to_genes(transcripts):
@@ -88,23 +90,30 @@ def parse_annotation(gtff, window, simplify=False):
88
90
  """
89
91
  type = annot_file_sniffer(gtff)
90
92
  logging.info(f"Parsing {type} file...")
91
- df = pd.DataFrame(data=[get_features(line, type=type)
92
- for line in open_gtf(gtff) if good_record(line, window.chromosome)],
93
- columns=['chromosome', 'begin', 'end', 'strand', 'gene', 'transcript'])
93
+ df = pd.DataFrame(
94
+ data=[
95
+ get_features(line, type=type)
96
+ for line in open_gtf(gtff)
97
+ if good_record(line, window.chromosome)
98
+ ],
99
+ columns=["chromosome", "begin", "end", "strand", "gene", "transcript"],
100
+ )
94
101
  logging.info("Loaded GTF file, processing...")
95
102
  if simplify:
96
- df.drop_duplicates(subset=['chromosome', 'begin', 'end', 'gene'], inplace=True)
103
+ df.drop_duplicates(subset=["chromosome", "begin", "end", "gene"], inplace=True)
97
104
  res = []
98
- for g in transcripts_in_window(df, window, feature='gene'):
105
+ for g in transcripts_in_window(df, window, feature="gene"):
99
106
  gtable = df.loc[df["gene"] == g]
100
107
  if len(gtable):
101
108
  res.append(
102
- Transcript(transcript=gtable["gene"].tolist()[0],
103
- gene=gtable["gene"].tolist()[0],
104
- exon_tuples=gtable.loc[:, ["begin", "end"]].sort_values("begin")
105
- .itertuples(index=False,
106
- name=None),
107
- strand=gtable["strand"].tolist()[0])
109
+ Transcript(
110
+ transcript=gtable["gene"].tolist()[0],
111
+ gene=gtable["gene"].tolist()[0],
112
+ exon_tuples=gtable.loc[:, ["begin", "end"]]
113
+ .sort_values("begin")
114
+ .itertuples(index=False, name=None),
115
+ strand=gtable["strand"].tolist()[0],
116
+ )
108
117
  )
109
118
  sys.stderr.write(f"Found {len(res)} gene(s) in the region.\n")
110
119
  logging.info(f"Found {len(res)} gene(s) in the region.\n")
@@ -113,12 +122,14 @@ def parse_annotation(gtff, window, simplify=False):
113
122
  for t in transcripts_in_window(df, window, feature="transcript"):
114
123
  tr = df.loc[df["transcript"] == t]
115
124
  res.append(
116
- Transcript(transcript=t,
117
- gene=tr["gene"].tolist()[0],
118
- exon_tuples=tr.loc[:, ["begin", "end"]].sort_values("begin")
119
- .itertuples(index=False,
120
- name=None),
121
- strand=tr["strand"].tolist()[0])
125
+ Transcript(
126
+ transcript=t,
127
+ gene=tr["gene"].tolist()[0],
128
+ exon_tuples=tr.loc[:, ["begin", "end"]]
129
+ .sort_values("begin")
130
+ .itertuples(index=False, name=None),
131
+ strand=tr["strand"].tolist()[0],
132
+ )
122
133
  )
123
134
  sys.stderr.write(f"Found {len(res)} transcript(s) in the region.\n")
124
135
  logging.info(f"Found {len(res)} transcript(s) in the region.\n")
@@ -132,20 +143,22 @@ def annot_file_sniffer(annot_file):
132
143
 
133
144
  Right not just lazily focus on the extension
134
145
  """
135
- if annot_file.endswith(('.gtf', '.gtf.gz')):
136
- return 'gtf'
137
- elif annot_file.endswith(('.gff', '.gff.gz')):
138
- return 'gff'
146
+ if annot_file.endswith((".gtf", ".gtf.gz")):
147
+ return "gtf"
148
+ elif annot_file.endswith((".gff", ".gff.gz")):
149
+ return "gff"
139
150
  else:
140
- sys.exit("ERROR: unrecognized extension of the annotation file.\n"
141
- "Supported are gtf, gtf.gz, gff and gff.gz")
151
+ sys.exit(
152
+ "ERROR: unrecognized extension of the annotation file.\n"
153
+ "Supported are gtf, gtf.gz, gff and gff.gz"
154
+ )
142
155
 
143
156
 
144
157
  def parse_bed(bed, window):
145
158
  logging.info("Parsing BED file")
146
- gr = pr.read_bed(bed)[window.chromosome, window.begin:window.end]
159
+ gr = pr.read_bed(bed)[window.chromosome, window.begin : window.end]
147
160
  df = gr.unstrand().df
148
- df = df.drop(columns=["Chromosome", "Score", "Strand"], errors='ignore')
161
+ df = df.drop(columns=["Chromosome", "Score", "Strand"], errors="ignore")
149
162
  if "Name" not in df.columns:
150
163
  df["Name"] = "noname"
151
164
  return df.itertuples(index=False, name=None)