Skip to content

Commit 6efacba

Browse files
authored
Add option for genome information annotations (#50)
* Add option --annotate-genomes to annotate genome summary info - to the right of the genomes in the ribbon plot - Genome size + number of chromosomes * Update new parameter name to --annotate-genome-info * Fix for pylint * Refactor parameter section of ntsynt_viz.smk * Update README.md * Update README.md * Rename genome info annotation parameter in smk, R script - Also update .pylintrc * Update passing of name_conversion in ntsynt_viz.py * Remove name conversion from a test in CI * Update Example 2 ubuntu orders * Update CI * Update expected orders TSV
1 parent 03918cd commit 6efacba

7 files changed

Lines changed: 93 additions & 33 deletions

README.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,8 @@ export PATH=/path/to/ntsynt-viz/github/ntSynt-viz/bin:$PATH
6666
```
6767
usage: ntsynt_viz.py [-h] --blocks BLOCKS --fais FAIS [FAIS ...] [--name_conversion NAME_CONVERSION] [--tree TREE] [--target-genome TARGET_GENOME] [--normalize]
6868
[--indel INDEL] [--length LENGTH] [--seq_length SEQ_LENGTH] [--keep KEEP [KEEP ...]] [--centromeres CENTROMERES] [--haplotypes HAPLOTYPES]
69-
[--order ORDER] [--prefix PREFIX] [--format {png,pdf,svg}] [--scale SCALE] [--height HEIGHT] [--width WIDTH] [--dpi DPI] [--no-arrow]
70-
[--ribbon_adjust RIBBON_ADJUST] [-f] [-n] [-v]
69+
[--order ORDER] [--prefix PREFIX] [--format {png,pdf,svg}] [--scale SCALE] [--height HEIGHT] [--width WIDTH] [--dpi DPI] [--annotate-genome-info]
70+
[--no-arrow] [--ribbon_adjust RIBBON_ADJUST] [-f] [-n] [-v]
7171
7272
Visualizing multi-genome synteny
7373
@@ -114,8 +114,10 @@ output arguments:
114114
Output format of plot [png]
115115
--scale SCALE Length of scale bar in bases [100e6]
116116
--height HEIGHT Height of plot in cm [20]
117-
--width WIDTH Width of plot in cm [50]
117+
--width WIDTH Width of plot in cm [55]
118118
--dpi DPI Resolution of output plot - png output only [300]
119+
--annotate-genome-info
120+
Add annotations about number of sequences and genome size to the right of each genome in the ribbon plot
119121
--ribbon_adjust RIBBON_ADJUST
120122
Ratio for adjusting spacing beside ribbon plot. Increase if ribbon plot labels are cut off, and decrease to reduce the white space to
121123
the left of the ribbon plot [0.1]

azure-pipelines.yml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,15 +53,17 @@ jobs:
5353
source activate ntsynt_viz_ci
5454
export PATH=$(pwd)/bin:$PATH
5555
cd tests
56-
ntsynt_viz.py --blocks great-apes.ntSynt.synteny_blocks.tsv --fais fais.tsv --name_conversion great-apes.name-conversions.tsv --prefix great-apes_ribbon-plots_no-tree --ribbon_adjust 0.15 --scale 1e9 --target-genome Homo_sapiens --format pdf --force
57-
diff -q great-apes_ribbon-plots_no-tree_est-distances.order.tsv expected/great-apes_ribbon-plots_no-tree_est-distances.order.tsv
56+
ntsynt_viz.py --blocks great-apes.ntSynt.synteny_blocks.tsv --fais fais.tsv --prefix great-apes_ribbon-plots_no-tree --ribbon_adjust 0.15 --scale 1e9 --target-genome GCA_000001405.15_GRCh38_genomic.chr-only.nums.fa --format pdf --force
57+
cat great-apes_ribbon-plots_no-tree_est-distances.order.tsv
58+
diff -q great-apes_ribbon-plots_no-tree_est-distances.order.tsv expected/great-apes_ribbon-plots_no-tree_est-distances_no-names.order.tsv
5859
displayName: Run Example 2 test (PDF output)
5960
6061
- script: |
6162
source activate ntsynt_viz_ci
6263
export PATH=$(pwd)/bin:$PATH
6364
cd tests
64-
ntsynt_viz.py --blocks great-apes.ntSynt.synteny_blocks.tsv --fais fais.tsv --name_conversion great-apes.name-conversions.tsv --prefix great-apes_ribbon-plots_no-tree --ribbon_adjust 0.15 --scale 2e9 --target-genome Pan_paniscus --format svg --force
65+
ntsynt_viz.py --blocks great-apes.ntSynt.synteny_blocks.tsv --fais fais.tsv --name_conversion great-apes.name-conversions.tsv --prefix great-apes_ribbon-plots_no-tree \
66+
--ribbon_adjust 0.15 --scale 2e9 --target-genome Pan_paniscus --format svg --annotate-genome-info --force
6567
displayName: Run Example 3 test (SVG output)
6668
6769
- script: |

bin/.pylintrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ max-attributes = 10
66
max-line-length = 120
77
max-branches = 20
88
max-public-methods=50
9-
max-statements = 70
9+
max-statements = 90
1010
max-module-lines = 1500
1111
max-bool-expr = 7
1212
max-positional-arguments = 10

bin/ntsynt_viz.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,13 @@ def main():
9393
output_group.add_argument("--scale", help="Length of scale bar in bases [100e6]", required=False, type=float,
9494
default=100e6)
9595
output_group.add_argument("--height", help="Height of plot in cm [20]", required=False, type=int, default=20)
96-
output_group.add_argument("--width", help="Width of plot in cm [50]", required=False, type=int, default=50)
96+
output_group.add_argument("--width", help="Width of plot in cm [55]", required=False, type=int, default=55)
9797
output_group.add_argument("--dpi", help="Resolution of output plot - png output only [300]",
9898
required=False, type=int, default=300)
99+
output_group.add_argument("--annotate-genome-info",
100+
help="Add annotations about number of sequences "
101+
"and genome size to the right of each genome in the ribbon plot",
102+
action="store_true")
99103
main_formatting_group.add_argument("--no-arrow", help="Only used with --normalize; "
100104
"do not draw arrows indicating reverse-complementation",
101105
action="store_true")
@@ -128,7 +132,6 @@ def main():
128132
f"--config " \
129133
f"prefix={args.prefix} " \
130134
f"blocks={args.blocks} " \
131-
f"name_conversion={args.name_conversion} " \
132135
f"fai='{args.fais}' " \
133136
f"ribbon_ratio={args.ribbon_adjust} " \
134137
f"scale={args.scale} " \
@@ -139,6 +142,8 @@ def main():
139142
f"width={args.width} " \
140143
f"min_seq_length={args.seq_length} "
141144

145+
if args.name_conversion:
146+
cmd += f"name_conversion={args.name_conversion} "
142147
if args.centromeres:
143148
cmd += f"centromeres={args.centromeres} "
144149
if args.normalize:
@@ -155,6 +160,8 @@ def main():
155160
cmd += f"dpi={args.dpi} "
156161
if args.order:
157162
cmd += f"order={args.order} "
163+
if args.annotate_genome_info:
164+
cmd += "annotate_genome_info=True "
158165
if args.tree:
159166
cmd += f"tree={args.tree} "
160167
target = "gggenomes_ribbon_plot_tree"

bin/ntsynt_viz.smk

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5,30 +5,30 @@ import os
55

66

77
# Parameters
8-
synteny_blocks = config["blocks"] if "blocks" in config else None
9-
name_conversion = config["name_conversion"] if "name_conversion" in config else None
10-
name_conversion = None if name_conversion == "None" else name_conversion
11-
prefix = config["prefix"] if "prefix" in config else "ntSynt_gggenomes"
12-
indel_threshold = config["indel_threshold"] if "indel_threshold" in config else 50000
13-
min_len = config["min_length"] if "min_length" in config else 50000
14-
fais = config["fai"] if "fai" in config else None
15-
ribbon_ratio = config["ribbon_ratio"] if "ribbon_ratio" in config else 0.1
16-
cladogram_ratio = config["cladogram_adjust"] if "cladogram_adjust" in config else 0.1
17-
scale = config["scale"] if "scale" in config else 1e9
18-
centromeres = config["centromeres"] if "centromeres" in config else None
19-
normalize = config["normalize"] if "normalize" in config else False
8+
synteny_blocks = config.get("blocks", None)
9+
name_conversion = config.get("name_conversion", None)
10+
prefix = config.get("prefix", "ntSynt_gggenomes")
11+
indel_threshold = config.get("indel_threshold", 50000)
12+
min_len = config.get("min_length", 50000)
13+
fais = config.get("fai", None)
14+
ribbon_ratio = config.get("ribbon_ratio", 0.1)
15+
cladogram_ratio = config.get("cladogram_adjust", 0.1)
16+
scale = config.get("scale", 1e9)
17+
centromeres = config.get("centromeres", None)
18+
normalize = config.get("normalize", False)
2019
blocks_no_suffix = os.path.basename(synteny_blocks).removesuffix(".tsv")
21-
tree = config["tree"] if "tree" in config else None
22-
format_img = config["format"] if "format" in config else "png"
23-
plot_height = config["height"] if "height" in config else 20
24-
plot_width = config["width"] if "width" in config else 50
25-
no_arrow = config["no_arrow"] if "no_arrow" in config else False
26-
target_genome = config["target_genome"] if "target_genome" in config else False
27-
haplotypes = config["haplotypes"] if "haplotypes" in config else []
28-
keep = " ".join(config["keep"]) if "keep" in config else []
29-
min_seq_length = config["min_seq_length"] if "min_seq_length" in config else 500000
30-
res = config["dpi"] if "dpi" in config else 300
20+
tree = config.get("tree", None)
21+
format_img = config.get("format", "png")
22+
plot_height = config.get("height", 20)
23+
plot_width = config.get("width", 50)
24+
no_arrow = config.get("no_arrow", False)
25+
target_genome = config.get("target_genome", False)
26+
haplotypes = config.get("haplotypes", [])
27+
keep = " ".join(config.get("keep", []))
28+
min_seq_length = config.get("min_seq_length", 500000)
29+
res = config.get("dpi", 300)
3130
orders = config.get("order", [])
31+
annotate_genome_info = config.get("annotate_genome_info", False)
3232

3333
def sort_fais(fai_list, name_conversion, orders):
3434
"Based on the name conversion TSV, sort the FAIs based on orders"
@@ -271,10 +271,11 @@ rule ribbon_plot:
271271
arrow = "--no-arrow" if no_arrow else "",
272272
haplotypes = f"--haplotypes {rules.nudges.output.nudges}" if haplotypes else "",
273273
resolution = f"--dpi {res}" if format_img == "png" else "",
274+
annotate_genome_info = "--annotate-genome-info" if annotate_genome_info else "",
274275
shell:
275276
"ntsynt_viz_plot_synteny_blocks_ribbon_plot.R -s {input.sequences} -l {input.links} -p {params.prefix} --ratio {params.ratio}"
276277
" --scale {params.scale} -c {input.colour_feats} --format {params.out_img_format} --height {params.height} --width {params.width}"
277-
" {params.centromeres} {params.arrow} {params.haplotypes} --colour_indices {input.colour_seqs} {params.resolution}"
278+
" {params.centromeres} {params.arrow} {params.haplotypes} --colour_indices {input.colour_seqs} {params.resolution} {params.annotate_genome_info}"
278279

279280
rule ribbon_plot_tree:
280281
input:
@@ -297,7 +298,8 @@ rule ribbon_plot_tree:
297298
arrow = "--no-arrow" if no_arrow else "",
298299
haplotypes = f"--haplotypes {rules.nudges.output.nudges}" if haplotypes else "",
299300
resolution = f"--dpi {res}" if format_img == "png" else "",
301+
annotate_genome_info = "--annotate-genome-info" if annotate_genome_info else "",
300302
shell:
301303
"ntsynt_viz_plot_synteny_blocks_ribbon_plot.R -s {input.sequences} -l {input.links} -p {params.prefix} --tree {input.tree}"
302304
" --ratio {params.ratio} --scale {params.scale} -c {input.colour_feats} --format {params.out_img_format} --height {params.height} --width {params.width}"
303-
" --order {input.orders} {params.centromeres} {params.arrow} {params.haplotypes} --colour_indices {input.colour_seqs} {params.resolution}"
305+
" --order {input.orders} {params.centromeres} {params.arrow} {params.haplotypes} --colour_indices {input.colour_seqs} {params.resolution} {params.annotate_genome_info}"

bin/ntsynt_viz_plot_synteny_blocks_ribbon_plot.R

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,20 @@ parser$add_argument("--ratio",
3838
"Increase if the labels are cut-off,",
3939
"decrease to decrease space between ribbon plot and cladogram"),
4040
default = 0.1, required = FALSE, type = "double")
41+
parser$add_argument("--right-ratio",
42+
help = paste("Ratio adjustment for space on the right side of the ribbon plot.",
43+
"Increase if the labels on the right are cut-off,",
44+
"decrease to decrease space between ribbon plot and right edge of the plot"),
45+
default = 0.03, required = FALSE, type = "double")
4146
parser$add_argument("-p", "--prefix",
4247
help = "Output prefix for PNG image (default synteny_gggenomes_plot)", required = FALSE,
4348
default = "synteny_gggenomes_plot")
4449
parser$add_argument("--format", help = "Output format for image (png, pdf or svg)", required = FALSE,
4550
default = "png", choices = c("png", "pdf", "svg"))
4651
parser$add_argument("--order", help = "TSV file with desired order of tip labels (only used if --tree specified).", required = FALSE)
4752
parser$add_argument("--dpi", help = "Output plot resolution - for PNG only (default 300)", default = 300, required = FALSE, type = "integer")
53+
parser$add_argument("--annotate-genome-info", help = "Add annotations about number of sequences and genome size to the right of each bin",
54+
action = "store_true")
4855

4956
args <- parser$parse_args()
5057

@@ -124,6 +131,32 @@ get_y_coord <- function(haplotypes, bin_id, y, end=FALSE) {
124131
}
125132
}
126133

134+
format_genome_size <- function(bp) {
135+
dplyr::case_when(
136+
bp >= 1e9 ~ paste0(sprintf("%.1f", bp / 1e9), " Gbp"),
137+
bp >= 1e6 ~ paste0(sprintf("%.1f", bp / 1e6), " Mbp"),
138+
bp >= 1e3 ~ paste0(sprintf("%.1f", bp / 1e3), " kbp"),
139+
TRUE ~ paste0(bp, " bp")
140+
)
141+
}
142+
143+
# Return dataframe with bin annotations
144+
get_bin_annotations <- function(plot){
145+
bin_stats <- plot %>%
146+
pull_seqs() %>% # or seqs(gggenomes_obj)
147+
group_by(bin_id) %>%
148+
summarise(
149+
n_chr = n(),
150+
genome_size = sum(length),
151+
y = max(y), # matches gggenomes' y layout
152+
x_right = max(xend) # rightmost coordinate
153+
) %>%
154+
mutate(label = paste0(" ", format_genome_size(genome_size), "; n=", n_chr))
155+
156+
bin_stats <- bin_stats %>% mutate(x_right = max(bin_stats$x_right))
157+
return(bin_stats)
158+
}
159+
127160
# Make the ribbon plot - these layers can be fully customized as needed!
128161
make_plot <- function(links, sequences, painting, colours_df, add_scale_bar = FALSE, centromeres = FALSE, add_arrow = FALSE, haplotypes = FALSE) {
129162
target_genome <- (sequences %>% head(1) %>% select(bin_id))[[1]]
@@ -185,6 +218,14 @@ make_plot <- function(links, sequences, painting, colours_df, add_scale_bar = FA
185218
axis.ticks.x = element_blank())
186219
}
187220

221+
if (args$annotate_genome_info) {
222+
bin_stats <- get_bin_annotations(plot)
223+
224+
plot <- plot + geom_text(data = bin_stats, aes(x = x_right, y = y, label = label, hjust = 0),
225+
size = 4) +
226+
expand_limits(x = max(bin_stats$x_right) + (xmax * (args$right_ratio)))
227+
}
228+
188229
return(plot)
189230

190231
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
GCA_000001405.15_GRCh38_genomic.chr-only.nums.fa
2+
GCF_002880755.1_Clint_PTRv2_genomic.chr-only.rename.fa
3+
GCF_013052645.1_Mhudiblu_PPA_v0_genomic.chr-only.rename.fa
4+
GCF_008122165.1_Kamilah_GGO_v0_genomic.chr-only.rename.fa
5+
GCF_028885625.2_NHGRI_mPonPyg2-v2.0_pri_genomic.chr.renamed.fa
6+
GCA_021498465.1_ASM2149846v1_genomic.renamed.chr.fa

0 commit comments

Comments
 (0)