Skip to content

Commit 859139c

Browse files
committed
feat: initial draft for styling gene arrows; closes #38
1 parent e185776 commit 859139c

File tree

2 files changed

+91
-76
lines changed

2 files changed

+91
-76
lines changed

R/geom_gene.R

Lines changed: 66 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,14 @@
44
#' @param overlap.gene.gap The gap between gene groups. Default: 0.1.
55
#' @param overlap.style The style of gene groups, choose from loose (each gene occupies single line)
66
#' and tight (place non-overlap genes in one line). Default: loose.
7-
#' @param gene.size The line size of gene. Default: 1.
8-
#' @param utr.size The line size of UTR. Default: 2.
9-
#' @param exon.size The line size of exon. Default: 3.
10-
#' @param arrow.size The line size of arrow. Default: 1.5.
7+
#' @param gene.size The line width of genes. Default: 1.
8+
#' @param utr.size The line width of UTRs. Default: 2.
9+
#' @param exon.size The line width of exons. Default: 3.
10+
#' @param arrow.angle Angle of the arrow head. Default 35°
11+
#' @param arrow.length Length of arrows. Default: 1.5
12+
#' @param arrow.type Whether to draw "closed" or "open" (default) arrow heads
13+
14+
#' @param
1115
#' @param arrow.gap The gap distance between intermittent arrows. Default: NULL.
1216
#' Set arrow.num and arrow.gap to NULL to suppress intermittent arrows.
1317
#' @param arrow.num Total number of intermittent arrows over whole region. Default: 50.
@@ -21,6 +25,13 @@
2125
#' @param plot.space Top and bottom margin. Default: 0.1.
2226
#' @param plot.height The relative height of gene annotation to coverage plot. Default: 0.2.
2327
#'
28+
29+
arrow.gap = NULL,
30+
arrow.num = 50,
31+
arrow.size.im = 0.5,
32+
arrow.length.im = 1.5,
33+
arrow.type.im = "closed",
34+
color.by.im = NULL,
2435
#' @return Plot.
2536
#' @importFrom dplyr %>%
2637
#' @importFrom rlang .data
@@ -61,16 +72,37 @@
6172
#' basic.coverage <- ggcoverage(data = track_df, range.position = "out")
6273
#' basic.coverage +
6374
#' geom_gene(gtf.gr = gtf_gr)
75+
#'
76+
#'# plot with custom style
77+
#' basic_coverage +
78+
#' geom_gene(
79+
#' gtf.gr = gtf_gr,
80+
#' exon.size = 2.0,
81+
#' arrow.size.im = 1.0,
82+
#' arrow.length.im = 5,
83+
#' arrow.type.im = "open",
84+
#' color.by.im = "strand",
85+
#' fill.color = c(
86+
#' "-" = "darkblue",
87+
#' "+" = "darkgreen"
88+
#' )
89+
#' )
6490
geom_gene <- function(gtf.gr,
6591
overlap.gene.gap = 0.1,
6692
overlap.style = "loose",
6793
gene.size = 1,
6894
utr.size = 2,
6995
exon.size = 3,
70-
arrow.size = 1.5,
96+
arrow.angle = 35,
97+
arrow.length = 1.5,
98+
arrow.type = "open",
99+
color.by = "strand",
71100
arrow.gap = NULL,
72101
arrow.num = 50,
73-
color.by = "strand",
102+
arrow.size.im = 0.5,
103+
arrow.length.im = 1.5,
104+
arrow.type.im = "closed",
105+
color.by.im = NULL,
74106
fill.color = c(
75107
"-" = "cornflowerblue",
76108
"+" = "darkolivegreen3"
@@ -88,10 +120,16 @@ geom_gene <- function(gtf.gr,
88120
gene.size = gene.size,
89121
utr.size = utr.size,
90122
exon.size = exon.size,
91-
arrow.size = arrow.size,
123+
arrow.angle = arrow.angle,
124+
arrow.length = arrow.length,
125+
arrow.type = arrow.type,
126+
color.by = color.by,
92127
arrow.gap = arrow.gap,
93128
arrow.num = arrow.num,
94-
color.by = color.by,
129+
arrow.size.im = arrow.size.im,
130+
arrow.length.im = arrow.length.im,
131+
arrow.type.im = arrow.type.im,
132+
color.by.im = color.by.im,
95133
fill.color = fill.color,
96134
show.utr = show.utr,
97135
label.size = label.size,
@@ -121,22 +159,9 @@ ggplot_add.gene <- function(object, plot, object_name) {
121159
ranges = IRanges::IRanges(plot.range.start, plot.range.end)
122160
)
123161
# get parameters
124-
gtf.gr <- object$gtf.gr
125-
overlap.gene.gap <- object$overlap.gene.gap
126-
overlap.style <- object$overlap.style
127-
gene.size <- object$gene.size
128-
utr.size <- object$utr.size
129-
exon.size <- object$exon.size
130-
arrow.size <- object$arrow.size
131-
color.by <- object$color.by
132-
fill.color <- object$fill.color
133-
show.utr <- object$show.utr
134-
arrow.gap <- object$arrow.gap
135-
arrow.num <- object$arrow.num
136-
label.size <- object$label.size
137-
label.vjust <- object$label.vjust
138-
plot.space <- object$plot.space
139-
plot.height <- object$plot.height
162+
for (ob in names(object)) {
163+
assign(x = ob, value = object[[ob]])
164+
}
140165

141166
# get gene in region
142167
gtf.df.used <- IRanges::subsetByOverlaps(x = gtf.gr, ranges = plot.range.gr) %>% as.data.frame()
@@ -203,11 +228,11 @@ ggplot_add.gene <- function(object, plot, object_name) {
203228
gene.info.used.utr <- gene.exon.utr$utr
204229
}
205230
gene.plot <- ggplot() +
206-
geom_arrows(gene.info.used.gene, color.by, gene.size, arrow.size) +
207-
geom_arrows(gene.info.used.exon, color.by, exon.size, arrow.size)
231+
geom_arrows(gene.info.used.gene, color.by, gene.size, arrow.length, arrow.angle, arrow.type) +
232+
geom_arrows(gene.info.used.exon, color.by, exon.size, arrow.length, arrow.angle, arrow.type)
208233
if (show.utr) {
209234
gene.plot <- gene.plot +
210-
geom_arrows(gene.info.used.utr, color.by, utr.size, arrow.size)
235+
geom_arrows(gene.info.used.utr, color.by, utr.size, arrow.length, arrow.angle, arrow.type)
211236
}
212237

213238
if (!is.null(arrow.gap) || !is.null(arrow.num)) {
@@ -251,8 +276,21 @@ ggplot_add.gene <- function(object, plot, object_name) {
251276
arrow.df$start <- as.numeric(arrow.df$start)
252277
arrow.df$end <- as.numeric(arrow.df$end)
253278
arrow.df$group <- as.numeric(arrow.df$group)
279+
if (is.null(color.by.im)) {
280+
color.by.im <- color.by
281+
arrow.df[[color.by]] <- "im"
282+
fill.color["im"] <- grDevices::grey(1, alpha = 0.5)
283+
} else if (color.by.im %in% colnames(arrow.df)) {
284+
stopifnot(unique(arrow.df[[color.by.im]]) %in% names(fill.color))
285+
} else {
286+
stop(paste0(
287+
"The selected variable '",
288+
color.by.im ,
289+
"' for 'color.by.im' is not available in the data"
290+
))
291+
}
254292
gene.plot <- gene.plot +
255-
geom_arrows(arrow.df, color.by, gene.size / 2, arrow.size, 35, TRUE)
293+
geom_arrows(arrow.df, color.by.im, arrow.size.im, arrow.length.im, arrow.angle, arrow.type.im)
256294
}
257295

258296
label.df <- data.frame(

R/utils.R

Lines changed: 25 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -355,9 +355,8 @@ GetPlotData <- function(plot, layer.num = 1) {
355355
#' @param color name of the color column in the data frame
356356
#' @param line_width line_width of the (arrow) segment
357357
#' @param arrow_size size of the arrow
358-
#' @param arrow_angle angle of the arrow. Default: 35°
359-
#' @param intermittent If TRUE, arrows are only drawn intermittently in
360-
#' half-transparent white color. Default: FALSE.
358+
#' @param arrow_angle angle of the arrow in degrees
359+
#' @param arrow_type type of arrow, either 'open' or 'closed'
361360
#' @importFrom grDevices grey
362361
#' @return A geom layer for ggplot2 objects.
363362
#' @export
@@ -366,54 +365,32 @@ geom_arrows <-
366365
color,
367366
line_width,
368367
arrow_size,
369-
arrow_angle = 35,
370-
intermittent = FALSE) {
368+
arrow_angle,
369+
arrow_type) {
371370
if (nrow(data)) {
372371
if (!"strand" %in% colnames(data)) {
373372
data$strand <- "+"
374373
}
375-
if (!intermittent) {
376-
geom_segment(
377-
data = data,
378-
mapping = aes_string(
379-
x = "start",
380-
y = "group",
381-
xend = "end",
382-
yend = "group",
383-
color = color
384-
),
385-
arrow = arrow(
386-
ends = ifelse(data$strand == "+", "last", "first"),
387-
angle = arrow_angle,
388-
length = unit(arrow_size, "points"),
389-
type = "open"
390-
),
391-
lineend = "butt",
392-
linejoin = "mitre",
393-
show.legend = FALSE,
394-
linewidth = line_width
395-
)
396-
} else {
397-
geom_segment(
398-
data = data,
399-
mapping = aes_string(
400-
x = "start",
401-
y = "group",
402-
xend = "end",
403-
yend = "group"
404-
),
405-
arrow = arrow(
406-
ends = ifelse(data$strand == "+", "last", "first"),
407-
angle = arrow_angle,
408-
length = unit(arrow_size, "points"),
409-
type = "closed"
410-
),
411-
lineend = "butt",
412-
linejoin = "mitre",
413-
show.legend = FALSE,
414-
linewidth = line_width,
415-
color = grDevices::grey(1, alpha = 0.5)
416-
)
417-
}
374+
geom_segment(
375+
inherit.aes = TRUE,
376+
data = data,
377+
mapping = aes(
378+
x = .data[["start"]],
379+
y = .data[["group"]],
380+
xend = .data[["end"]],
381+
yend = .data[["group"]],
382+
color = .data[[color]]
383+
),
384+
arrow = arrow(
385+
ends = ifelse(data$strand == "+", "last", "first"),
386+
angle = arrow_angle,
387+
length = unit(arrow_size, "points"),
388+
type = arrow_type
389+
),
390+
lineend = "butt",
391+
linejoin = "mitre",
392+
show.legend = FALSE,
393+
linewidth = line_width
394+
)
418395
}
419396
}

0 commit comments

Comments
 (0)