1.2 Un vistazo rápido
Antes de profundizar demasiado en los detalles, primero muestro un ejemplo simple con el uso de funcionalidades básicas en el paquete circlize para ayudarlo a obtener una idea básica de cómo funciona el paquete.
Primero generemos algunos datos aleatorios. Se necesita un vector de caracteres para presentar categorías, un vector numérico de valores x y un vector de valores y.
set.seed(999)n = 1000df = data.frame(sectors = sample(letters, n, replace = TRUE), x = rnorm(n), y = runif(n))
Primero inicializamos el diseño circular. El círculo se divide en sectores en función del rango de datos en los ejes x de cada categoría. En el siguiente código, df$x
se divide por df$sectors
y el ancho de los sectores se calcula automáticamente en función de los rangos de datos de cada categoría. Por defecto, los sectores se posicionan comenzando desde \(\theta = 0\) (en el sistema de coordenadas polares) y van a lo largo del círculo, sabiamente. Es posible que no vea nada después de ejecutar el código siguiente porque notrack se ha agregado todavía.
library(circlize)circos.par("track.height" = 0.1)circos.initialize(df$sectors, x = df$x)
Establecemos un parámetro global track.height
a 0.1 por la función de opcióncircis.par()
para que todas las pistas que se agregarán tengan una altura predeterminada de0. 1. El círculo utilizado por circlize siempre tiene un radio de 1, por lo que una altura de 0,1 significa el 10% del radio del círculo. En capítulos posteriores, puede encontrar cómo configurar la altura con unidades físicas, por ejemplo, cm.
Tenga en cuenta que la asignación de sectores solo necesita valores en la dirección x (o en la dirección circular), los valores en la dirección y (dirección radical) se usarán en el paso de crear pistas.
Después de inicializar el diseño circular, se pueden agregar gráficos a la gráfica de una manera pista por pista. Antes de dibujar nada, necesitamos saber que todas las pistas deben crearse primero por circos.trackPlotRegion()
o, para abreviar,circos.track()
, luego se pueden agregar las funciones de bajo nivel. Solo piense en el motor gráfico base R, primero necesita llamar a plot()
y luego puede usar funciones como points()
y lines()
para agregar gráficos. Dado que los rangos x para las celdas de la pista ya se han definido en el paso de inicialización,aquí solo necesitamos especificar el rango y para cada celda. Los rangos y se pueden especificar con el argumento y
como un vector numérico (de modo que el rango y se extraerá y calculará de forma automática en cada celda) o el argumento ylim
como un avector de longitud dos. En principio, los rangos y deben ser los mismos para todas las celdas de la misma pista. (Ver Figura 1.2)
circos.track(df$sectors, y = df$y, panel.fun = function(x, y) { circos.text(CELL_META$xcenter, CELL_META$cell.ylim + mm_y(5), CELL_META$sector.index) circos.axis(labels.cex = 0.6)})col = rep(c("#FF0000", "#00FF00"), 4)circos.trackPoints(df$sectors, df$x, df$y, col = col, pch = 16, cex = 0.5)circos.text(-1, 0.5, "text", sector.index = "a", track.index = 1)
Figura 1.2: Primer ejemplo de circlize, agregue la primera pista.
Los ejes para la trama circular se dibujan normalmente en la parte más externa del círculo. Aquí añadimos ejes en la primera pista poniendo circos.axis()
dentro de la función autodefinida panel.fun
(ver el código anterior). circos.track()
crea una región de trazado de una manera celda por celda y panel.fun
se ejecuta de forma real inmediatamente después de que se crea la región de trazado para una celda determinada. Por lo tanto, panel.fun
en realidad significa agregar gráficos en la celda actual (El uso de panel.fun
se discute más a fondo en la Sección 2.7).Sin especificar argumentos, circos.axis()
dibuja ejes x en la parte superior de cada celda (o en el exterior de cada celda).
Además, agregamos el nombre del sector fuera de la primera pista usando circos.text()
.CELL_META
proporciona «meta información» para la celda actual. Hay varios parámetros que pueden ser recuperados por CELL_META
. Todo su uso se explica en la Sección 2.7. En el código anterior, los nombres de los sectores se dibujan fuera de las celdas y es posible que vea mensajes de advertencia que dicen puntos de datos que exceden las regiones de trazado. Eso está totalmente bien y no te preocupes por eso. También puede agregar nombres de sector creando una pista vacía sin bordes como primera pista y agregar nombres de sector en ella (como lo que hacencircos.initializeWithIdeogram()
y chordDiagram()
, después de pasar por los siguientes capítulos).
Al especificar la posición del texto en la dirección y, se añade un desplazamiento demm_y(5)
(5 mm) a la posición y del texto. En circos.text()
, los valores x e y se miden en la coordenada de datos (la coordenada en la celda), y hay algunas funciones auxiliares que convierten unidades absolutas en valores correspondientes en la coordenada de datos. La sección 2.8.2 proporciona más información sobre la conversión de unidades de coordenadas indiferentes.
Una vez creada la pista,circos.trackPoints()
añade puntos a la primera pista. circos.trackPoints()
simplemente agrega puntos en todas las celdas simultáneamente. Como se explica con más detalle en la sección 3.2, se puede reemplazar colocando circos.text()
en panel.fun
, sin embargo,circos.trackPoints()
sería más conveniente si solo se necesitan los puntos para colocar en las celdas (pero realmente no lo recomiendo). Es bastante sencillo entender que esta función necesita una variable categórica (df$sectors
), valores en dirección x y dirección y (df$x
y df$y
).
Las funciones de bajo nivel como circos.text()
también se pueden usar fuera depanel.fun
como se muestra en el código anterior. Si es así, sector.index
y track.index
deben especificarse explícitamente porque el sector «actual»y la pista «actual» pueden no ser lo que desea. Si los gráficos se agregan directamente a la pista creada más recientemente, se puede enviar track.index
porque esta pista solo está marcada como la pista» actual».
OK, ahora agregamos histogramas a la segunda pista. Aquí circos.trackHist()
es una función de alto nivel, lo que significa que crea una nueva pista (como puede imaginar hist()
también es una función de alto nivel). bin.size
se establece explícitamente de modo que el tamaño de la bandeja para histogramas en todas las celdas sea el mismo y se pueda comparar entre sí. (Ver Figura 1.3)
bgcol = rep(c("#EFEFEF", "#CCCCCC"), 4)circos.trackHist(df$sectors, df$x, bin.size = 0.2, bg.col = bgcol, col = NA)
Figura 1.3: Primer ejemplo de círculo, agregue la segunda pista.
En la tercera pista y en panel.fun
, elegimos aleatoriamente 10 puntos de datos en cada celda, los ordenamos por valores x y los conectamos con líneas. En el siguiente código, cuando sectors
(el primer argumento sin nombre), los argumentos x
y y
se establecen encircos.track()
, los valores x e y se dividen entre df$sectors
y el subconjunto correspondiente de valores x e y se envía a panel.fun
a través de los argumentosx
y y
de panel.fun
. Por lo tanto, x
an y
in panel.fun
son exactamente los valores en la celda «actual». (Ver Figura 1.4)
circos.track(df$sectors, x = df$x, y = df$y, panel.fun = function(x, y) { ind = sample(length(x), 10) x2 = x y2 = y od = order(x2) circos.lines(x2, y2)})
Figura 1.4: Primer ejemplo de circlize, agregue la tercera pista.
Ahora volvemos a la segunda pista y actualizamos la celda en el sector «d».Esto se hace por circos.updatePlotRegion()
o la versión cortacircos.update()
. La función borra los gráficos que se han agregado.circos.update()
no puede modificar los valores xlim
y ylim
de la celda, así como otros ajustes relacionados con la posición de la celda. circos.update()
necesita especificar explícitamente el índice de sector y el índice de seguimiento a menos que la celda»actual» sea lo que desea actualizar. Después de llamar a circos.update()
,la celda «actual» se redirige a la celda que acaba de especificar y puede usar funciones gráficas de bajo nivel para agregar gráficos directamente a ella.(Ver Figura 1.5)
circos.update(sector.index = "d", track.index = 2, bg.col = "#FF8080", bg.border = "black")circos.points(x = -2:2, y = rep(0.5, 5), col = "white")circos.text(CELL_META$xcenter, CELL_META$ycenter, "updated", col = "white")
Figura 1.5: Primer ejemplo de circlize, actualice la segunda pista.
A continuación, continuamos creando nuevas pistas. Aunque hemos vuelto a la segunda pista, al crear una nueva pista, la nueva pista todavía se crea después de la pista que está más adentro. En esta nueva pista, añadimos mapas de calor decircos.rect()
. Tenga en cuenta que no hemos establecido los datos de entrada, mientras que simplemente establecemos el argumentoylim
porque los mapas de calor solo llenan toda la celda de la izquierda a la derecha y de abajo hacia arriba. También el valor exacto de ylim
no es importante y x
, y
en panel.fun()
no se utilizan (en realidad, ambos sonNULL
). (Ver Figura 1.6)
circos.track(ylim = c(0, 1), panel.fun = function(x, y) { xlim = CELL_META$xlim ylim = CELL_META$ylim breaks = seq(xlim, xlim, by = 0.1) n_breaks = length(breaks) circos.rect(breaks, rep(ylim, n_breaks - 1), breaks, rep(ylim, n_breaks - 1), col = rand_color(n_breaks), border = NA)})
Figura 1.6: Primer ejemplo de circlize, agregue la cuarta pista.
En la mayor parte del interior del círculo, se agregan enlaces o cintas. Puede haber enlaces de un solo punto a punto, punto a intervalo o intervalo a intervalo. La sección 3.11 proporciona un uso detallado de los enlaces. (Ver Figura 1.7)
circos.link("a", 0, "b", 0, h = 0.4)circos.link("c", c(-0.5, 0.5), "d", c(-0.5,0.5), col = "red", border = "blue", h = 0.2)circos.link("e", 0, "g", c(-1,1), col = "green", border = "black", lwd = 2, lty = 2)
Figura 1.7: Primer ejemplo de circlize, agregar enlaces.
Finalmente necesitamos restablecer los parámetros gráficos y las variables internas, para que no estropee su próxima gráfica.
circos.clear()