Los Circos plot son representaciones circulares originalmente concebidas para representar información genómica (aunque se pueden representar otras cosas). La estructura general puede verse en el siguiente gráfico.
En la parte más externa del gráfico está representado en forma de ideograma la estructura cromosómica del genoma. En las partes más internas se representa diferentes tipos de información (texto, puntos, histogramas…) que está mapeada sobre el genoma, es decir, es información que está localizada “espacialmente” en el mismo usando coordenadas genómicas. A cada una de estas representaciones las llamamos tracks. Por último, en la región más interna se pueden representar relaciones entre diferentes coordenadas genómicas mediante links.
En R hay diferentes paquetes para hacer estas representaciones. La extensión de ggplot2, ggbio es quizás el más potente, pero también el más complejo. En esta introducción veremos RCircos, que es más sencillo.
En primer lugar instalamos y cargamos el paquete RCircos
require(RCircos)
## Loading required package: RCircos
El propio paquete tiene una vignette en la cual nos hemos basado para hacer este tutorial.
Un gráfico Circos empiezan con un ideograma del mapa cromosómico de la especie en cuestión: RCircos viene con ideogramas cromosómicos para tres especies: humano, ratón y rata. Pueden cargarse usando la función de R data(). Carguemos y veamos el de humano:
data(UCSC.HG19.Human.CytoBandIdeogram)
head(UCSC.HG19.Human.CytoBandIdeogram)
## Chromosome ChromStart ChromEnd Band Stain
## 1 chr1 0 2300000 p36.33 gneg
## 2 chr1 2300000 5400000 p36.32 gpos25
## 3 chr1 5400000 7200000 p36.31 gneg
## 4 chr1 7200000 9200000 p36.23 gpos25
## 5 chr1 9200000 12700000 p36.22 gneg
## 6 chr1 12700000 16200000 p36.21 gpos50
str(UCSC.HG19.Human.CytoBandIdeogram)
## 'data.frame': 862 obs. of 5 variables:
## $ Chromosome: Factor w/ 24 levels "chr1","chr10",..: 1 1 1 1 1 1 1 1 1 1 ...
## $ ChromStart: int 0 2300000 5400000 7200000 9200000 12700000 16200000 20400000 23900000 28000000 ...
## $ ChromEnd : int 2300000 5400000 7200000 9200000 12700000 16200000 20400000 23900000 28000000 30200000 ...
## $ Band : Factor w/ 259 levels "p11","p11.1",..: 97 96 95 94 93 92 91 90 89 88 ...
## $ Stain : Factor w/ 8 levels "acen","gneg",..: 2 4 2 4 2 5 2 4 2 4 ...
Vemos que el objeto es simplemente un data.frame que contiene la información citogenética a representar.
Los de ratón y rata son, respectivamente, UCSC.Mouse.GRCm38.CytoBandIdeogram y UCSC.Baylor.3.4.Rat.cytoBandIdeogram.
Una vez cargado el ideograma, hay que inicializar los componentes esenciales de RCircos
chr.exclude <- NULL
cyto.info <- UCSC.HG19.Human.CytoBandIdeogram
tracks.inside <- 10
tracks.outside <- 0
RCircos.Set.Core.Components(cyto.info, chr.exclude,
tracks.inside, tracks.outside)
Los argumentos son bastante autoexplicativos. En chr.exclude debemos incluir aquellos cromosomas que NO queremos que aparezcan en la representación (el x "chrX" y el Y "chrY" suelen ser los candidatos habituales a excluir)
El ideograma cromosómico a utilizar se explicita en cyto.info mientras que tracks.inside y tracks.outside es el número de tracks a utilizar en el interior y el exterior del ideograma, respectivamente.
Una vez establecidos los componentes esenciales de RCircos podemos hacer una primera representación del ideograma. Aquí es importante tener en cuenta que RCircos no tiene control de los devices gráficos de R. Es decir, debemos trabajar con él dentro del device. Si no especificamos uno, utilizará la salida gŕafica estándar por pantalla. Ahora bien, los Circos plot pueden ser bastante pesados y eso puede dar problemas con Rstudio. Si queremos que la salida sea a un fichero pdf, por ejemplo, habría que abrir dicho device previamente con pdf() y cerrarlo al final con dev.off()
RCircos.Set.Plot.Area()
RCircos.Chromosome.Ideogram.Plot()
Con esto representamos únicamente el ideograma cromosómico. El primer comando prepara (“limpia”, por así decirlo) el área a representar. Siempre que queramos empezar un RCircos de nuevo hay que utilizarlo.
Representemos el ideograma excluyendo los cromosomas X e Y.
chr.exclude <- c("chrX", "chrY")
RCircos.Set.Core.Components(cyto.info, chr.exclude,
tracks.inside, tracks.outside)
RCircos.Set.Plot.Area()
RCircos.Chromosome.Ideogram.Plot()
Una vez que ya hemos representado el ideograma, vamos añadiendo tarcks. En nuestro caso, en el interior ya que así lo hemos especificado inicialmente. Existen diferentes tipos de tracks gráficos que pueden añadirse al gráfico:
– heatmap – histogram – lines – scatterplot – tiles
Además se pueden representar enlaces entre regiones o posiciones cromosómicas y también conectores y texto para el nombre de los genes.
Para introducir cada tipo de track se utiliza una función concreta de la forma RCircos.TIPO.Plot. Además, cada fucnión requiere que los datos a representar estén en un data.frame añadidos a su posición genómica.
Por ejemplo, veamos en primer lugar como añadir los nombres de los genes en el Circos plot. Para ello, lo primero es cargar los datos de los nombres de los genes:
data(RCircos.Gene.Label.Data)
head(RCircos.Gene.Label.Data)
## Chromosome chromStart chromEnd Gene
## 1 chr1 8921418 8934967 ENO1
## 2 chr1 17345375 17380514 SDHB
## 3 chr1 27022894 27107247 ARID1A
## 4 chr1 41976121 42501596 HIVEP3
## 5 chr1 43803519 43818443 MPL
## 6 chr1 45794977 45805926 MUTYH
Una vez cargados los datos representamos el primer track, en este caso los conectores de las posiciones genómicas a los textos.
chr.exclude <- NULL
RCircos.Set.Core.Components(cyto.info, chr.exclude,
tracks.inside, tracks.outside)
RCircos.Set.Plot.Area()
RCircos.Chromosome.Ideogram.Plot()
side <- "in" # En que lado del ideograma estará: "in" or "out"
track.num <- 1 # La posición del track
RCircos.Gene.Connector.Plot(RCircos.Gene.Label.Data,
track.num, side)
La sintaxis del comando es, de nuevo, muy intuitiva. La función RCircos.Gene.Connector.Plot require los datos (RCircos.Gene.Label.Data), la posición del track en cuestión y si va dentro (“in”) o fuera (“out”) del ideograma. A continuación, usando la función RCircos.Gene.Name.Plot introducimos los nombres de los genes, a esta función hay que pasarle un argumento adicional especificando en qué columna del data.frame están los datos (en este caso los nombres de los genes) a representar.
OJO: Cada vez que se añade un track no es necesario reiniciar todo el plot como aparece en el código de abajo. Esto sólo es necesario para que R Markdown pueda representar cada uno de los plots. En el script con el código limpio adjunto a este tutorial veréis que los tracks se añaden secuencialmente.
RCircos.Set.Plot.Area()
RCircos.Chromosome.Ideogram.Plot()
side <- "in" # En que lado del ideograma estará: "in" or "out"
track.num <- 1 # La posición del track
RCircos.Gene.Connector.Plot(RCircos.Gene.Label.Data,
track.num, side)
track.num <- 2
name.col <- 4 #indicamos la columna en la que está el nombre
RCircos.Gene.Name.Plot(RCircos.Gene.Label.Data,
name.col,track.num, side)
A continuación incluiremos un par de tracks gráficos. Por ejemplo, un heatmap de la expresión en la línea celular A498. Podemos encontrarla en el dataset RCircos.Heatmap.Data.
data(RCircos.Heatmap.Data)
head(RCircos.Heatmap.Data)
## Chromosome chromStart chromEnd GeneName X786.O A498 A549.ATCC
## 1 chr1 934341 935552 HES4 6.75781 7.38773 6.47890
## 2 chr1 948846 949919 ISG15 7.56297 10.49590 5.89893
## 3 chr1 1138887 1142089 TNFRSF18 4.69775 4.55593 4.38970
## 4 chr1 1270657 1284492 DVL1 7.76886 7.52194 6.87125
## 5 chr1 1288070 1293915 MXRA8 4.49805 4.72032 4.62207
## 6 chr1 1592938 1624243 SLC35E2B 8.73104 8.10229 8.36599
## ACHN BT.549 CAKI.1
## 1 6.05517 8.85062 7.00307
## 2 7.58095 12.08470 7.81459
## 3 4.50064 4.47525 4.47721
## 4 7.03517 7.65386 7.69733
## 5 4.58575 5.66389 4.93499
## 6 9.04116 9.24175 9.89727
Donde vemos que la expresión de dicha línea está en la columna 6 y así se lo indicaremos a la función RCircos.Heatmap.Plot
RCircos.Set.Plot.Area()
RCircos.Chromosome.Ideogram.Plot()
side <- "in" # En que lado del ideograma estará: "in" or "out"
track.num <- 1 # La posición del track
RCircos.Gene.Connector.Plot(RCircos.Gene.Label.Data,
track.num, side)
track.num <- 2
name.col <- 4 #indicamos la columna en la que está el nombre
RCircos.Gene.Name.Plot(RCircos.Gene.Label.Data,
name.col,track.num, side)
data.col <- 6
track.num <- 3
RCircos.Heatmap.Plot(RCircos.Heatmap.Data, data.col,
track.num, side)
Siguendo este esquema general existen otros tipos de funciones para representar tracks gráficos. En el codigo siguiente se muestra el resto. Con todos ellos formamos un RCircos completo.
RCircos.Set.Plot.Area()
RCircos.Chromosome.Ideogram.Plot()
side <- "in" # En que lado del ideograma estará: "in" or "out"
track.num <- 1 # La posición del track
RCircos.Gene.Connector.Plot(RCircos.Gene.Label.Data,
track.num, side)
track.num <- 2
name.col <- 4 #indicamos la columna en la que está el nombre
RCircos.Gene.Name.Plot(RCircos.Gene.Label.Data,
name.col,track.num, side)
data.col <- 6
track.num <- 3
RCircos.Heatmap.Plot(RCircos.Heatmap.Data, data.col,
track.num, side)
data(RCircos.Line.Data)
data.col <- 5
track.num <- 4
side <- "in"
RCircos.Line.Plot(RCircos.Line.Data, data.col,
track.num, side)
data(RCircos.Scatter.Data)
data.col <- 5
track.num <- 5
side <- "in"
by.fold <- 1 # los puntos con un valor por encima de by.fold se pintan en rojo
RCircos.Scatter.Plot(RCircos.Scatter.Data, data.col,
track.num, side, by.fold)
data(RCircos.Histogram.Data)
data.col <- 4
track.num <- 6
side <- "in"
RCircos.Histogram.Plot(RCircos.Histogram.Data,
data.col, track.num, side)
data(RCircos.Tile.Data)
track.num <- 7
side <- "in"
RCircos.Tile.Plot(RCircos.Tile.Data, track.num, side)
El último tipo de representación de los Circos son los enlaces entre posiciones del genoma. En RCircos estos enlaces pueden ser links si son entre regiones pequeñas o ribbons si son entre regiones más o menos grandes. Veamos los datasets de ejemplo para los links
data(RCircos.Link.Data)
head(RCircos.Link.Data)
## Chromosome chromStart chromEnd Chromosome.1 chromStart.1 chromEnd.1
## 1 chr1 8284703 8285399 chr1 8285752 8286389
## 2 chr1 85980143 85980624 chr7 123161313 123161687
## 3 chr1 118069850 118070319 chr1 118070329 118070689
## 4 chr1 167077258 167077658 chr1 169764630 169764965
## 5 chr1 171671272 171671550 chr1 179790879 179791292
## 6 chr1 174333479 174333875 chr6 101861516 101861840
y para los ribbons
data(RCircos.Ribbon.Data)
head(RCircos.Ribbon.Data)
## chromA chromStartA chromEndA chromB chromStartB chromEndB
## 1 chr1 28000000 84900000 chr18 19000000 56200000
## 2 chr1 214500000 236600000 chr10 3800000 17300000
## 3 chr5 62900000 104500000 chr13 79000000 104800000
## 4 chr8 73900000 139900000 chr17 0 22200000
En ambos casos se va a representar un data.frame en el que en cada línea hay dos regiones genómicas representadas por el cromosoma, la posición en la que empieza y la que acaba. Se ve que la única diferencia entre los datos de los links y los de los ribbons es el tamaño de dichas regiones. Para representarlo se hace lo siguiente.
RCircos.Set.Plot.Area()
RCircos.Chromosome.Ideogram.Plot()
side <- "in" # En que lado del ideograma estará: "in" or "out"
track.num <- 1 # La posición del track
RCircos.Gene.Connector.Plot(RCircos.Gene.Label.Data,
track.num, side)
track.num <- 2
name.col <- 4 #indicamos la columna en la que está el nombre
RCircos.Gene.Name.Plot(RCircos.Gene.Label.Data,
name.col,track.num, side)
data.col <- 6
track.num <- 3
RCircos.Heatmap.Plot(RCircos.Heatmap.Data, data.col,
track.num, side)
data(RCircos.Line.Data)
data.col <- 5
track.num <- 4
side <- "in"
RCircos.Line.Plot(RCircos.Line.Data, data.col,
track.num, side)
data(RCircos.Scatter.Data)
data.col <- 5
track.num <- 5
side <- "in"
by.fold <- 1 # los puntos con un valor por encima de by.fold se pintan en rojo
RCircos.Scatter.Plot(RCircos.Scatter.Data, data.col,
track.num, side, by.fold)
data(RCircos.Histogram.Data)
data.col <- 4
track.num <- 6
side <- "in"
RCircos.Histogram.Plot(RCircos.Histogram.Data,
data.col, track.num, side)
data(RCircos.Tile.Data)
track.num <- 7
side <- "in"
RCircos.Tile.Plot(RCircos.Tile.Data, track.num, side)
track.num <- 8
RCircos.Link.Plot(RCircos.Link.Data, track.num, by.chromosome = TRUE)
RCircos.Ribbon.Plot(ribbon.data=RCircos.Ribbon.Data,
track.num=9, by.chromosome=FALSE, twist=FALSE)
En la ayuda de ambas funciones puede verse como cambiar algunas de las propiedades de los gráficos como la posibilidad de que haya twist en los ribbons o que los colores sean diferentes en los enlaces intra o extracromosomicos.
Este tutorial es, básicamente, una reorganización de la viñeta del paquete, donde puede encontrarse más información para modificar algunas de las propiedades de los Circos.