├── .Rbuildignore ├── .gitignore ├── DESCRIPTION ├── LICENSE ├── LICENSE.md ├── NAMESPACE ├── R ├── bedVis.R ├── calcuRotatedCoord.R ├── linkVis.R ├── loadBigWig.R ├── trackVis.R ├── trancriptVis.R └── utils-pipe.R ├── README.md ├── data └── gtf.rda ├── man ├── bedVis.Rd ├── calcuRotatedCoord.Rd ├── gtf.Rd ├── linkVis.Rd ├── loadBigWig.Rd ├── pipe.Rd ├── trackVis.Rd ├── trancriptVis.Rd ├── tranplotR-logo.png └── tranplotR-logo.svg └── transPlotR.Rproj /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^transPlotR\.Rproj$ 2 | ^\.Rproj\.user$ 3 | ^LICENSE\.md$ 4 | ^test-code\.R$ 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | .Rhistory 3 | .Rdata 4 | .httr-oauth 5 | .DS_Store 6 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: transPlotR 2 | Title: Visualize Transcript Structures in Elegant Way 3 | Version: 0.0.5 4 | Authors@R: 5 | person("Jun", "Zhang", , "3219030654@stu.cpu.edu.cn", role = c("aut", "cre"), 6 | comment = c(ORCID = "0000-0001-7692-9105")) 7 | Description: To visualize the gene structure with multiple isoforms better, I developed this package to draw different transcript structures easily. 8 | License: MIT + file LICENSE 9 | Encoding: UTF-8 10 | Roxygen: list(markdown = TRUE) 11 | RoxygenNote: 7.2.3 12 | Imports: 13 | cowplot, 14 | dplyr, 15 | ggplot2, 16 | purrr, 17 | magrittr, 18 | ggarchery, 19 | geomtextpath, 20 | stats, 21 | rtracklayer, 22 | ggnewscale, 23 | future, 24 | furrr, 25 | ggh4x 26 | Depends: 27 | R (>= 2.10), 28 | tidyverse 29 | URL: https://github.com/junjunlab/transPlotR 30 | BugReports: https://github.com/junjunlab/transPlotR/issues 31 | LazyData: true 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | YEAR: 2022 2 | COPYRIGHT HOLDER: transPlotR authors 3 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # MIT License 2 | 3 | Copyright (c) 2022 transPlotR authors 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 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | export("%>%") 4 | export(bedVis) 5 | export(calcuRotatedCoord) 6 | export(linkVis) 7 | export(loadBigWig) 8 | export(trackVis) 9 | export(trancriptVis) 10 | import(cowplot) 11 | import(stats) 12 | import(tidyverse) 13 | importFrom(magrittr,"%>%") 14 | -------------------------------------------------------------------------------- /R/bedVis.R: -------------------------------------------------------------------------------- 1 | #' @title bedVis 2 | #' @name bedVis 3 | #' @author JunZhang 4 | #' @description visualize peaks(bed files). 5 | #' 6 | #' @param bdFile the bed file path, default(NULL). 7 | #' @param chr the chromesome of peak, default(NULL). 8 | #' @param region.min the peak start coordinate, default(NULL). 9 | #' @param region.max the peak end coordinate, default(NULL). 10 | #' @param track.width track width, default(0.1). 11 | #' @param collapse whether collapse the track, default(FALSE). 12 | #' @param fill track fill colors, default(NULL). 13 | #' @param show.legend whether show fill color legend, default(TRUE). 14 | #' @param add.label whether add peak name, default(FALSE). 15 | #' @param label.column the peak name column name, default(NULL). 16 | #' @param label.vjsut the peak label vjust, default(0.1). 17 | #' 18 | #' @return a ggplot object. 19 | #' 20 | #' @export 21 | 22 | globalVariables(c("sn","ymin")) 23 | 24 | bedVis <- function(bdFile = NULL, 25 | chr = NULL, 26 | region.min = NULL, 27 | region.max = NULL, 28 | track.width = 0.1, 29 | collapse = FALSE, 30 | fill = NULL, 31 | show.legend = TRUE, 32 | add.label = FALSE, 33 | label.column = NULL, 34 | label.vjsut = 0.1){ 35 | # loop read bed 36 | purrr::map_df(1:length(bdFile),function(x){ 37 | tmp <- rtracklayer::import.bed(bdFile[x]) %>% 38 | data.frame() 39 | 40 | # add name 41 | tmp$fileName <- strsplit(bdFile[x],split = ".bed") %>% unlist() 42 | 43 | # add sn 44 | tmp$sn <- x 45 | return(tmp) 46 | }) -> bdData 47 | 48 | # filter region data 49 | if(!is.null(region.min) & !is.null(region.max)){ 50 | regeion.bd <- bdData %>% 51 | dplyr::filter(seqnames == chr) %>% 52 | dplyr::filter(start >= region.min & end <= region.max) 53 | }else{ 54 | regeion.bd <- bdData %>% 55 | dplyr::filter(seqnames == chr) 56 | } 57 | 58 | # whether collapse track 59 | if(collapse == TRUE){ 60 | regeion.bd$sn <- 1 61 | } 62 | 63 | # add y region 64 | regeion.bd <- regeion.bd %>% 65 | dplyr::mutate(ymin = sn - track.width, 66 | ymax = sn + track.width) 67 | 68 | # plot 69 | bed <- 70 | ggplot2::ggplot(regeion.bd) + 71 | ggplot2::geom_rect(ggplot2::aes_string(xmin = 'start',xmax = 'end', 72 | ymin = 'ymin',ymax = 'ymax', 73 | fill = 'fileName'), 74 | show.legend = show.legend) + 75 | ggplot2::theme_bw(base_size = 14) + 76 | ggplot2::theme(panel.grid = ggplot2::element_blank(), 77 | axis.text = ggplot2::element_blank(), 78 | axis.ticks = ggplot2::element_blank(), 79 | axis.title = ggplot2::element_blank()) + 80 | ggplot2::guides(fill = ggplot2::guide_legend(title = '')) 81 | 82 | if(!is.null(fill)){ 83 | bed.col <- bed + 84 | ggplot2::scale_fill_manual(values = fill) 85 | }else{ 86 | bed.col <- bed 87 | } 88 | 89 | # ======================================== 90 | # add peak label 91 | if(add.label == TRUE){ 92 | bed.label <- bed.col + 93 | ggplot2::geom_text(ggplot2::aes(x = (start + end)/2,y = ymin - label.vjsut, 94 | label = get(label.column)), 95 | check_overlap = TRUE) 96 | }else{ 97 | bed.label <- bed.col 98 | } 99 | return(bed.label) 100 | } 101 | -------------------------------------------------------------------------------- /R/calcuRotatedCoord.R: -------------------------------------------------------------------------------- 1 | #' @title calcuRotatedCoord 2 | #' @name calcuRotatedCoord 3 | #' @author JunZhang 4 | #' @description calculate the rotated rectangle coordinate with specified degree. 5 | #' 6 | #' @param data data.frame 7 | #' @param theta rotate degree, default(45). 8 | #' @param workers how many workers for parallel calculation, default(1). 9 | #' @param rx x variable name, default(NULL). 10 | #' @param ry y variable name, default(NULL). 11 | #' 12 | #' @return a data.frame 13 | #' @export 14 | 15 | globalVariables(c('.data','multisession','xr','yr')) 16 | 17 | calcuRotatedCoord <- function(data = NULL, 18 | rx = NULL, 19 | ry = NULL, 20 | theta = 45, 21 | workers = 1){ 22 | # Set a "plan" for how the code should run. 23 | future::plan(future::multisession, workers = workers) 24 | 25 | # get coord 26 | furrr::future_map_dfr(1:nrow(data),function(i){ 27 | tmp <- data[i,] 28 | 29 | x <- rx 30 | y <- ry 31 | 32 | tmp <- tmp %>% 33 | dplyr::mutate(xr = .data[[x]]*cos(pi*(theta/180)) + .data[[y]]*sin(pi*(theta/180)), 34 | yr = .data[[y]]*cos(pi*(theta/180)) - .data[[x]]*sin(pi*(theta/180))) 35 | 36 | tmp <- tmp %>% 37 | dplyr::mutate(xr = xr*cos(pi*(theta/180)), 38 | yr = yr*sin(pi*(theta/180))) 39 | return(tmp) 40 | }) -> data 41 | 42 | return(data) 43 | } 44 | -------------------------------------------------------------------------------- /R/linkVis.R: -------------------------------------------------------------------------------- 1 | #' @title linkVis 2 | #' @name linkVis 3 | #' @author JunZhang 4 | #' @description visualize the coordinate relation like chromtin accessbility or peak sites correlation. 5 | #' 6 | #' @param linkData the link data with data.frame format, default(NULL). 7 | #' @param start link start position, default(NULL). 8 | #' @param end link end position, default(NULL). 9 | #' @param group facet group variable name, default(NULL). 10 | #' @param link.aescolor link line color or mapping variable name, default(NULL). 11 | #' @param link.color colors to change the link line colors when "link.aescolor" is a mapping variable, default(NULL). 12 | #' @param line.size link line size, default(0.5). 13 | #' @param curvature the link line curvature, default(0.5). 14 | #' @param yshift the space upper the link line, default(0.1). 15 | #' @param legend.title the legend title, default(""). 16 | #' @param facet whether show the plot with facet plot, default(TRUE). 17 | #' @param facet.placement the facet label placement, default("outside"). 18 | #' @param facet.fill facet rectangle fill color, default("grey90"). 19 | #' @param facet.color facet rectangle border color, default("black"). 20 | #' @param facet.text.angle facet text angle, default(90). 21 | #' @param facet.text.size facet text size, default(14). 22 | #' @param xAixs.info whether remove X axis info, default(FASLE). 23 | #' 24 | #' @param base_size theme base_size, default(14). 25 | #' 26 | #' @return a ggplot object. 27 | #' @export 28 | 29 | linkVis <- function(linkData = NULL, 30 | start = NULL, 31 | end = NULL, 32 | group = NULL, 33 | base_size = 14, 34 | link.aescolor = NULL, 35 | link.color = NULL, 36 | line.size = 0.5, 37 | curvature = 0.5, 38 | yshift = 0.1, 39 | legend.title = "", 40 | facet = TRUE, 41 | facet.placement = "outside", 42 | facet.fill = "grey90", 43 | facet.color = "black", 44 | facet.text.angle = 90, 45 | facet.text.size = 14, 46 | xAixs.info = TRUE){ 47 | # get input data 48 | data <- linkData 49 | colname <- colnames(data) 50 | 51 | # whether facet by groups 52 | if(facet == TRUE){ 53 | if(link.aescolor %in% colname){ 54 | p1 <- 55 | ggplot2::ggplot(linkData) + 56 | ggplot2::geom_curve(ggplot2::aes_string(x = start,xend = end, 57 | y = group,yend = group, 58 | color = link.aescolor), 59 | curvature = curvature, 60 | lwd = line.size) 61 | }else{ 62 | p1 <- 63 | ggplot2::ggplot(linkData) + 64 | ggplot2::geom_curve(ggplot2::aes_string(x = start,xend = end, 65 | y = group,yend = group), 66 | color = link.aescolor, 67 | curvature = curvature, 68 | lwd = line.size) 69 | } 70 | }else{ 71 | linkData$yc <- as.character(1) 72 | 73 | if(link.aescolor %in% colname){ 74 | p1 <- 75 | ggplot2::ggplot(linkData) + 76 | ggplot2::geom_curve(ggplot2::aes_string(x = start,xend = end, 77 | y = "yc",yend = "yc", 78 | color = link.aescolor), 79 | curvature = curvature, 80 | lwd = line.size) 81 | }else{ 82 | p1 <- 83 | ggplot2::ggplot(linkData) + 84 | ggplot2::geom_curve(ggplot2::aes_string(x = start,xend = end, 85 | y = "yc",yend = "yc"), 86 | color = link.aescolor, 87 | curvature = curvature, 88 | lwd = line.size) 89 | } 90 | } 91 | 92 | # ajust y 93 | p1 <- p1 + 94 | ggplot2::scale_y_discrete(expand = ggplot2::expansion(mult = c(0,-yshift))) + 95 | ggplot2::theme_bw(base_size) + 96 | ggplot2::xlab('') + ggplot2::ylab('') 97 | 98 | # whether mapping color 99 | if(link.aescolor %in% colname){ 100 | if(is.null(link.color)){ 101 | if(is.numeric(linkData[,link.aescolor])){ 102 | p2 <- p1 + 103 | ggplot2::scale_color_gradient(low = "#339933", 104 | high = "#FF9900", 105 | name = legend.title) 106 | }else{ 107 | p2 <- p1 + 108 | ggplot2::scale_color_discrete(name = legend.title) 109 | } 110 | }else{ 111 | if(is.numeric(linkData[,link.aescolor])){ 112 | p2 <- p1 + 113 | ggplot2::scale_color_gradient(low = link.color[1], 114 | high = link.color[2], 115 | name = legend.title) 116 | }else{ 117 | p2 <- p1 + 118 | ggplot2::scale_color_manual(values = link.color, 119 | name = legend.title) 120 | } 121 | } 122 | }else{ 123 | p2 <- p1 124 | } 125 | 126 | # facet 127 | if(facet == TRUE){ 128 | p3 <- p2 + 129 | ggplot2::theme(axis.ticks.y = ggplot2::element_blank(), 130 | axis.text.y = ggplot2::element_blank(), 131 | panel.grid = ggplot2::element_blank(), 132 | strip.placement = facet.placement, 133 | strip.background = ggplot2::element_rect(fill = facet.fill, 134 | color = facet.color), 135 | strip.text.y.left = ggplot2::element_text(angle = facet.text.angle, 136 | size = facet.text.size)) + 137 | ggplot2::facet_wrap(facets = group, 138 | ncol = 1,scales = "free_y", 139 | strip.position = "left") 140 | }else{ 141 | p3 <- p2 + 142 | ggplot2::theme(axis.ticks.y = ggplot2::element_blank(), 143 | axis.text.y = ggplot2::element_blank(), 144 | panel.grid = ggplot2::element_blank()) 145 | } 146 | 147 | # whether remove X axis info 148 | if(xAixs.info == FALSE){ 149 | p4 <- p3 + 150 | ggplot2::theme(axis.text.x = ggplot2::element_blank(), 151 | axis.ticks.x = ggplot2::element_blank()) 152 | }else{ 153 | p4 <- p3 154 | } 155 | return(p4) 156 | } 157 | 158 | -------------------------------------------------------------------------------- /R/loadBigWig.R: -------------------------------------------------------------------------------- 1 | #' @title loadBigWig 2 | #' @name loadBigWig 3 | #' @author JunZhang 4 | #' @description read bigwig files. 5 | #' 6 | #' @param bwFile the path of bigwig files, default(NULL). bigwig files should end with ".bw" or ".bigwig" and directory should not be named "bw" or"bigwig". 7 | #' 8 | #' @return a data.frame 9 | #' @export 10 | 11 | loadBigWig <- function(bwFile = NULL){ 12 | # loop read bed 13 | purrr::map_df(1:length(bwFile),function(x){ 14 | tmp <- rtracklayer::import.bw(bwFile[x]) %>% 15 | data.frame() %>% 16 | dplyr::select(-width,-strand) 17 | 18 | # sampe name 19 | spt <- strsplit(bwFile[x],split = "/|.bw|.bigwig") %>% unlist() 20 | sname <- spt[length(spt)] 21 | # add name 22 | tmp$fileName <- sname 23 | 24 | return(tmp) 25 | }) -> bWData 26 | return(bWData) 27 | } 28 | -------------------------------------------------------------------------------- /R/trackVis.R: -------------------------------------------------------------------------------- 1 | #' @title trackVis 2 | #' @name trackVis 3 | #' @author JunZhang 4 | #' @description visualize bigwig files. 5 | #' 6 | #' @param bWData the data.frame bigwig data, default(NULL). 7 | #' @param gtf.file whether supply gtf annotation file, default(NULL). 8 | #' @param gene.name the gene name to be choosed for visualization, default(NULL). 9 | #' @param chr chr the chromesome of peak, default(NULL). 10 | #' @param region.min the start coordinate, default(NULL). 11 | #' @param region.max the end coordinate, default(NULL). 12 | #' @param show.legend whether show color legend, default(FALSE). 13 | #' @param legend.position the legend position, default("right"). 14 | #' @param color the track color, default(NULL). 15 | #' @param extend.up extend for upstream of start site, default(3000). 16 | #' @param extend.dn extend for downstream of start site, default(3000). 17 | #' @param base_size theme base size, default(14). 18 | #' @param label.angle the facet label angle, default(0). 19 | #' @param label.face the facet label face, default("bold"). 20 | #' @param space.y the facet panel space, default(0.5). 21 | #' @param sample.order the sample order to be plotted in graph, default(NULL). 22 | #' @param sampleName.dist the facet label distance from Y axis, default(0.4). 23 | #' @param sampleName.hjust the facet label hjust, default(1). 24 | #' @param sampleName.vjust the facet label vjust, default(0.5). 25 | #' @param xAxis.info whether retain X axis info, default(TRUE). 26 | #' @param yAxis.info whether retain Y axis info, default(TRUE). 27 | #' @param ticks.y.len the y axis ticks length, default(0.3). 28 | #' @param theme plot theme, "bw" or "classic", default("classic"). 29 | #' @param scales the facet scales settings, default("fixed"). 30 | #' @param ncol the columns to be arranged, default(1). 31 | #' @param mark.region whether highlight regions in plot, default(FALSE). 32 | #' @param mark.col the colors of marked regions, default(NULL). 33 | #' @param mark.alpha the color alpha of marked regions, default(0.5). 34 | #' @param new.yaxis whether add new style Y axis, default(FALSE). 35 | #' @param pos.ratio the new style Y axis relative position, default(c(0.01,0.8)). 36 | #' @param yinfo.text.size the new style Y axis text size, default(5). 37 | #' 38 | #' @param back.color whether add panel background color, default(FALSE). 39 | #' @param back.color.alpha panel background color alpha, default(0.15). 40 | #' @param y.max the ylim, default(NULL). 41 | #' @param new.label whether add label in plot, default(FALSE). 42 | #' @param label.color the label color, default(NULL). 43 | #' @param pos.label.ratio the new label relative position, default(c(0.99,0.8)). 44 | #' @param label.text.size the new label text size, default(5). 45 | #' @param label.hjust the new label text hjust, default(1). 46 | #' @param yinfo.hjust the new style Y axis text hjust, default(0). 47 | #' @param facetGroup the annotation for samples, default(NULL). 48 | #' @param annoLine.size the annotation line size, default(1). 49 | #' @param line.arrow the annotation line arrow, default(NULL). 50 | #' 51 | #' @return a ggplot object. 52 | #' @export 53 | 54 | globalVariables(c("fileName","group","label","score","x","y")) 55 | 56 | trackVis <- function(bWData = NULL, 57 | gtf.file = NULL, 58 | gene.name = NULL, 59 | chr = NULL, 60 | region.min = NULL, 61 | region.max = NULL, 62 | show.legend = FALSE, 63 | legend.position = "right", 64 | color = NULL, 65 | extend.up = 3000, 66 | extend.dn = 3000, 67 | base_size = 14, 68 | label.angle = 0, 69 | label.face = "bold", 70 | space.y = 0.5, 71 | sample.order = NULL, 72 | sampleName.dist = 0, 73 | sampleName.hjust = 1, 74 | sampleName.vjust = 0.5, 75 | facetGroup = NULL, 76 | annoLine.size = 1, 77 | line.arrow = NULL, 78 | y.max = NULL, 79 | xAxis.info = TRUE, 80 | yAxis.info = TRUE, 81 | ticks.y.len = 0.3, 82 | theme = "classic", 83 | scales = "fixed", 84 | ncol = 1, 85 | mark.region = NULL, 86 | mark.col = NULL, 87 | mark.alpha = 0.5, 88 | new.yaxis = FALSE, 89 | pos.ratio = c(0.01,0.8), 90 | yinfo.text.size = 5, 91 | yinfo.hjust = 0, 92 | new.label = FALSE, 93 | label.color = NULL, 94 | pos.label.ratio = c(0.99,0.8), 95 | label.text.size = 5, 96 | label.hjust = 1, 97 | back.color = FALSE, 98 | back.color.alpha = 0.15){ 99 | # whether supply gene name 100 | if(!is.null(gtf.file) & !is.null(gene.name)){ 101 | gene <- gtf.file %>% dplyr::filter(gene_name == gene.name) 102 | chr <- unique(gene$seqnames) %>% as.character() 103 | region.min <- min(gene$start) 104 | region.max <- max(gene$start) 105 | } 106 | 107 | # filter specified region 108 | regeion.bw <- bWData %>% 109 | dplyr::filter(seqnames == chr) %>% 110 | dplyr::filter(start >= (region.min - extend.up) & end <= (region.max + extend.dn)) 111 | 112 | # whether change order 113 | if(!is.null(sample.order)){ 114 | regeion.bw$fileName <- factor(regeion.bw$fileName,levels = sample.order) 115 | }else{ 116 | regeion.bw$fileName <- factor(regeion.bw$fileName,levels = unique(regeion.bw$fileName)) 117 | } 118 | 119 | # panel background data 120 | dback <- data.frame(fileName = factor(unique(regeion.bw$fileName), 121 | levels = levels(regeion.bw$fileName))) 122 | # dback <- regeion.bw[,7:ncol(regeion.bw)] %>% unique() %>% data.frame() 123 | 124 | # whether add background 125 | if(back.color == TRUE){ 126 | p0 <- 127 | ggplot2::ggplot(regeion.bw) + 128 | ggplot2::geom_rect(data = dback, 129 | ggplot2::aes(xmin = -Inf,xmax = Inf,ymin = 0,ymax = Inf, 130 | fill = fileName), 131 | show.legend = FALSE, 132 | alpha = back.color.alpha) 133 | }else{ 134 | p0 <- 135 | ggplot2::ggplot(regeion.bw) 136 | } 137 | 138 | # plot 139 | p1 <- p0 + 140 | ggplot2::geom_rect(ggplot2::aes(xmin = start,xmax = end, 141 | ymin = 0,ymax = score, 142 | fill = fileName,color = fileName), 143 | show.legend = show.legend) + 144 | ggplot2::geom_segment(ggplot2::aes(x = min(start),xend = max(end), 145 | y = 0,yend = 0), 146 | size = 1) + 147 | ggplot2::xlab('') + ggplot2::ylab('') + 148 | ggplot2::coord_cartesian(expand = 0) + 149 | ggplot2::guides(fill = ggplot2::guide_legend(title = '')) + 150 | ggplot2::guides(color = ggplot2::guide_legend(title = '')) 151 | 152 | if(is.null(facetGroup)){ 153 | p1 <- p1 + 154 | ggplot2::facet_wrap(~fileName,ncol = ncol, 155 | strip.position = 'left',scales = scales) 156 | }else{ 157 | p1 <- p1 + 158 | ggh4x::facet_nested_wrap(facets = c(facetGroup,"fileName"), 159 | nest_line = ggplot2::element_line(colour = 'black', 160 | size = annoLine.size, 161 | arrow = line.arrow), 162 | strip.position = 'left', 163 | scales = scales,ncol = ncol) 164 | } 165 | 166 | # y labels 167 | if(is.null(y.max)){ 168 | if(scales == "fixed"){ 169 | ylimit <- range(regeion.bw$score)[2] 170 | }else{ 171 | # free_y 172 | if(is.null(facetGroup)){ 173 | ylimit <- regeion.bw %>% 174 | dplyr::group_by(fileName) %>% 175 | dplyr::summarise(maxScore = max(score)) 176 | }else{ 177 | ylimit <- regeion.bw %>% 178 | dplyr::group_by(.data[[facetGroup]],fileName) %>% 179 | dplyr::summarise(maxScore = max(score)) 180 | } 181 | } 182 | }else{ 183 | if(scales == "fixed"){ 184 | ylimit <- y.max 185 | }else{ 186 | # free_y 187 | if(is.null(facetGroup)){ 188 | ylimit <- regeion.bw %>% 189 | dplyr::group_by(fileName) %>% 190 | dplyr::summarise(maxScore = max(score)) 191 | 192 | # add new range 193 | ylimit$minScore <- unlist(y.max[[1]]) 194 | ylimit$maxScore <- unlist(y.max[[2]]) 195 | }else{ 196 | ylimit <- regeion.bw %>% 197 | dplyr::group_by(.data[[facetGroup]],fileName) %>% 198 | dplyr::summarise(maxScore = max(score)) 199 | 200 | # add new range 201 | ylimit$minScore <- unlist(y.max[[1]]) 202 | ylimit$maxScore <- unlist(y.max[[2]]) 203 | } 204 | } 205 | } 206 | 207 | # change y range 208 | if(scales == "fixed"){ 209 | p1 <- p1 + 210 | ggplot2::scale_y_continuous(breaks = c(0,ylimit), 211 | limits = c(0,ylimit)) 212 | }else{ 213 | if(!is.null(y.max)){ 214 | low <- unlist(y.max[[1]]) 215 | high <- unlist(y.max[[2]]) 216 | 217 | # facet new scales 218 | lapply(1:length(unique(regeion.bw$fileName)), function(x){ 219 | ggplot2::scale_y_continuous(limits = c(low[x],high[x]), 220 | breaks = c(low[x],high[x])) 221 | }) -> new.scales 222 | 223 | # add new scales 224 | p1 <- p1 + 225 | ggh4x::facetted_pos_scales(y = new.scales) 226 | }else{ 227 | p1 <- p1 228 | } 229 | } 230 | 231 | # choose theme 232 | if(theme == "bw"){ 233 | p1.1 <- p1 + 234 | ggplot2::theme_bw(base_size = base_size) + 235 | ggplot2::theme(strip.text.y.left = ggplot2::element_text(angle = label.angle, 236 | face = label.face, 237 | size = base_size, 238 | hjust = sampleName.hjust, 239 | vjust = sampleName.vjust), 240 | panel.grid = ggplot2::element_blank(), 241 | legend.position = legend.position, 242 | strip.placement = 'outside', 243 | strip.background = ggplot2::element_rect(fill = NA,colour = NA), 244 | strip.switch.pad.wrap = ggplot2::unit(sampleName.dist,'cm'), 245 | panel.spacing = ggplot2::unit(space.y,'cm')) 246 | 247 | }else{ 248 | p1.1 <- p1 + 249 | ggplot2::theme_classic(base_size = base_size) + 250 | ggplot2::theme(strip.text.y.left = ggplot2::element_text(angle = label.angle, 251 | face = label.face, 252 | size = base_size, 253 | hjust = sampleName.hjust, 254 | vjust = sampleName.vjust), 255 | panel.grid = ggplot2::element_blank(), 256 | legend.position = legend.position, 257 | strip.placement = 'outside', 258 | strip.background = ggplot2::element_rect(fill = NA,colour = NA), 259 | strip.switch.pad.wrap = ggplot2::unit(sampleName.dist,'cm'), 260 | panel.spacing = ggplot2::unit(space.y,'cm'), 261 | axis.ticks.length.y = ggplot2::unit(ticks.y.len,"cm")) 262 | } 263 | 264 | # whether supply own colors 265 | if(!is.null(color)){ 266 | p2 <- p1.1 + 267 | ggplot2::scale_fill_manual(values = color) + 268 | ggplot2::scale_color_manual(values = color) 269 | }else{ 270 | p2 <- p1.1 271 | } 272 | 273 | # whether retain X axis info 274 | if(xAxis.info == FALSE){ 275 | p3 <- p2 + 276 | ggplot2::theme(axis.ticks.x = ggplot2::element_blank(), 277 | axis.text.x = ggplot2::element_blank()) 278 | }else{ 279 | p3 <- p2 280 | } 281 | 282 | # whether retain Y axis info 283 | if(yAxis.info == FALSE){ 284 | p4 <- p3 + 285 | ggplot2::theme(axis.ticks.y = ggplot2::element_blank(), 286 | axis.text.y = ggplot2::element_blank()) 287 | }else{ 288 | p4 <- p3 289 | } 290 | 291 | # whether mark some regions 292 | if(!is.null(mark.region)){ 293 | if(is.list(mark.region)){ 294 | mark.df.tmp <- data.frame(start = unlist(mark.region[[1]]), 295 | end = unlist(mark.region[[2]]), 296 | group = as.character(1:length(unlist(mark.region[[1]])))) 297 | 298 | lapply(1:length(unique(regeion.bw$fileName)), function(x){ 299 | tmp <- mark.df.tmp 300 | tmp$fileName <- unique(regeion.bw$fileName)[x] 301 | return(tmp) 302 | }) %>% do.call("rbind",.) %>% data.frame() -> mark.df 303 | 304 | mark.df$fileName <- factor(mark.df$fileName,levels = levels(regeion.bw$fileName)) 305 | 306 | # add mark 307 | p5 <- p4 + 308 | ggnewscale::new_scale_fill() + 309 | ggplot2::geom_rect(data = mark.df, 310 | ggplot2::aes(xmin = start,xmax = end, 311 | ymin = 0,ymax = ylimit, 312 | fill = group),alpha = mark.alpha, 313 | show.legend = FALSE) 314 | 315 | # change mark colors 316 | if(!is.null(mark.col)){ 317 | p5 <- p5 + 318 | ggplot2::scale_fill_manual(values = mark.col) 319 | }else{ 320 | p5 <- p5 321 | } 322 | }else{ 323 | print("Please supply list object!") 324 | } 325 | }else{ 326 | p5 <- p4 327 | } 328 | 329 | # whether add new yaxis 330 | if(new.yaxis == TRUE){ 331 | if(scales == "fixed"){ 332 | yinfo <- data.frame(label = paste("[0-",ylimit,"]",sep = ''), 333 | x = range(regeion.bw$start)[1] + pos.ratio[1]*(range(regeion.bw$start)[2] - range(regeion.bw$start)[1]), 334 | y = pos.ratio[2]*ylimit) 335 | }else{ 336 | if(is.null(y.max)){ 337 | yinfo <- data.frame(label = paste("[0-",ylimit$maxScore,"]",sep = ''), 338 | fileName = ylimit$fileName, 339 | group = if("group" %in% colnames(ylimit)){ylimit$group}else{1}, 340 | x = range(regeion.bw$start)[1] + pos.ratio[1]*(range(regeion.bw$start)[2] - range(regeion.bw$start)[1]), 341 | y = pos.ratio[2]*ylimit$maxScore) 342 | }else{ 343 | yinfo <- data.frame(label = paste("[",ylimit$minScore,"-",ylimit$maxScore,"]",sep = ''), 344 | fileName = ylimit$fileName, 345 | group = if("group" %in% colnames(ylimit)){ylimit$group}else{1}, 346 | x = range(regeion.bw$start)[1] + pos.ratio[1]*(range(regeion.bw$start)[2] - range(regeion.bw$start)[1]), 347 | y = pos.ratio[2]*ylimit$maxScore) 348 | } 349 | } 350 | 351 | # add text label 352 | p6 <- p5 + 353 | ggplot2::geom_text(data = yinfo, 354 | ggplot2::aes(x = x,y = y,label = label), 355 | size = yinfo.text.size, 356 | hjust = yinfo.hjust) 357 | }else{ 358 | p6 <- p5 359 | } 360 | 361 | # whether add new sample label 362 | if(new.label == TRUE){ 363 | if(is.null(facetGroup)){ 364 | group <- NA 365 | fileName <- unique(regeion.bw$fileName) 366 | }else{ 367 | tmp <- regeion.bw %>% 368 | dplyr::select(fileName,group) %>% 369 | unique() 370 | fileName <- tmp$fileName 371 | group <- tmp$group 372 | } 373 | 374 | # label info 375 | labelinfo <- data.frame(fileName = fileName, 376 | group = group, 377 | x = range(regeion.bw$start)[1] + pos.label.ratio[1]*(range(regeion.bw$start)[2] - range(regeion.bw$start)[1]), 378 | y = pos.label.ratio[2]*ylimit) 379 | 380 | labelinfo$fileName <- factor(labelinfo$fileName,levels = levels(regeion.bw$fileName)) 381 | 382 | # add text label 383 | if(is.null(label.color)){ 384 | label.color <- rep('black',nrow(labelinfo)) 385 | }else{ 386 | label.color <- label.color 387 | } 388 | 389 | # plot 390 | p7 <- p6 + 391 | ggnewscale::new_scale_color() + 392 | ggplot2::geom_text(data = labelinfo, 393 | ggplot2::aes(x = x,y = y,label = fileName,color = fileName), 394 | show.legend = FALSE, 395 | size = label.text.size, 396 | hjust = label.hjust, 397 | fontface = label.face) + 398 | ggplot2::scale_color_manual(values = label.color) 399 | # ggplot2::theme(strip.text.y.left = ggplot2::element_blank()) 400 | if(is.null(facetGroup)){ 401 | p7 <- p7 + 402 | ggplot2::theme(strip.text.y.left = ggplot2::element_blank()) 403 | }else{ 404 | p7 <- p7 405 | } 406 | }else{ 407 | p7 <- p6 408 | } 409 | 410 | return(p7) 411 | } 412 | -------------------------------------------------------------------------------- /R/trancriptVis.R: -------------------------------------------------------------------------------- 1 | #' @title trancriptVis 2 | #' @name trancriptVis 3 | #' @author JunZhang 4 | #' @description This package is to visualize gene diffrent isoforms. 5 | #' @param gtfFile GTF file. 6 | #' @param gene Target gene to plot. 7 | #' @param myTranscript Specify which transcripts to plot use transcipt id. 8 | #' @param Chr Chromosome number. 9 | #' @param posStart Region start position on genome. 10 | #' @param posEnd Region end position on genome. 11 | #' @param collapse Whether to collapse multiple transcripts into one, default(FALSE). 12 | #' @param exonWidth Exon width to plot, default(0.3). 13 | #' @param relTextDist Transcripts name or gene name relative to exon, default(0.3). 14 | #' @param intronSize Intron line size, default(0.5). 15 | #' @param arrowBreak How many gap distance to draw arrows, the smaller the more arrows, default(0.15). 16 | #' @param exonColorBy Whether color group by "transcript_id" or "gene_name", default(NULL). 17 | #' @param exonFill Exon fill color, default('#333399'). 18 | #' @param circle Whether make plot into a circle plot, default(FALSE). 19 | #' @param cicStart Circle plot start position, default(pi). 20 | #' @param circSegCol Circle sgement color, default('#333399'). 21 | #' @param text_only When circle plot labeled by gene name, whether remove the line connected with gene name, default(FALSE). 22 | #' @param ylimLow The Y axis lower limitation of Circle plot, default(-10). 23 | #' @param openAngle The gap of the circle plot, default(0.5). 24 | #' @param arrowCol Normal arrow color, default('#333399'). 25 | #' @param arrowAngle Normal arrow angle, default(30). 26 | #' @param arrowLength Normal arrow length, default(0.1). 27 | #' @param arrowType Normal arrow type, default('open'). 28 | #' @param addNormalArrow Whether add normal arrow on plot, default(TRUE). 29 | #' @param newStyleArrow Whether add new style arrow on plot, default(FALSE). 30 | #' @param absSpecArrowLen Whether make new style arrow length to be relative to each transcript length or absolute length to the longest transcript, default(FALSE). 31 | #' @param speArrowRelPos The relative position to the transcript on horizontal direction of new style arrow, default(0). 32 | #' @param speArrowRelLen The relative length to the transcript length of new style arrow, default(0.05). 33 | #' @param speArrowStart The new style arrow start position on the vertical direction, default(-0.15). 34 | #' @param speArrowRelHigh The relative height of new style arrow to the vertical length, default(2). 35 | #' @param speArrowLineSize The new style arrow line size, default(0.5). 36 | #' @param speArrowCol The new style arrow line color, default('black'). 37 | #' @param speArrowAngle The new style arrow angle, default(30). 38 | #' @param speArrowLen The new style arrow length, default(0.1). 39 | #' @param speArrowType The new style arrow type, default('closed'). 40 | #' @param textLabel The text label aesthetic mappings, default('transcript_id'). 41 | #' @param textLabelSize The text label size, default(5). 42 | #' @param textLabelColor The text label color, default('black'). 43 | #' @param base_size Theme basesize, default(14). 44 | #' @param marginX Plot left and right margins, default(0.2). 45 | #' @param marginY Plot top and bottomn margins, default(0.2). 46 | #' @param aspect.ratio Plot ratio, default(NULL). 47 | #' @param facetByGene Whether facet by gene to plot, this useful for your genes which are far away from each other or not located on the same chromosome, default(FALSE). 48 | #' @param ncolGene The column numbers to plot, default(NULL). 49 | #' @param scales Facet plot scales, same as "facet_wrap" function, default('free'). 50 | #' @param strip.position Facet plot strip.position, same as "facet_wrap" function, default('top'). 51 | #' @param forcePosRel Whether force the genome coordinate to relative position to transcript start/end position, default('FALSE'). 52 | #' @param panel.spacing Facet plot panel space, default(0.3). 53 | #' @param revNegStrand Whether reverse the negtive strand when set "forcePosRel=TRUE", default('FALSE'). 54 | #' 55 | #' @param xAxis.info Whether retain X axis ticks and text, default(TRUE). 56 | #' @param reverse.y whether reverse the Y axis, default(FALSE). 57 | #' @param text.pos the label position(left/right), default(middle). 58 | #' @param selecType choose the representative transcript to show("lt(longest transcript)" or "lcds(longest CDS)"), default(NULL). 59 | #' @param topN the top number representative transcript to be shown, default(1). 60 | #' @param show.legend whether show color legend, default(FALSE). 61 | #' 62 | #' @import tidyverse 63 | #' @import cowplot 64 | #' @import stats 65 | #' 66 | #' @return A ggplot object. 67 | #' 68 | #' @export 69 | #' @examples 70 | #' ############################################################## 71 | #' # test function 72 | #' 73 | #' ######################################################## 74 | #' # load data 75 | #' data(gtf) 76 | #' 77 | #' # non-coding gene 78 | #' trancriptVis(gtfFile = gtf, 79 | #' gene = 'Xist') 80 | #' 81 | #' # coding gene 82 | #' trancriptVis(gtfFile = gtf, 83 | #' gene = 'Nanog') 84 | #' 85 | #' # change fill color 86 | #' trancriptVis(gtfFile = gtf, 87 | #' gene = 'Nanog', 88 | #' exonFill = '#CCFF00') 89 | #' 90 | #' # change inrton line size 91 | #' trancriptVis(gtfFile = gtf, 92 | #' gene = 'Nanog', 93 | #' intronSize = 1) 94 | #' 95 | #' # change label size,color and position 96 | #' trancriptVis(gtfFile = gtf, 97 | #' gene = 'Nanog', 98 | #' textLabelSize = 4, 99 | #' textLabelColor = 'red', 100 | #' relTextDist = 0) 101 | #' 102 | #' # aes by gene name 103 | #' trancriptVis(gtfFile = gtf, 104 | #' gene = 'Nanog', 105 | #' textLabel = 'gene_name') 106 | #' 107 | #' # color aes by transcript 108 | #' trancriptVis(gtfFile = gtf, 109 | #' gene = 'Tpx2', 110 | #' exonColorBy = 'transcript_id') 111 | #' 112 | #' # change arrow color and type 113 | #' trancriptVis(gtfFile = gtf, 114 | #' gene = 'Nanog', 115 | #' arrowCol = 'orange', 116 | #' arrowType = 'closed') 117 | #' 118 | #' # no intron gene and add arrow color 119 | #' # change arrow color and type 120 | #' trancriptVis(gtfFile = gtf, 121 | #' gene = 'Jun', 122 | #' textLabel = 'gene_name', 123 | #' arrowCol = 'white', 124 | #' arrowType = 'closed') + 125 | #' theme_void() 126 | #' 127 | #' # add arrow breaks 128 | #' trancriptVis(gtfFile = gtf, 129 | #' gene = 'Nanog', 130 | #' arrowCol = 'orange', 131 | #' arrowType = 'closed', 132 | #' arrowBreak = 0.1) 133 | #' 134 | #' # draw specific transcript 135 | #' p1 <- trancriptVis(gtfFile = gtf, 136 | #' gene = 'Commd7') 137 | #' 138 | #' p2 <- trancriptVis(gtfFile = gtf, 139 | #' gene = 'Commd7', 140 | #' myTranscript = c('ENSMUST00000071852','ENSMUST00000109782')) 141 | #' 142 | #' # combine 143 | #' cowplot::plot_grid(p1,p2,ncol = 2,align = 'hv') 144 | 145 | # global variables 146 | globalVariables(c('end', 'gene_id', 'gene_name','seqnames',".", 147 | 'start', 'strand','transcript_id','transcript_name', 148 | 'type', 'vl_x1' ,'width', 'yPos','.env','cdslen','tlen')) 149 | 150 | # use_package("tidyverse", type = "depends") 151 | 152 | # define function 153 | trancriptVis <- function(gtfFile = NULL, 154 | gene = NULL, 155 | selecType = NULL, 156 | topN = 1, 157 | myTranscript = NULL, 158 | Chr = NULL, 159 | posStart = NULL, 160 | posEnd = NULL, 161 | collapse = FALSE, 162 | exonWidth = 0.3, 163 | relTextDist = 0.3, 164 | intronSize = 0.5, 165 | arrowBreak = 0.15, 166 | exonColorBy = NULL, 167 | show.legend = FALSE, 168 | exonFill = '#333399', 169 | circle = FALSE, 170 | cicStart = pi, 171 | circSegCol = '#333399', 172 | text_only = FALSE, 173 | ylimLow = -10, 174 | openAngle = 0.5, 175 | arrowCol = '#333399', 176 | arrowAngle = 30, 177 | arrowLength = 0.1, 178 | arrowType = 'open', 179 | addNormalArrow = TRUE, 180 | newStyleArrow = FALSE, 181 | absSpecArrowLen = FALSE, 182 | speArrowRelPos = 0, 183 | speArrowRelLen = 0.05, 184 | speArrowStart = -0.15, 185 | speArrowRelHigh = 2, 186 | speArrowLineSize = 0.5, 187 | speArrowCol = 'black', 188 | speArrowAngle = 30, 189 | speArrowLen = 0.1, 190 | speArrowType = "closed", 191 | textLabel = 'transcript_id', 192 | text.pos = "middle", 193 | textLabelSize = 5, 194 | textLabelColor = 'black', 195 | base_size = 14, 196 | marginX = 10, 197 | marginY = 10, 198 | aspect.ratio = NULL, 199 | facetByGene = FALSE, 200 | ncolGene = NULL, 201 | scales = 'free', 202 | strip.position = 'top', 203 | forcePosRel = FALSE, 204 | panel.spacing = 0.3, 205 | revNegStrand = FALSE, 206 | xAxis.info = TRUE, 207 | reverse.y = FALSE){ 208 | ############################################################################## 209 | # test whether with a given specific gene or region 210 | 211 | # select columns 212 | # if("transcript_name" %in% colnames(gtfFile)){ 213 | # sln <- c('seqnames','start','end','width','strand','type','gene_id','gene_name','transcript_id','transcript_name') 214 | # }else{ 215 | # sln <- c('seqnames','start','end','width','strand','type','gene_id','gene_name','transcript_id') 216 | # } 217 | 218 | # load GTF file 219 | if(is.character(gtfFile)){ 220 | gtfFile <- rtracklayer::import(gtfFile,format = "gtf") %>% 221 | data.frame() 222 | }else{ 223 | gtfFile <- gtfFile 224 | } 225 | 226 | # check colnames 227 | if("transcript_name" %in% colnames(gtfFile)){ 228 | if("gene_name" %in% colnames(gtfFile)){ 229 | sln <- c('seqnames','start','end','width','strand','type','gene_id','gene_name','transcript_id','transcript_name') 230 | }else{ 231 | sln <- c('seqnames','start','end','width','strand','type','gene_id','transcript_id','transcript_name') 232 | } 233 | }else{ 234 | if("gene_name" %in% colnames(gtfFile)){ 235 | sln <- c('seqnames','start','end','width','strand','type','gene_id','gene_name','transcript_id') 236 | }else{ 237 | sln <- c('seqnames','start','end','width','strand','type','gene_id','transcript_id') 238 | } 239 | } 240 | 241 | # select data 242 | if(is.null(gene)){ 243 | # filter gene by region 244 | myGene <- gtfFile %>% 245 | dplyr::filter(seqnames == Chr & start >= posStart & end <= posEnd) %>% 246 | dplyr::filter(type != 'gene') %>% 247 | dplyr::select(sln) 248 | }else{ 249 | # use gene_id stands for gene_name 250 | if("gene_name" %in% colnames(gtfFile)){ 251 | # filter gene by gene name 252 | myGene <- gtfFile %>% 253 | dplyr::filter(gene_name %in% .env$gene) %>% 254 | dplyr::filter(type != 'gene') %>% 255 | dplyr::select(sln) 256 | }else{ 257 | # filter gene by gene id 258 | myGene <- gtfFile %>% 259 | dplyr::select(sln) %>% 260 | dplyr::mutate(gene_name = gene_id) %>% 261 | dplyr::filter(gene_name %in% .env$gene) %>% 262 | dplyr::filter(type != 'gene') 263 | } 264 | } 265 | 266 | ############################################################################## 267 | # whether plot specific transcript 268 | if(is.null(myTranscript)){ 269 | myData <- myGene 270 | }else{ 271 | myData <- myGene %>% 272 | dplyr::filter(transcript_id %in% myTranscript) 273 | } 274 | 275 | # whether type column contains "transcript" info 276 | typeInfo <- unique(myData$type) 277 | if("transcript" %in% typeInfo){ 278 | myData <- myData 279 | }else{ 280 | purrr::map_df(unique(myData$transcript_id),function(x){ 281 | tmp <- myData %>% dplyr::filter(transcript_id == x) 282 | tinfo <- tmp[1,] 283 | 284 | # assign start and end 285 | tinfo <- tinfo %>% 286 | dplyr::mutate(start = min(tmp$start), 287 | end = max(tmp$end), 288 | width = abs(max(tmp$end) - min(tmp$start)) + 1, 289 | type = "transcript") 290 | 291 | # combine 292 | tData <- rbind(tinfo,tmp) 293 | return(tData) 294 | }) -> myData 295 | } 296 | 297 | ############################################################################## 298 | # select representive transcript 299 | ############################################################################## 300 | # function 301 | filterRepTrans <- function(data,selecType,topN = 1){ 302 | tg <- data 303 | 304 | # calculate transcript/CDS length 305 | purrr::map_df(unique(tg$transcript_id),function(x){ 306 | tmp <- tg %>% dplyr::filter(transcript_id == x & type == "exon") 307 | tmp2 <- tg %>% dplyr::filter(transcript_id == x & type == "CDS") 308 | tranLength <- data.frame(tid = x,tlen = sum(tmp$width),cdslen = sum(tmp2$width)) 309 | return(tranLength) 310 | }) -> lenInfo 311 | 312 | # choose type 313 | if(selecType == "lt"){ 314 | rankTran <- lenInfo %>% 315 | dplyr::arrange(dplyr::desc(tlen),dplyr::desc(cdslen)) %>% 316 | dplyr::slice_head(n = topN) 317 | return(rankTran$tid) 318 | }else if(selecType == "lcds"){ 319 | rankTran <- lenInfo %>% 320 | dplyr::arrange(dplyr::desc(cdslen),dplyr::desc(tlen)) %>% 321 | dplyr::slice_head(n = topN) 322 | return(rankTran$tid) 323 | }else{ 324 | print("Please choose 'lt' or 'lcds'!") 325 | } 326 | } 327 | 328 | # get rep trans 329 | if(!is.null(selecType)){ 330 | purrr::map_df(unique(myData$gene_id),function(x){ 331 | tmp <- myData %>% dplyr::filter(gene_id == x) 332 | res <- tmp %>% dplyr::filter(transcript_id %in% filterRepTrans(tmp,selecType,topN)) 333 | }) -> myData 334 | 335 | }else{ 336 | myData <- myData 337 | } 338 | 339 | ############################################################################## 340 | 341 | ############################################################################## 342 | # get gene id 343 | gid <- unique(myData$gene_id) 344 | 345 | ############################################################################## 346 | # add y axis position 347 | if(collapse == FALSE){ 348 | # expand gene 349 | purrr::map_df(1:length(gid),function(x){ 350 | tmp <- myData %>% 351 | dplyr::filter(gene_id == gid[x]) 352 | # loop for tid 353 | trans_tmp <- tmp %>% dplyr::filter(type == 'transcript') %>% 354 | dplyr::arrange(width) 355 | 356 | # whether has transcript in gene info 357 | if(nrow(trans_tmp) > 0){ 358 | tid <- unique(trans_tmp$transcript_id) 359 | 360 | # assign y position 361 | purrr::map_df(1:length(tid),function(x){ 362 | tmp1 <- myData %>% 363 | dplyr::filter(transcript_id == tid[x]) %>% 364 | dplyr::mutate(yPos = x) 365 | tmp1$ymin <- ifelse(tmp1$type == 'CDS', 366 | tmp1$yPos - exonWidth/2, 367 | tmp1$yPos - exonWidth/6) 368 | tmp1$ymax <- ifelse(tmp1$type == 'CDS', 369 | tmp1$yPos + exonWidth/2, 370 | tmp1$yPos + exonWidth/6) 371 | return(tmp1) 372 | }) -> exon_ypos 373 | } 374 | # return(exon_ypos) 375 | }) -> mul_exon_ypos 376 | }else{ 377 | # collapse gene 378 | mul_exon_ypos <- myData %>% dplyr::mutate(yPos = 1) 379 | mul_exon_ypos$ymin <- ifelse(mul_exon_ypos$type == 'CDS', 380 | mul_exon_ypos$yPos - exonWidth/2, 381 | mul_exon_ypos$yPos - exonWidth/6) 382 | mul_exon_ypos$ymax <- ifelse(mul_exon_ypos$type == 'CDS', 383 | mul_exon_ypos$yPos + exonWidth/2, 384 | mul_exon_ypos$yPos + exonWidth/6) 385 | } 386 | 387 | ############################################################################## 388 | # whether transform coordinate 389 | if(forcePosRel == TRUE){ 390 | purrr::map_df(gene,function(x){ 391 | tmp <- mul_exon_ypos %>% 392 | dplyr::filter(gene_name == x) 393 | purrr::map_df(unique(tmp$transcript_id),function(t){ 394 | tmp1 <- tmp %>% dplyr::filter(transcript_id == t) %>% 395 | dplyr::arrange(start,end) 396 | 397 | # whether reverse negtive strand 398 | if(revNegStrand == FALSE){ 399 | # start coord 400 | startPos <- min(tmp1$start) 401 | 402 | # add new pos 403 | tmp1 <- tmp1 %>% dplyr::mutate(start = start - startPos, 404 | end = end - startPos) 405 | }else{ 406 | if(unique(tmp1$strand) == '-'){ 407 | # end coord 408 | endPos <- max(tmp1$end) 409 | 410 | # add new pos 411 | tmp1 <- tmp1 %>% dplyr::mutate(start = endPos - start, 412 | end = endPos - end) 413 | }else{ 414 | # start coord 415 | startPos <- min(tmp1$start) 416 | 417 | # add new pos 418 | tmp1 <- tmp1 %>% dplyr::mutate(start = start - startPos, 419 | end = end - startPos) 420 | } 421 | } 422 | return(tmp1) 423 | }) -> relPos_tmp 424 | return(relPos_tmp) 425 | }) -> exonNewPos 426 | }else{ 427 | exonNewPos <- mul_exon_ypos 428 | } 429 | 430 | ############################################################################## 431 | # extarct data 432 | exon <- exonNewPos %>% dplyr::filter(type != 'transcript') 433 | trans <- exonNewPos %>% dplyr::filter(type == 'transcript') 434 | 435 | # add text x/y pos 436 | if(revNegStrand == FALSE){ 437 | # define label position 438 | if(text.pos == "left"){ 439 | text.pos.hjust = 1 440 | trans$textX <- trans$start 441 | trans$textY <- trans$yPos + relTextDist 442 | }else if(text.pos == "right"){ 443 | text.pos.hjust = 0 444 | trans$textX <- trans$end 445 | trans$textY <- trans$yPos + relTextDist 446 | }else{ 447 | text.pos.hjust = 0.5 448 | trans$textX <- ifelse(trans$strand == '+', 449 | trans$start + trans$width/2, 450 | trans$end - trans$width/2) 451 | trans$textY <- trans$yPos + relTextDist 452 | } 453 | }else{ 454 | # define label position 455 | if(text.pos == "left"){ 456 | text.pos.hjust = 1 457 | trans$textX <- trans$start 458 | trans$textY <- trans$yPos + relTextDist 459 | }else if(text.pos == "right"){ 460 | text.pos.hjust = 0 461 | trans$textX <- trans$end 462 | trans$textY <- trans$yPos + relTextDist 463 | }else{ 464 | text.pos.hjust = 0.5 465 | trans$textX <- (trans$start + trans$end)/2 466 | trans$textY <- trans$yPos + relTextDist 467 | } 468 | } 469 | 470 | ############################################################################## 471 | # whether add specific arrow 472 | if(newStyleArrow == FALSE){ 473 | arrow_trans <- trans 474 | }else{ 475 | # whether supply gene or coordinate 476 | if(is.null(gene)){ 477 | gene <- unique(trans$gene_name) 478 | } 479 | 480 | # loop 481 | purrr::map_df(gene,function(gen){ 482 | genTrans <- trans %>% dplyr::filter(gene_name == gen) %>% 483 | dplyr::arrange(dplyr::desc(width)) 484 | 485 | # define longest transcript length 486 | longestWidth = genTrans$width[1] 487 | 488 | # add special arrow 489 | purrr::map_df(genTrans$transcript_id,function(x){ 490 | tmp <- genTrans %>% 491 | dplyr::filter(transcript_id == x) 492 | 493 | # test strand 494 | if(absSpecArrowLen == TRUE){ 495 | # add absolute specArrow 496 | if(tmp$strand == '+'){ 497 | tmp <- tmp %>% dplyr::mutate(vl_x1 = start + speArrowRelPos*width, 498 | vl_x2 = vl_x1 + speArrowRelLen*longestWidth, 499 | vl_y1 = yPos + speArrowStart, 500 | vl_y2 = yPos + speArrowStart*speArrowRelHigh) 501 | }else if(tmp$strand == '-'){ 502 | tmp <- tmp %>% dplyr::mutate(vl_x1 = end - speArrowRelPos*width, 503 | vl_x2 = vl_x1 - speArrowRelLen*longestWidth, 504 | vl_y1 = yPos + speArrowStart, 505 | vl_y2 = yPos + speArrowStart*speArrowRelHigh) 506 | } 507 | }else{ 508 | # add relative specArrow 509 | if(tmp$strand == '+'){ 510 | tmp <- tmp %>% dplyr::mutate(vl_x1 = start + speArrowRelPos*width, 511 | vl_x2 = vl_x1 + speArrowRelLen*width, 512 | vl_y1 = yPos + speArrowStart, 513 | vl_y2 = yPos + speArrowStart*speArrowRelHigh) 514 | }else if(tmp$strand == '-'){ 515 | tmp <- tmp %>% dplyr::mutate(vl_x1 = end - speArrowRelPos*width, 516 | vl_x2 = vl_x1 - speArrowRelLen*width, 517 | vl_y1 = yPos + speArrowStart, 518 | vl_y2 = yPos + speArrowStart*speArrowRelHigh) 519 | } 520 | } 521 | return(tmp) 522 | }) -> arrow_trans1 523 | return(arrow_trans1) 524 | }) -> arrow_trans 525 | } 526 | 527 | # change reversed specArrow direction 528 | if(revNegStrand == FALSE){ 529 | arrow_trans <- arrow_trans 530 | }else{ 531 | arrow_trans$vl_x2 <- abs(arrow_trans$vl_x2) 532 | } 533 | 534 | # strand control arrow direction 535 | arrow_trans$ad <- ifelse(arrow_trans$strand == '+','last','first') 536 | 537 | # arrow breaks 538 | arrow_seq = c(0.05,seq(0,0.95,arrowBreak)[-1],1) 539 | 540 | ############################################################################## 541 | # first layer 542 | if(is.null(exonColorBy)){ 543 | p1 <- ggplot2::ggplot(exon) + 544 | ggplot2::geom_rect(ggplot2::aes_(xmin = ~start,xmax = ~end, 545 | ymin = ~ymin,ymax = ~ymax), 546 | fill = exonFill) 547 | }else{ 548 | p1 <- ggplot2::ggplot(exon) + 549 | ggplot2::geom_rect(ggplot2::aes_(xmin = ~start,xmax = ~end, 550 | ymin = ~ymin,ymax = ~ymax, 551 | fill = ~get(exonColorBy)), 552 | show.legend = show.legend) 553 | } 554 | 555 | ############################################################################## 556 | if(newStyleArrow == FALSE){ 557 | p2 <- p1 558 | }else{ 559 | p2 <- p1 + 560 | # add vertical line 561 | ggplot2::geom_segment(data = arrow_trans, 562 | ggplot2::aes_string(x = "vl_x1",xend = "vl_x1", 563 | y = "vl_y1",yend = "vl_y2"), 564 | color = speArrowCol, 565 | size = speArrowLineSize) + 566 | # add horizotal line and arrow 567 | ggplot2::geom_segment(data = arrow_trans, 568 | ggplot2::aes_string(x = "vl_x1",xend = "vl_x2", 569 | y = "vl_y2",yend = "vl_y2"), 570 | color = speArrowCol, 571 | size = speArrowLineSize, 572 | arrow = ggplot2::arrow(angle = speArrowAngle, 573 | length = ggplot2::unit(speArrowLen, "inches"), 574 | ends = "last", 575 | type = speArrowType)) 576 | } 577 | 578 | 579 | ############################################################################## 580 | # whether facet by gene when gene far away each other or not on same chromosome 581 | if(facetByGene == FALSE){ 582 | # whether draw ploar plot 583 | if(circle == FALSE){ 584 | # add arrow and segment line with geom_arrowsegment 585 | if(addNormalArrow == TRUE){ 586 | p3 <- p2 + 587 | ggarchery::geom_arrowsegment(data = arrow_trans, 588 | ggplot2::aes_(x = ~start,xend = ~end, 589 | y = ~yPos,yend = ~yPos), 590 | color = arrowCol, 591 | size = intronSize, 592 | arrow_positions = arrow_seq, 593 | arrow_fills = rep(arrowCol,length(arrow_seq)), 594 | arrows = list(ggplot2::arrow(angle = arrowAngle, 595 | length = ggplot2::unit(arrowLength, "inches"), 596 | ends = arrow_trans$ad, 597 | type = arrowType))) 598 | }else{ 599 | p3 <- p2 + 600 | ggplot2::geom_segment(data = arrow_trans, 601 | ggplot2::aes_(x = ~start,xend = ~end, 602 | y = ~yPos,yend = ~yPos), 603 | color = arrowCol, 604 | size = intronSize) 605 | } 606 | }else{ 607 | # add arrow and segment line geom_segment 608 | if(addNormalArrow == TRUE){ 609 | p3 <- p2 + 610 | ggplot2::geom_segment(data = arrow_trans, 611 | ggplot2::aes_(x = ~start,xend = ~end, 612 | y = ~yPos,yend = ~yPos), 613 | color = circSegCol, 614 | size = intronSize, 615 | arrow = ggplot2::arrow(angle = arrowAngle, 616 | length = ggplot2::unit(arrowLength, "inches"), 617 | ends = arrow_trans$ad, 618 | type = arrowType)) 619 | }else{ 620 | p3 <- p2 + 621 | ggplot2::geom_segment(data = arrow_trans, 622 | ggplot2::aes_(x = ~start,xend = ~end, 623 | y = ~yPos,yend = ~yPos), 624 | color = circSegCol, 625 | size = intronSize) 626 | } 627 | } 628 | }else{ 629 | # define columns to facet 630 | if(is.null(ncolGene)){ 631 | ncol = length(gene) 632 | }else{ 633 | ncol = ncolGene 634 | } 635 | # facet plot 636 | 637 | # whether draw ploar plot 638 | if(circle == FALSE){ 639 | # add arrow and segment line with geom_arrowsegment 640 | if(addNormalArrow == TRUE){ 641 | # loop add arrow 642 | for (g in gene) { 643 | tmpTrans <- arrow_trans %>% dplyr::filter(gene_name == g) 644 | p2 <- p2 + 645 | ggarchery::geom_arrowsegment(data = tmpTrans, 646 | ggplot2::aes_(x = ~start,xend = ~end, 647 | y = ~yPos,yend = ~yPos), 648 | color = arrowCol, 649 | size = intronSize, 650 | arrow_positions = arrow_seq, 651 | arrow_fills = rep(arrowCol,length(arrow_seq)), 652 | arrows = list(ggplot2::arrow(angle = arrowAngle, 653 | length = ggplot2::unit(arrowLength, "inches"), 654 | ends = tmpTrans$ad, 655 | type = arrowType))) 656 | } 657 | p3_tmp <- p2 658 | }else{ 659 | p3_tmp <- p2 + 660 | ggplot2::geom_segment(data = arrow_trans, 661 | ggplot2::aes_(x = ~start,xend = ~end, 662 | y = ~yPos,yend = ~yPos), 663 | color = arrowCol, 664 | size = intronSize) 665 | } 666 | }else{ 667 | # add arrow and segment line geom_segment 668 | if(addNormalArrow == TRUE){ 669 | # loop add arrow 670 | for (g in gene) { 671 | tmpTrans <- arrow_trans %>% dplyr::filter(gene_name == g) 672 | p2 <- p2 + 673 | ggplot2::geom_segment(data = tmpTrans, 674 | ggplot2::aes_(x = ~start,xend = ~end, 675 | y = ~yPos,yend = ~yPos), 676 | color = circSegCol, 677 | size = intronSize, 678 | arrow = ggplot2::arrow(angle = arrowAngle, 679 | length = ggplot2::unit(arrowLength, "inches"), 680 | ends = tmpTrans$ad, 681 | type = arrowType)) 682 | } 683 | p3_tmp <- p2 684 | }else{ 685 | p3_tmp <- p2 + 686 | ggplot2::geom_segment(data = arrow_trans, 687 | ggplot2::aes_(x = ~start,xend = ~end, 688 | y = ~yPos,yend = ~yPos), 689 | color = circSegCol, 690 | size = intronSize) 691 | } 692 | } 693 | 694 | # facet 695 | p3 <- p3_tmp + 696 | ggplot2::facet_wrap(facets = "gene_name", 697 | scales = scales, 698 | ncol = ncol, 699 | strip.position = strip.position) 700 | } 701 | 702 | ############################################################################## 703 | # add text label 704 | if(circle == FALSE){ 705 | # geom_text 706 | p4 <- p3 + 707 | ggplot2::geom_text(data = arrow_trans, 708 | ggplot2::aes_string(x = 'textX',y = 'textY', 709 | label = textLabel), 710 | size = textLabelSize, 711 | color = textLabelColor, 712 | hjust = text.pos.hjust, 713 | check_overlap = T) + 714 | ggplot2::theme_bw(base_size = base_size) + 715 | ggplot2::theme(panel.grid = ggplot2::element_blank(), 716 | axis.ticks.y = ggplot2::element_blank(), 717 | axis.text.y = ggplot2::element_blank(), 718 | axis.title.y = ggplot2::element_blank(), 719 | plot.margin = ggplot2::margin(t = marginY,r = marginX,b = marginY ,l = marginX)) + 720 | ggplot2::xlab('Positions on genome') 721 | }else{ 722 | # geom_textpath 723 | p4 <- p3 + 724 | geomtextpath::geom_textpath(data = arrow_trans, 725 | ggplot2::aes_string(x = "textX",y = "textY",label = textLabel), 726 | size = textLabelSize, 727 | color = textLabelColor, 728 | hjust = text.pos.hjust, 729 | text_only = text_only) + 730 | ggplot2::coord_polar(theta = 'x',start = cicStart) + 731 | ggplot2::scale_y_continuous(limits = c(ylimLow,nrow(arrow_trans) + 1)) + 732 | ggplot2::scale_x_continuous(expand = c(0,openAngle*max(trans$width))) + 733 | ggplot2::theme_void() 734 | } 735 | 736 | ############################################################################## 737 | # add ratio 738 | if(is.null(aspect.ratio)){ 739 | p5 <- p4 740 | }else{ 741 | p5 <- p4 + 742 | ggplot2::theme(aspect.ratio = aspect.ratio) 743 | } 744 | 745 | ############################################################################## 746 | # facet background 747 | if(facetByGene == TRUE){ 748 | p6 <- p5 + 749 | ggplot2::theme(strip.text.x = ggplot2::element_text(size = base_size + 2), 750 | strip.background = ggplot2::element_rect(fill = 'grey90'), 751 | panel.spacing = ggplot2::unit(panel.spacing,'cm')) 752 | }else{ 753 | p6 <- p5 754 | } 755 | 756 | ############################################################################## 757 | # xlabel 758 | if(forcePosRel == TRUE){ 759 | p7 <- p6 + 760 | ggplot2::xlab('Positions on genome') 761 | }else{ 762 | p7 <- p6 + 763 | ggplot2::xlab('Relative position to start/end') 764 | } 765 | 766 | # X aixs text and ticks 767 | if(xAxis.info == F){ 768 | p8 <- p7 + 769 | ggplot2::theme(axis.ticks.x = ggplot2::element_blank(), 770 | axis.text.x = ggplot2::element_blank()) 771 | }else{ 772 | p8 <- p7 773 | } 774 | 775 | # whether reverse y axis 776 | if(reverse.y == TRUE){ 777 | p9 <- p8 + 778 | ggplot2::scale_y_reverse() 779 | }else{ 780 | p9 <- p8 781 | } 782 | return(p9) 783 | } 784 | 785 | ############################### 786 | #' This is a test data for this package 787 | #' test data describtion 788 | #' 789 | #' @name gtf 790 | #' @docType data 791 | #' @author Junjun Lao 792 | "gtf" 793 | -------------------------------------------------------------------------------- /R/utils-pipe.R: -------------------------------------------------------------------------------- 1 | #' Pipe operator 2 | #' 3 | #' See \code{magrittr::\link[magrittr:pipe]{\%>\%}} for details. 4 | #' 5 | #' @name %>% 6 | #' @rdname pipe 7 | #' @keywords internal 8 | #' @export 9 | #' @importFrom magrittr %>% 10 | #' @usage lhs \%>\% rhs 11 | #' @param lhs A value or the magrittr placeholder. 12 | #' @param rhs A function call using the magrittr semantics. 13 | #' @return The result of calling `rhs(lhs)`. 14 | NULL 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # transPlotR 3 | 4 | 5 | 6 | There are some packages to plot gene structures, for example [**ggbio**](https://bioconductor.org/packages/release/bioc/html/ggbio.html), [**ggtranscript**](https://github.com/dzhang32/ggtranscript)... But there are still some limitations for them. The **IGV** software provides a good visualization for gene multiple isoforms. If you want to plot **protein-coding** or **non-coding genes**, it seems a little bit difficult for you to draw with a lot of codes. Here I developed a small R package named [**transPlotR**](https://github.com/junjunlab/transPlotR) which makes gene structure visualization much easier. You can provide a little parameters to **trancriptVis** to make a plot with your own **GTF** files. 7 | 8 | Besides, **bedVis** and **trackVis** functions can be used to visualize bed and bigwig files with combing **transcriptVis** function. All these functions will let you produce a nice track plot for some Chip-seq, ATAC-seq and m6A-seq datasets. 9 | 10 | 11 | 12 | ## Installation 13 | 14 | You can install the development version of transPlotR like so: 15 | 16 | ``` r 17 | # install.packages("devtools") 18 | devtools::install_github("junjunlab/transPlotR") 19 | ``` 20 | 21 | ## Requirement 22 | 23 | > - **rtracklayer**, **ggarchery**, **geomtextpath**, **ggnewscale**, **purrr** 24 | 25 | ## Citation 26 | 27 | > Jun Z (2022). *transPlotR: An elegant package to visualize gene structures.* https://github.com/junjunlab/transPlotR, https://github.com/junjunlab/transPlotR/wiki/TransPlot-documentation 28 | 29 | ## Figure 30 | 31 | ![image](https://user-images.githubusercontent.com/64965509/188102988-fd13646d-46d8-4f47-9921-990815f8d376.png) 32 | 33 | ## More examples 34 | 35 | > - **https://github.com/junjunlab/transPlotR/wiki/TransPlot-documentation** 36 | > - **https://github.com/junjunlab/transPlotR/wiki/TransPlot-0.0.3-documentation** 37 | 38 | ## Related blogs 39 | 40 | > - [**transPlotR 优雅的绘制基因转录本结构**](https://mp.weixin.qq.com/s?__biz=MzkyMTI1MTYxNA==&mid=2247501734&idx=1&sn=d03029b38bfbeda067109bc477bdffa7&chksm=c184fdd7f6f374c1edb12bec9e741834f8adb59ed336730438dc275794520f63f0889e91d2aa&token=503374955&lang=zh_CN#rd) 41 | > - [**trancriptVis 的左膀右臂: bedVis 和 trackVis**](https://mp.weixin.qq.com/s?__biz=MzkyMTI1MTYxNA==&mid=2247505845&idx=1&sn=837625700fb274c83d16de7102f6ed55&chksm=c184edc4f6f364d25de9376ac41d9582f357f11e56a3d366d381c04fa9a5592d5f223b575814&token=503374955&lang=zh_CN#rd) 42 | > - [**linkVis 可视化基因位点连接**](https://mp.weixin.qq.com/s?__biz=MzkyMTI1MTYxNA==&mid=2247505905&idx=1&sn=9ec3ccfc72d1f4889596099fdb1ba67f&chksm=c184ed80f6f3649603c3a6a21ff1e324f028b34d21064b5fd9f4a38c1dca4578a61d6698c582&token=503374955&lang=zh_CN#rd) 43 | > - [**trackVis 给 track 加个背景色**](https://mp.weixin.qq.com/s?__biz=MzkyMTI1MTYxNA==&mid=2247505942&idx=1&sn=41c5ada6cca8e550f54e2517ec82889e&chksm=c184e267f6f36b711ba10c8e4c4e547e5a34f901ad07c50150e27b88a14d715bd9184b728be9&token=503374955&lang=zh_CN#rd) 44 | > - [**trancriptVis 可视化 NCBI 的 GTF 文件**](https://mp.weixin.qq.com/s?__biz=MzkyMTI1MTYxNA==&mid=2247506038&idx=1&sn=3799e20c5f29989bf60ab55b9ca02420&chksm=c184e207f6f36b1171c423da6caf9e7f299d16b5273d3b26482b8662b20b43a004e6324ee878&token=503374955&lang=zh_CN#rd) 45 | > - [**trackVis 在图里添加样本标签**](https://mp.weixin.qq.com/s?__biz=MzkyMTI1MTYxNA==&mid=2247506082&idx=1&sn=3db6fded3ae1c35ad1750f538419ddba&chksm=c184e2d3f6f36bc5533a7343f47150954fe4ac478ba3b61aee466b8286c2869678b6d10ccbcb&token=503374955&lang=zh_CN#rd) 46 | > - [**trackVis 给样本加个分组注释**](https://mp.weixin.qq.com/s?__biz=MzkyMTI1MTYxNA==&mid=2247506176&idx=1&sn=1dad4695f275d68104db5b6929bffebf&chksm=c184e371f6f36a67108993c2baaf442d001e00622216073f8ee2d7d8211a585292352e54f836&token=503374955&lang=zh_CN#rd) 47 | > - [**trackVis 居然可以自由修改 Y 轴范围**](https://mp.weixin.qq.com/s?__biz=MzkyMTI1MTYxNA==&mid=2247506218&idx=1&sn=a3f9b773e0b6a764732198866fb23f3e&chksm=c184e35bf6f36a4de62754ac01c901c384859a3fb675a2bec84684daddb3c64a7f429e7bb63e&token=503374955&lang=zh_CN#rd) 48 | > - [**trackVis 修改样本顺序和分组顺序**](https://mp.weixin.qq.com/s?__biz=MzkyMTI1MTYxNA==&mid=2247506440&idx=1&sn=7dd1e5cdaf52f7bba1716d5e9c06b08c&chksm=c184e079f6f3696f61840142474ff2257a4550dd0cf1792cbf479fda4c45c71fbd1d651b2c11&token=503374955&lang=zh_CN#rd) 49 | -------------------------------------------------------------------------------- /data/gtf.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/junjunlab/transPlotR/f77b0611046e97f7bc1b757b8d2cfbdffe862bf1/data/gtf.rda -------------------------------------------------------------------------------- /man/bedVis.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/bedVis.R 3 | \name{bedVis} 4 | \alias{bedVis} 5 | \title{bedVis} 6 | \arguments{ 7 | \item{bdFile}{the bed file path, default(NULL).} 8 | 9 | \item{chr}{the chromesome of peak, default(NULL).} 10 | 11 | \item{region.min}{the peak start coordinate, default(NULL).} 12 | 13 | \item{region.max}{the peak end coordinate, default(NULL).} 14 | 15 | \item{track.width}{track width, default(0.1).} 16 | 17 | \item{collapse}{whether collapse the track, default(FALSE).} 18 | 19 | \item{fill}{track fill colors, default(NULL).} 20 | 21 | \item{show.legend}{whether show fill color legend, default(TRUE).} 22 | 23 | \item{add.label}{whether add peak name, default(FALSE).} 24 | 25 | \item{label.column}{the peak name column name, default(NULL).} 26 | 27 | \item{label.vjsut}{the peak label vjust, default(0.1).} 28 | } 29 | \value{ 30 | a ggplot object. 31 | } 32 | \description{ 33 | visualize peaks(bed files). 34 | } 35 | \author{ 36 | JunZhang 37 | } 38 | -------------------------------------------------------------------------------- /man/calcuRotatedCoord.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/calcuRotatedCoord.R 3 | \name{calcuRotatedCoord} 4 | \alias{calcuRotatedCoord} 5 | \title{calcuRotatedCoord} 6 | \arguments{ 7 | \item{data}{data.frame} 8 | 9 | \item{theta}{rotate degree, default(45).} 10 | 11 | \item{workers}{how many workers for parallel calculation, default(1).} 12 | 13 | \item{rx}{x variable name, default(NULL).} 14 | 15 | \item{ry}{y variable name, default(NULL).} 16 | } 17 | \value{ 18 | a data.frame 19 | } 20 | \description{ 21 | calculate the rotated rectangle coordinate with specified degree. 22 | } 23 | \author{ 24 | JunZhang 25 | } 26 | -------------------------------------------------------------------------------- /man/gtf.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/trancriptVis.R 3 | \docType{data} 4 | \name{gtf} 5 | \alias{gtf} 6 | \title{This is a test data for this package 7 | test data describtion} 8 | \format{ 9 | An object of class \code{data.frame} with 1987 rows and 31 columns. 10 | } 11 | \usage{ 12 | gtf 13 | } 14 | \description{ 15 | This is a test data for this package 16 | test data describtion 17 | } 18 | \author{ 19 | Junjun Lao 20 | } 21 | \keyword{datasets} 22 | -------------------------------------------------------------------------------- /man/linkVis.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/linkVis.R 3 | \name{linkVis} 4 | \alias{linkVis} 5 | \title{linkVis} 6 | \usage{ 7 | linkVis( 8 | linkData = NULL, 9 | start = NULL, 10 | end = NULL, 11 | group = NULL, 12 | base_size = 14, 13 | link.aescolor = NULL, 14 | link.color = NULL, 15 | line.size = 0.5, 16 | curvature = 0.5, 17 | yshift = 0.1, 18 | legend.title = "", 19 | facet = TRUE, 20 | facet.placement = "outside", 21 | facet.fill = "grey90", 22 | facet.color = "black", 23 | facet.text.angle = 90, 24 | facet.text.size = 14, 25 | xAixs.info = TRUE 26 | ) 27 | } 28 | \arguments{ 29 | \item{linkData}{the link data with data.frame format, default(NULL).} 30 | 31 | \item{start}{link start position, default(NULL).} 32 | 33 | \item{end}{link end position, default(NULL).} 34 | 35 | \item{group}{facet group variable name, default(NULL).} 36 | 37 | \item{base_size}{theme base_size, default(14).} 38 | 39 | \item{link.aescolor}{link line color or mapping variable name, default(NULL).} 40 | 41 | \item{link.color}{colors to change the link line colors when "link.aescolor" is a mapping variable, default(NULL).} 42 | 43 | \item{line.size}{link line size, default(0.5).} 44 | 45 | \item{curvature}{the link line curvature, default(0.5).} 46 | 47 | \item{yshift}{the space upper the link line, default(0.1).} 48 | 49 | \item{legend.title}{the legend title, default("").} 50 | 51 | \item{facet}{whether show the plot with facet plot, default(TRUE).} 52 | 53 | \item{facet.placement}{the facet label placement, default("outside").} 54 | 55 | \item{facet.fill}{facet rectangle fill color, default("grey90").} 56 | 57 | \item{facet.color}{facet rectangle border color, default("black").} 58 | 59 | \item{facet.text.angle}{facet text angle, default(90).} 60 | 61 | \item{facet.text.size}{facet text size, default(14).} 62 | 63 | \item{xAixs.info}{whether remove X axis info, default(FASLE).} 64 | } 65 | \value{ 66 | a ggplot object. 67 | } 68 | \description{ 69 | visualize the coordinate relation like chromtin accessbility or peak sites correlation. 70 | } 71 | \author{ 72 | JunZhang 73 | } 74 | -------------------------------------------------------------------------------- /man/loadBigWig.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/loadBigWig.R 3 | \name{loadBigWig} 4 | \alias{loadBigWig} 5 | \title{loadBigWig} 6 | \usage{ 7 | loadBigWig(bwFile = NULL) 8 | } 9 | \arguments{ 10 | \item{bwFile}{the path of bigwig files, default(NULL). bigwig files should end with ".bw" or ".bigwig" and directory should not be named "bw" or"bigwig".} 11 | } 12 | \value{ 13 | a data.frame 14 | } 15 | \description{ 16 | read bigwig files. 17 | } 18 | \author{ 19 | JunZhang 20 | } 21 | -------------------------------------------------------------------------------- /man/pipe.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/utils-pipe.R 3 | \name{\%>\%} 4 | \alias{\%>\%} 5 | \title{Pipe operator} 6 | \usage{ 7 | lhs \%>\% rhs 8 | } 9 | \arguments{ 10 | \item{lhs}{A value or the magrittr placeholder.} 11 | 12 | \item{rhs}{A function call using the magrittr semantics.} 13 | } 14 | \value{ 15 | The result of calling \code{rhs(lhs)}. 16 | } 17 | \description{ 18 | See \code{magrittr::\link[magrittr:pipe]{\%>\%}} for details. 19 | } 20 | \keyword{internal} 21 | -------------------------------------------------------------------------------- /man/trackVis.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/trackVis.R 3 | \name{trackVis} 4 | \alias{trackVis} 5 | \title{trackVis} 6 | \arguments{ 7 | \item{bWData}{the data.frame bigwig data, default(NULL).} 8 | 9 | \item{gtf.file}{whether supply gtf annotation file, default(NULL).} 10 | 11 | \item{gene.name}{the gene name to be choosed for visualization, default(NULL).} 12 | 13 | \item{chr}{chr the chromesome of peak, default(NULL).} 14 | 15 | \item{region.min}{the start coordinate, default(NULL).} 16 | 17 | \item{region.max}{the end coordinate, default(NULL).} 18 | 19 | \item{show.legend}{whether show color legend, default(FALSE).} 20 | 21 | \item{legend.position}{the legend position, default("right").} 22 | 23 | \item{color}{the track color, default(NULL).} 24 | 25 | \item{extend.up}{extend for upstream of start site, default(3000).} 26 | 27 | \item{extend.dn}{extend for downstream of start site, default(3000).} 28 | 29 | \item{base_size}{theme base size, default(14).} 30 | 31 | \item{label.angle}{the facet label angle, default(0).} 32 | 33 | \item{label.face}{the facet label face, default("bold").} 34 | 35 | \item{space.y}{the facet panel space, default(0.5).} 36 | 37 | \item{sample.order}{the sample order to be plotted in graph, default(NULL).} 38 | 39 | \item{sampleName.dist}{the facet label distance from Y axis, default(0.4).} 40 | 41 | \item{sampleName.hjust}{the facet label hjust, default(1).} 42 | 43 | \item{sampleName.vjust}{the facet label vjust, default(0.5).} 44 | 45 | \item{xAxis.info}{whether retain X axis info, default(TRUE).} 46 | 47 | \item{yAxis.info}{whether retain Y axis info, default(TRUE).} 48 | 49 | \item{ticks.y.len}{the y axis ticks length, default(0.3).} 50 | 51 | \item{theme}{plot theme, "bw" or "classic", default("classic").} 52 | 53 | \item{scales}{the facet scales settings, default("fixed").} 54 | 55 | \item{ncol}{the columns to be arranged, default(1).} 56 | 57 | \item{mark.region}{whether highlight regions in plot, default(FALSE).} 58 | 59 | \item{mark.col}{the colors of marked regions, default(NULL).} 60 | 61 | \item{mark.alpha}{the color alpha of marked regions, default(0.5).} 62 | 63 | \item{new.yaxis}{whether add new style Y axis, default(FALSE).} 64 | 65 | \item{pos.ratio}{the new style Y axis relative position, default(c(0.01,0.8)).} 66 | 67 | \item{yinfo.text.size}{the new style Y axis text size, default(5).} 68 | 69 | \item{back.color}{whether add panel background color, default(FALSE).} 70 | 71 | \item{back.color.alpha}{panel background color alpha, default(0.15).} 72 | 73 | \item{y.max}{the ylim, default(NULL).} 74 | 75 | \item{new.label}{whether add label in plot, default(FALSE).} 76 | 77 | \item{label.color}{the label color, default(NULL).} 78 | 79 | \item{pos.label.ratio}{the new label relative position, default(c(0.99,0.8)).} 80 | 81 | \item{label.text.size}{the new label text size, default(5).} 82 | 83 | \item{label.hjust}{the new label text hjust, default(1).} 84 | 85 | \item{yinfo.hjust}{the new style Y axis text hjust, default(0).} 86 | 87 | \item{facetGroup}{the annotation for samples, default(NULL).} 88 | 89 | \item{annoLine.size}{the annotation line size, default(1).} 90 | 91 | \item{line.arrow}{the annotation line arrow, default(NULL).} 92 | } 93 | \value{ 94 | a ggplot object. 95 | } 96 | \description{ 97 | visualize bigwig files. 98 | } 99 | \author{ 100 | JunZhang 101 | } 102 | -------------------------------------------------------------------------------- /man/trancriptVis.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/trancriptVis.R 3 | \name{trancriptVis} 4 | \alias{trancriptVis} 5 | \title{trancriptVis} 6 | \arguments{ 7 | \item{gtfFile}{GTF file.} 8 | 9 | \item{gene}{Target gene to plot.} 10 | 11 | \item{myTranscript}{Specify which transcripts to plot use transcipt id.} 12 | 13 | \item{Chr}{Chromosome number.} 14 | 15 | \item{posStart}{Region start position on genome.} 16 | 17 | \item{posEnd}{Region end position on genome.} 18 | 19 | \item{collapse}{Whether to collapse multiple transcripts into one, default(FALSE).} 20 | 21 | \item{exonWidth}{Exon width to plot, default(0.3).} 22 | 23 | \item{relTextDist}{Transcripts name or gene name relative to exon, default(0.3).} 24 | 25 | \item{intronSize}{Intron line size, default(0.5).} 26 | 27 | \item{arrowBreak}{How many gap distance to draw arrows, the smaller the more arrows, default(0.15).} 28 | 29 | \item{exonColorBy}{Whether color group by "transcript_id" or "gene_name", default(NULL).} 30 | 31 | \item{exonFill}{Exon fill color, default('#333399').} 32 | 33 | \item{circle}{Whether make plot into a circle plot, default(FALSE).} 34 | 35 | \item{cicStart}{Circle plot start position, default(pi).} 36 | 37 | \item{circSegCol}{Circle sgement color, default('#333399').} 38 | 39 | \item{text_only}{When circle plot labeled by gene name, whether remove the line connected with gene name, default(FALSE).} 40 | 41 | \item{ylimLow}{The Y axis lower limitation of Circle plot, default(-10).} 42 | 43 | \item{openAngle}{The gap of the circle plot, default(0.5).} 44 | 45 | \item{arrowCol}{Normal arrow color, default('#333399').} 46 | 47 | \item{arrowAngle}{Normal arrow angle, default(30).} 48 | 49 | \item{arrowLength}{Normal arrow length, default(0.1).} 50 | 51 | \item{arrowType}{Normal arrow type, default('open').} 52 | 53 | \item{addNormalArrow}{Whether add normal arrow on plot, default(TRUE).} 54 | 55 | \item{newStyleArrow}{Whether add new style arrow on plot, default(FALSE).} 56 | 57 | \item{absSpecArrowLen}{Whether make new style arrow length to be relative to each transcript length or absolute length to the longest transcript, default(FALSE).} 58 | 59 | \item{speArrowRelPos}{The relative position to the transcript on horizontal direction of new style arrow, default(0).} 60 | 61 | \item{speArrowRelLen}{The relative length to the transcript length of new style arrow, default(0.05).} 62 | 63 | \item{speArrowStart}{The new style arrow start position on the vertical direction, default(-0.15).} 64 | 65 | \item{speArrowRelHigh}{The relative height of new style arrow to the vertical length, default(2).} 66 | 67 | \item{speArrowLineSize}{The new style arrow line size, default(0.5).} 68 | 69 | \item{speArrowCol}{The new style arrow line color, default('black').} 70 | 71 | \item{speArrowAngle}{The new style arrow angle, default(30).} 72 | 73 | \item{speArrowLen}{The new style arrow length, default(0.1).} 74 | 75 | \item{speArrowType}{The new style arrow type, default('closed').} 76 | 77 | \item{textLabel}{The text label aesthetic mappings, default('transcript_id').} 78 | 79 | \item{textLabelSize}{The text label size, default(5).} 80 | 81 | \item{textLabelColor}{The text label color, default('black').} 82 | 83 | \item{base_size}{Theme basesize, default(14).} 84 | 85 | \item{marginX}{Plot left and right margins, default(0.2).} 86 | 87 | \item{marginY}{Plot top and bottomn margins, default(0.2).} 88 | 89 | \item{aspect.ratio}{Plot ratio, default(NULL).} 90 | 91 | \item{facetByGene}{Whether facet by gene to plot, this useful for your genes which are far away from each other or not located on the same chromosome, default(FALSE).} 92 | 93 | \item{ncolGene}{The column numbers to plot, default(NULL).} 94 | 95 | \item{scales}{Facet plot scales, same as "facet_wrap" function, default('free').} 96 | 97 | \item{strip.position}{Facet plot strip.position, same as "facet_wrap" function, default('top').} 98 | 99 | \item{forcePosRel}{Whether force the genome coordinate to relative position to transcript start/end position, default('FALSE').} 100 | 101 | \item{panel.spacing}{Facet plot panel space, default(0.3).} 102 | 103 | \item{revNegStrand}{Whether reverse the negtive strand when set "forcePosRel=TRUE", default('FALSE').} 104 | 105 | \item{xAxis.info}{Whether retain X axis ticks and text, default(TRUE).} 106 | 107 | \item{reverse.y}{whether reverse the Y axis, default(FALSE).} 108 | 109 | \item{text.pos}{the label position(left/right), default(middle).} 110 | 111 | \item{selecType}{choose the representative transcript to show("lt(longest transcript)" or "lcds(longest CDS)"), default(NULL).} 112 | 113 | \item{topN}{the top number representative transcript to be shown, default(1).} 114 | 115 | \item{show.legend}{whether show color legend, default(FALSE).} 116 | } 117 | \value{ 118 | A ggplot object. 119 | } 120 | \description{ 121 | This package is to visualize gene diffrent isoforms. 122 | } 123 | \examples{ 124 | ############################################################## 125 | # test function 126 | 127 | ######################################################## 128 | # load data 129 | data(gtf) 130 | 131 | # non-coding gene 132 | trancriptVis(gtfFile = gtf, 133 | gene = 'Xist') 134 | 135 | # coding gene 136 | trancriptVis(gtfFile = gtf, 137 | gene = 'Nanog') 138 | 139 | # change fill color 140 | trancriptVis(gtfFile = gtf, 141 | gene = 'Nanog', 142 | exonFill = '#CCFF00') 143 | 144 | # change inrton line size 145 | trancriptVis(gtfFile = gtf, 146 | gene = 'Nanog', 147 | intronSize = 1) 148 | 149 | # change label size,color and position 150 | trancriptVis(gtfFile = gtf, 151 | gene = 'Nanog', 152 | textLabelSize = 4, 153 | textLabelColor = 'red', 154 | relTextDist = 0) 155 | 156 | # aes by gene name 157 | trancriptVis(gtfFile = gtf, 158 | gene = 'Nanog', 159 | textLabel = 'gene_name') 160 | 161 | # color aes by transcript 162 | trancriptVis(gtfFile = gtf, 163 | gene = 'Tpx2', 164 | exonColorBy = 'transcript_id') 165 | 166 | # change arrow color and type 167 | trancriptVis(gtfFile = gtf, 168 | gene = 'Nanog', 169 | arrowCol = 'orange', 170 | arrowType = 'closed') 171 | 172 | # no intron gene and add arrow color 173 | # change arrow color and type 174 | trancriptVis(gtfFile = gtf, 175 | gene = 'Jun', 176 | textLabel = 'gene_name', 177 | arrowCol = 'white', 178 | arrowType = 'closed') + 179 | theme_void() 180 | 181 | # add arrow breaks 182 | trancriptVis(gtfFile = gtf, 183 | gene = 'Nanog', 184 | arrowCol = 'orange', 185 | arrowType = 'closed', 186 | arrowBreak = 0.1) 187 | 188 | # draw specific transcript 189 | p1 <- trancriptVis(gtfFile = gtf, 190 | gene = 'Commd7') 191 | 192 | p2 <- trancriptVis(gtfFile = gtf, 193 | gene = 'Commd7', 194 | myTranscript = c('ENSMUST00000071852','ENSMUST00000109782')) 195 | 196 | # combine 197 | cowplot::plot_grid(p1,p2,ncol = 2,align = 'hv') 198 | } 199 | \author{ 200 | JunZhang 201 | } 202 | -------------------------------------------------------------------------------- /man/tranplotR-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/junjunlab/transPlotR/f77b0611046e97f7bc1b757b8d2cfbdffe862bf1/man/tranplotR-logo.png -------------------------------------------------------------------------------- /man/tranplotR-logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 8 | 633 | 634 | 635 | 636 | 637 | 638 | 639 | 640 | -------------------------------------------------------------------------------- /transPlotR.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: No 4 | SaveWorkspace: No 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: UTF-8 11 | 12 | RnwWeave: Sweave 13 | LaTeX: pdfLaTeX 14 | 15 | AutoAppendNewline: Yes 16 | StripTrailingWhitespace: Yes 17 | LineEndingConversion: Posix 18 | 19 | BuildType: Package 20 | PackageUseDevtools: Yes 21 | PackageInstallArgs: --no-multiarch --with-keep.source 22 | PackageRoxygenize: rd,collate,namespace 23 | --------------------------------------------------------------------------------