× ¿Necesitas ayuda para aprender R? Inscríbete en el Curso de introducción a R de Applied Epi, prueba nuestros Tutoriales gratuitos de R, escribe en nuestro Foro de preguntas y respuestas, o pregunta por nuestra Asistencia técnica para R.

38 Árboles filogenéticos

38.1 Resumen

Los árboles filogenéticos se utilizan para visualizar y describir el parentesco y la evolución de los organismos a partir de la secuencia de su código genético.

Pueden construirse a partir de secuencias genéticas utilizando métodos basados en la distancia (como el método de unión de vecinos) o métodos basados en los caracteres (como el método de máxima verosimilitud y el método Bayesiano Markov Chain Monte Carlo). La secuenciación de nueva generación (NGS, por sus siglas en inglés) se ha vuelto más económica y se está utilizando cada vez más en el área de salud pública para describir los patógenos causantes de enfermedades infecciosas. Los dispositivos de secuenciación portátil reducen el tiempo de respuesta y prometen facilitar los datos en tiempo real y así apoyar la investigación de brotes. Los datos de NGS se pueden utilizar para identificar el origen o la fuente de una cepa de un brote y su propagación, así como para determinar la presencia de genes de resistencia antimicrobiana. Para visualizar el parentesco genético entre muestras biológicas se construye un árbol filogenético.

Aquí aprenderemos a utilizar el paquete ggtree, que permite la visualización combinada de árboles filogenéticos con datos de muestra adicionales en forma de dataframe. Esto nos permitirá observar patrones y comprender mejor la dinámica de los brotes.

38.2 Preparación

Cargar paquetes

Este trozo de código muestra la carga de los paquetes necesarios. En este manual destacamos ‘p_load()’ de pacman, que instala el paquete si es necesario y lo carga para su uso. También puede cargar los paquetes instalados con library() de R base. Consulta la página Fundamentos de R para obtener más información sobre los paquetes de R.

pacman::p_load(
  rio,             # importa/exportar
  here,            # rutas de fichero relativas
  tidyverse,       # manejo general de datos y visualización
  ape,             # para importar y exportar archivos filogenéticos
  ggtree,          # para visualizar archivos filogenéticos
  treeio,          # para visualizar archivos filogenéticos
  ggnewscale)      # para añadir capas adicionales de esquemas de color

Importar datos

Los datos de esta página pueden descargarse con las instrucciones de la página Descargando el manual y los datos.

Hay varios formatos diferentes en los que se puede almacenar un árbol filogenético (por ejemplo, Newick, NEXUS, Phylip). Uno de los más comunes es el formato de archivo Newick (.nwk), que es el estándar para representar árboles en forma legible por el ordenador. Esto significa que un árbol completo puede expresarse en un formato de cadena como “((t2:0,04,t1:0,34):0,89,(t5:0,37,(t4:0,03,t3:0,67):0,9):0,59);”, enumerando todos los nodos y puntas, y su relación (longitud de rama) entre sí.

Nota: Es importante entender que el archivo del árbol filogenético en sí mismo no contiene datos de secuenciación, sino que es simplemente el resultado de las distancias genéticas entre las secuencias. Por lo tanto, no podemos extraer datos de secuenciación de un archivo de árbol.

En primer lugar, utilizamos la función read.tree() del paquete ape para importar un archivo de árbol filogenético de Newick en formato .txt, y lo almacenamos en un objeto tipo lista llamado “phylo”. Si es necesario, utiliza la función here() del paquete here para especificar la ruta relativa del archivo.

Nota: En este caso el árbol newick se guarda como un archivo .txt para facilitar su manejo y descarga desde Github.

tree <- ape::read.tree("Shigella_tree.txt")

Inspeccionamos nuestro objeto árbol (‘tree’) y vemos que contiene 299 puntas (o muestras) y 236 nodos.

tree
## 
## Phylogenetic tree with 299 tips and 236 internal nodes.
## 
## Tip labels:
##   SRR5006072, SRR4192106, S18BD07865, S18BD00489, S17BD08906, S17BD05939, ...
## Node labels:
##   17, 29, 100, 67, 100, 100, ...
## 
## Rooted; includes branch lengths.

En segundo lugar, importamos una tabla almacenada en un archivo .csv con información adicional para cada muestra secuenciada, como el sexo, el país de origen y los atributos de resistencia antimicrobiana, utilizando la función import() del paquete rio:

sample_data <- import("sample_data_Shigella_tree.csv")

A continuación se muestran las primeras 50 filas de los datos:

Limpiar e inspeccionar

Limpiamos e inspeccionamos nuestros datos: Para asignar los datos de muestra correctos al árbol filogenético, los valores de la columna Sample_ID en el dataframe sample_data deben coincidir con los valores de tip.labels en el archivo tree:

Comprobamos el formato de los tip.labels en el archivo de árbol mirando las 6 primeras entradas usando head() de R base.

head(tree$tip.label) 
## [1] "SRR5006072" "SRR4192106" "S18BD07865" "S18BD00489" "S17BD08906" "S17BD05939"

También nos aseguramos de que la primera columna de nuestro dataframe sample_data sea Sample_ID. Miramos los nombres de las columnas de nuestro dataframe utilizando colnames() de R base.

colnames(sample_data)   
##  [1] "Sample_ID"                  "serotype"                   "Country"                    "Continent"                  "Travel_history"             "Year"                       "Belgium"                   
##  [8] "Source"                     "Gender"                     "gyrA_mutations"             "macrolide_resistance_genes" "MIC_AZM"                    "MIC_CIP"

Miramos los Sample_IDs en el dataframe para asegurarnos de que el formato es el mismo que en el tip.label (por ejemplo, las letras son todas mayúsculas, no hay barras bajas adicionales _ entre las letras y los números, etc.)

head(sample_data$Sample_ID) # volvemos a inspeccionar sólo los 6 primeros usando head()
## [1] "S17BD05944" "S15BD07413" "S18BD07247" "S19BD07384" "S18BD07338" "S18BD02657"

También podemos comparar si todas las muestras están presentes en el archivo tree y viceversa, generando un vector lógico de TRUE o FALSE donde coinciden o no. Estos no se imprimen aquí, para simplificar.

sample_data$Sample_ID %in% tree$tip.label

tree$tip.label %in% sample_data$Sample_ID

Podemos utilizar estos vectores para mostrar cualquier ID que no esté en el árbol (no hay ninguno).

sample_data$Sample_ID[!tree$tip.label %in% sample_data$Sample_ID]
## character(0)

Al inspeccionar podemos ver que el formato de Sample_ID en el dataframe corresponde al formato de los nombres de las muestras en el tip.labels. No es necesario que estén clasificados en el mismo orden para que coincidan.

Estamos listos para empezar!

38.3 Visualización simple de un árbol

Diferentes configuraciones de los árboles

ggtree ofrece varios formatos de presentación y algunos pueden ser más adecuados que otros dependiendo del propósito específico. A continuación se muestran algunos ejemplos. Para otras opciones, consulta este libro en línea.

A continuación, vemos algunos ejemplos de configuración de árboles:

ggtree(tree)                                            # árbol lineal simple
ggtree(tree,  branch.length = "none")                   # árbol lineal simple con todas las puntas alineadas
ggtree(tree, layout="circular")                         # árbol circular simple
ggtree(tree, layout="circular", branch.length = "none") # árbol circular simple con todas las puntas alineadas

Árbol simple con datos de muestra

El operador %<+% se utiliza para conectar el dataframe sample_data con el archivo tree. La anotación más sencilla de un árbol es el agregado de los nombres de las muestras en las puntas, así como la coloración de las puntas y, si se desea, de las ramas:

Este es un ejemplo de árbol circular:

ggtree(tree, layout = "circular", branch.length = 'none') %<+% sample_data + # %<+% agrega un dataframe con datos de muestra al árbol
  aes(color = I(Belgium))+                       # colorea las ramas de acuerdo con una variable en tu dataframe
  scale_color_manual(
    name = "Sample Origin",                      # nombre de tu esquema de color (aparecerá en la leyenda así) 
    breaks = c("Yes", "No"),                     # las diferentes opciones en tu variable
    labels = c("NRCSS Belgium", "Other"),        # cómo quieres que se nombren las diferentes opciones en tu leyenda, permite formatearlas
    values = c("blue", "black"),                 # el color que deseas asignar a la variable  
    na.value = "black") +                        # colorea los valores no disponibles (NA) en negro 
  new_scale_color()+                             # permite añadir un esquema de color adicional para otra variable
    geom_tippoint(
      mapping = aes(color = Continent),          # color de la punta por continente Puedes cambiar la forma añadiendo "shape = "
      size = 1.5)+                               # define el tamaño de la punta
  scale_color_brewer(
    name = "Continent",                    # nombre de tu esquema de color (se mostrará en la leyenda así)
    palette = "Set1",                      # elegimos un conjunto de colores que vienen con el paquete de Brewer
    na.value = "grey") +                    # para los valores NA elegimos el color gris
  geom_tiplab(                             # añade el nombre de la muestra en la punta de su rama 
    color = 'black',                       # añade tantas líneas de texto como desees con + , pero es posible que tengas que ajustar el valor de desplazamiento para colocarlas una al lado de la otra
    offset = 1,
    size = 1,
    geom = "text",
    #align = TRUE
    )+    
  ggtitle("Phylogenetic tree of Shigella sonnei")+       # Nombre del árbol
  theme(
    axis.title.x = element_blank(), # elimina el título del eje x
    axis.title.y = element_blank(), # elimina el título del eje y
    legend.title = element_text(    # define el tamaño y el formato de la fuente del título de la leyenda
      face = "bold",
      size = 12),   
    legend.text=element_text(       # define el tamaño de letra y tipografía de la leyenda
      face = "bold",
      size = 10),  
    plot.title = element_text(      # define el tamaño de letra y tipografía del título del gráfico
      size = 12,
      face = "bold"),  
    legend.position = "bottom",     # define la posición de la leyenda
    legend.box = "vertical",        # define la posición de la leyenda
    legend.margin = margin())   

Podes exportar el gráfico de árbol con ggsave() como lo harías con cualquier otro objeto ggplot. Escrito de esta manera, ggsave() guarda la última imagen producida en la ruta de archivo que especifiques. Recordá que podes utilizar here() y rutas de archivo relativas para guardar fácilmente en subcarpetas, etc.

ggsave("example_tree_circular_1.png", width = 12, height = 14)

38.4 Manipulación de árboles

A veces puede tener un árbol filogenético muy grande y sólo le interesa una parte del árbol. Por ejemplo, si ha creado un árbol que incluye muestras históricas o internacionales para obtener una gran visión general sobre como pueden encajar tus datos en esos contextos. Pero luego, para ver más de cerca alguna parte tus datos, tendrás que inspeccionar sólo esa parte del árbol.

Dado que el archivo del árbol filogenético es el resultado del análisis de los datos de secuenciación, no podemos manipular el orden de los nodos y las ramas en el propio archivo. Estos ya han sido determinados en análisis anteriores a partir de los datos NGS en bruto. Sin embargo, podemos ampliar partes, ocultar partes e incluso subdividir partes del árbol.

Ampliar el zoom

Si en vez de “cortar” tu árbol, prefieres inspeccionar sólo una parte más de cerca, puedes hacer zoom para ver una parte específica.

En primer lugar, trazamos todo el árbol en formato lineal y añadimos etiquetas numéricas a cada nodo del árbol.

p <- ggtree(tree,) %<+% sample_data +
  geom_tiplab(size = 1.5) +                # etiqueta las puntas de todas las ramas del árbol con el nombre de la muestra
  geom_text2(
    mapping = aes(subset = !isTip,
                  label = node),
    size = 5,
    color = "darkred",
    hjust = 1,
    vjust = 1)                            # etiqueta todos los nodos del árbol

p  # imprime en pantalla

Para hacer zoom en una rama en particular (la que sobresale a la derecha), utilizá viewClade() en el objeto ggtree p y proporcioná el número de nodo para verlo más de cerca:

viewClade(p, node = 452)

Ramas colapsadas

Sin embargo, tal vez queramos ignorar esta rama, entonces podemos colapsarla en ese mismo nodo (nodo 452) utilizando collapse(). Definimos este árbol como p_collapsed.

p_collapsed <- collapse(p, node = 452)
p_collapsed

Como aclaración, cuando imprimimos p_collapsed, añadimos un geom_point2() (un diamante azul) en el nodo de la rama colapsada.

p_collapsed + 
geom_point2(aes(subset = (node == 452)),  # asignamos un símbolo al nodo colapsado
            size = 5,                     # definimos el tamaño del símbolo
            shape = 23,                   # definimos la forma del símbolo
            fill = "steelblue")           # definimos el color del símbolo

Subconjunto de un árbol

Si queremos hacer un cambio más permanente y crear un nuevo árbol reducido con el que trabajar, podemos subconjuntar parte de él con tree_subset(). Luego podemos guardarlo como un nuevo archivo de árbol newick o archivo .txt.

En primer lugar, inspeccionamos los nodos del árbol y las etiquetas de las puntas para decidir qué subconjunto se va a seleccionar.

ggtree(
  tree,
  branch.length = 'none',
  layout = 'circular') %<+% sample_data +               # añade los datos de la muestra usando el operador %<+%
  geom_tiplab(size = 1)+                                # etiqueta las puntas de todas las ramas del árbol con el nombre de la muestra
  geom_text2(
    mapping = aes(subset = !isTip, label = node),
    size = 3,
    color = "darkred") +                                # etiqueta todos los nodos del árbol
 theme(
   legend.position = "none",                            # elimina la leyenda
   axis.title.x = element_blank(),
   axis.title.y = element_blank(),
   plot.title = element_text(size = 12, face="bold"))

Ahora, digamos que hemos decidido crear un un subconjunto del árbol (o sub-árbol) con solo el nodo 528 (manteniendo las puntas dentro de esta rama después del nodo 528) y lo guardamos como un nuevo objeto sub_tree1:

sub_tree1 <- tree_subset(
  tree,
  node = 528)                                            #Subconjuntamos el árbol en el nodo 528

Veamos el subconjunto del árbol 1:

ggtree(sub_tree1) +
  geom_tiplab(size = 3) +
  ggtitle("Subset tree 1")

También podes hacer un subconjunto basado en una muestra en particular, especificando cuántos nodos “hacia atrás” queres incluir. Vamos a subconjuntar la misma parte del árbol basándonos en una muestra, en este caso S17BD07692, retrocediendo 9 nodos y lo guardamos como un nuevo objeto sub_tree2:

sub_tree2 <- tree_subset(
  tree,
  "S17BD07692",
  levels_back = 9) # levels back define cuántos nodos hacia atrás quieres ir desde la punta de la muestra

Veamos el subconjunto del árbol 2:

ggtree(sub_tree2) +
  geom_tiplab(size =3)  +
  ggtitle("Subset tree 2")

También podes guardar tu nuevo sub-árbol como un archivo Newick o incluso un archivo de texto utilizando la función write.tree() del paquete ape:

# para guardar en formato .nwk 
ape::write.tree(sub_tree2, file='data/phylo/Shigella_subtree_2.nwk')

# para guardar en formato  .txt
ape::write.tree(sub_tree2, file='data/phylo/Shigella_subtree_2.txt')

Rotación de nodos en un árbol

Como ya hemos dicho, no podemos cambiar el orden de las puntas o de los nodos en el árbol, ya que éste se basa en su parentesco genético y no está sujeto a manipulación visual. Pero podemos rotar las ramas alrededor de los nodos si eso facilita la visualización.

En primer lugar, trazamos nuestro nuevo sub-árbol 2 con las etiquetas de los nodos para elegir el nodo que queremos manipular y lo almacenamos en un objeto de ggtree plot p.

p <- ggtree(sub_tree2) +  
  geom_tiplab(size = 4) +
  geom_text2(aes(subset=!isTip, label=node), # etiqueta todos los nodos del árbol
             size = 5,
             color = "darkred", 
             hjust = 1, 
             vjust = 1) 
p

Luego podemos manipular los nodos aplicando ggtree::rotate() o ggtree::flip(): Nota: para ilustrar qué nodos estamos manipulando aplicamos primero la función geom_hilight() de ggtree para resaltar las muestras en los nodos que nos interesan y almacenamos ese objeto gráfico de ggtree en un nuevo objeto p1.

p1 <- p + geom_hilight(  # resalta el nodo 39 en azul, "extend =" permite definir la longitud del bloque de color
  node = 39,
  fill = "steelblue",
  extend = 0.0017) +  
geom_hilight(            # resalta el nodo 37 en amarillo
  node = 37,
  fill = "yellow",
  extend = 0.0017) +               
ggtitle("Original tree")


p1 # imprime en pantalla

Ahora podemos rotar el nodo 37 en el objeto p1 para que las muestras del nodo 38 se muevan hacia abajo. Almacenamos el árbol rotado en un nuevo objeto p2

p2 <- ggtree::rotate(p1, 37) + 
      ggtitle("Rotated Node 37")


p2   # imprime en pantalla

O podemos usar el comando flip para rotar el nodo 36 en el objeto p1 y mover el nodo 37 a la parte superior y el nodo 39 a la parte inferior. Almacenamos el árbol con nodos rotados como un nuevo objeto p3.

p3 <- ggtree::flip(p1, 39, 37) +
      ggtitle("Rotated Node 36")


p3   # imprime en pantalla

Ejemplo de sub-árbol con anotación de datos

Digamos que estamos investigando el grupo de casos con expansión clonal que se produjo en 2017 y 2018 representados en el nodo 39 de nuestro sub-árbol. Añadimos el año de aislamiento de la cepa, así como el historial de viajes y coloreamos por país para ver el origen de otras cepas estrechamente relacionadas genéticamente:

ggtree(sub_tree2) %<+% sample_data +     # usamos el operador %<+% para enlazar con sample_data
  geom_tiplab(                          # etiqueta las puntas de todas las ramas del árbol con el nombre de la muestra
    size = 2.5,
    offset = 0.001,
    #align = TRUE
    ) + 
  theme_tree2()+
  xlim(0, 0.015)+                       # establece los límites del eje x de nuestro árbol
  geom_tippoint(aes(color=Country),     # colorea la punta por continente
                size = 1.5)+ 
  scale_color_brewer(
    name = "Country", 
    palette = "Set1", 
    na.value = "grey")+
  geom_tiplab(                         # añade el año de aislamiento como etiqueta de texto en las puntas
    aes(label = Year),
    color = 'blue',
    offset = 0.0045,
    size = 3,
    linetype = "blank" ,
    geom = "text",
    #align = TRUE
    )+ 
  geom_tiplab(                          # añade el historial de viajes como una etiqueta de texto en las puntas, en color rojo
    aes(label = Travel_history),
    color = 'red',
    offset = 0.006,
    size = 3,
    linetype = "blank",
    geom = "text",
    #align = TRUE
    )+ 
  ggtitle("Phylogenetic tree of Belgian S. sonnei strains with travel history")+  # añade el título del árbol
  xlab("genetic distance (0.001 = 4 nucleotides difference)")+                   # añade una etiqueta en el eje x
 
  theme(
    axis.title.x = element_text(size = 10),
    axis.title.y = element_blank(),
    legend.title = element_text(face = "bold", size = 12),
    legend.text = element_text(face = "bold", size = 10),
    plot.title = element_text(size = 12, face = "bold"))

Nuestra observación apunta a un evento de importación de cepas procedentes de Asia, que luego circularon en Bélgica a lo largo de los años y parecen haber causado el último brote.

38.5 Árboles más complejos: añadir mapas térmicos de datos de muestra

Podemos añadir información más compleja, como la presencia categórica de genes de resistencia antimicrobiana y valores numéricos de resistencia realmente medida contra agentes antimicrobianos en forma de mapa de calor utilizando la función ggtree::gheatmap().

Primero necesitamos graficar nuestro árbol (puede ser lineal o circular) y almacenarlo en un nuevo objeto ggtree p: Utilizaremos el sub-árbol de la parte 3).

p <- ggtree(sub_tree2, branch.length='none', layout='circular') %<+% sample_data +
  geom_tiplab(size =3) + 
 theme(
   legend.position = "none",
    axis.title.x = element_blank(),
    axis.title.y = element_blank(),
    plot.title = element_text(
      size = 12,
      face = "bold",
      hjust = 0.5,
      vjust = -15))
p

En segundo lugar, preparamos nuestros datos. Para visualizar las diferentes variables con nuevos esquemas de color, realizamos un subconjunto de nuestro dataframe a la variable deseada. Es importante añadir el Sample_ID como nombre de fila (rownames) de lo contrario los datos no coinciden con los tip.labels del árbol.

En nuestro ejemplo, queremos ver el género y las mutaciones que podrían conferir resistencia a la ciprofloxacina, un importante antibiótico de primera línea utilizado para tratar las infecciones por Shigella.

Creamos un dataframe para el género:

gender <- data.frame("gender" = sample_data[,c("Gender")])
rownames(gender) <- sample_data$Sample_ID

Creamos un dataframe para las mutaciones en el gen gyrA, que confieren resistencia a la ciprofloxacina:

cipR <- data.frame("cipR" = sample_data[,c("gyrA_mutations")])
rownames(cipR) <- sample_data$Sample_ID

Creamos un dataframe para la concentración inhibitoria mínima (CIM) medida en laboratorio para la ciprofloxacina:

MIC_Cip <- data.frame("mic_cip" = sample_data[,c("MIC_CIP")])
rownames(MIC_Cip) <- sample_data$Sample_ID

Creamos un primer gráfico añadiendo un mapa de calor binario para el género al árbol filogenético y almacenándolo en un nuevo objeto de gráfico ggtree h1:

h1 <-  gheatmap(p, gender,                            # añadimos al árbol una capa de mapa de calor para el género del dataframe
                offset = 10,                          # offset desplaza el mapa de calor a la derecha
                width = 0.10,                         # width define el ancho de la columna del mapa de calor
                color = NULL,                         # color define el borde de las columnas del mapa de calor
         colnames = FALSE) +                          # oculta los nombres de las columnas del mapa de calor
  scale_fill_manual(name = "Gender",                  # define el esquema de colores y la leyenda para el género
                    values = c("#00d1b1", "purple"),
                    breaks = c("Male", "Female"),
                    labels = c("Male", "Female")) +
   theme(legend.position = "bottom",
        legend.title = element_text(size = 12),
        legend.text = element_text(size = 10),
        legend.box = "vertical", legend.margin = margin())
## Scale for y is already present.
## Adding another scale for y, which will replace the existing scale.
## Scale for fill is already present.
## Adding another scale for fill, which will replace the existing scale.
h1

A continuación, añadimos información sobre las mutaciones en el gen gyrA, que confieren resistencia a la ciprofloxacina:

Nota: La presencia de mutaciones cromosómicas puntuales en los datos de secuenciación del genoma completo (WGS) se determinó previamente utilizando la herramienta PointFinder desarrollada por Zankari et al. (ver la sección de referencias adicionales)

En primer lugar, asignamos un nuevo esquema de colores a nuestro objeto gráfico h1 y lo almacenamos en un objeto llamado h2. Esto nos permite definir y cambiar los colores para nuestra segunda variable en el mapa de calor.

h2 <- h1 + new_scale_fill() 

A continuación, añadimos la segunda capa del mapa de calor a h2 y almacenamos los gráficos combinados en un nuevo objeto h3:

h3 <- gheatmap(h2, cipR,         # añade la segunda capa del mapa de calor que describe las mutaciones de resistencia a la ciprofloxacina
               offset = 12, 
               width = 0.10, 
               colnames = FALSE) +
  scale_fill_manual(name = "Ciprofloxacin resistance \n conferring mutation",
                    values = c("#fe9698","#ea0c92"),
                    breaks = c( "gyrA D87Y", "gyrA S83L"),
                    labels = c( "gyrA d87y", "gyrA s83l")) +
   theme(legend.position = "bottom",
        legend.title = element_text(size = 12),
        legend.text = element_text(size = 10),
        legend.box = "vertical", legend.margin = margin())+
  guides(fill = guide_legend(nrow = 2,byrow = TRUE))
## Scale for y is already present.
## Adding another scale for y, which will replace the existing scale.
## Scale for fill is already present.
## Adding another scale for fill, which will replace the existing scale.
h3

Repetimos el proceso anterior, añadiendo primero una nueva capa de escala de colores a nuestro objeto existente h3, y luego añadiendo los datos continuos sobre la concentración inhibitoria mínima (CIM) de ciprofloxacina para cada cepa al objeto resultante h4 para producir el objeto final h5:

# Primero añadimos el nuevo esquema de colores:
h4 <- h3 + new_scale_fill()

# luego combinamos los dos en una nueva gráfica:
h5 <- gheatmap(h4, MIC_Cip,  
               offset = 14, 
               width = 0.10,
                colnames = FALSE)+
  scale_fill_continuous(name = "MIC for Ciprofloxacin",  # aquí definimos un esquema de color de gradiente para la variable continua MIC
                      low = "yellow", high = "red",
                      breaks = c(0, 0.50, 1.00),
                      na.value = "white") +
   guides(fill = guide_colourbar(barwidth = 5, barheight = 1))+
   theme(legend.position = "bottom",
        legend.title = element_text(size = 12),
        legend.text = element_text(size = 10),
        legend.box = "vertical", legend.margin = margin())
## Scale for y is already present.
## Adding another scale for y, which will replace the existing scale.
## Scale for fill is already present.
## Adding another scale for fill, which will replace the existing scale.
h5

Podemos hacer el mismo ejercicio para un árbol lineal:

p <- ggtree(sub_tree2) %<+% sample_data +
  geom_tiplab(size = 3) + # etiqueta las puntas
  theme_tree2()+
  xlab("genetic distance (0.001 = 4 nucleotides difference)")+
  xlim(0, 0.015)+
 theme(legend.position = "none",
      axis.title.y = element_blank(),
      plot.title = element_text(size = 12, 
                                face = "bold",
                                hjust = 0.5,
                                vjust = -15))
p

Primero añadimos el género:

h1 <-  gheatmap(p, gender, 
                offset = 0.003,
                width = 0.1, 
                color="black", 
         colnames = FALSE)+
  scale_fill_manual(name = "Gender",
                    values = c("#00d1b1", "purple"),
                    breaks = c("Male", "Female"),
                    labels = c("Male", "Female"))+
   theme(legend.position = "bottom",
        legend.title = element_text(size = 12),
        legend.text = element_text(size = 10),
        legend.box = "vertical", legend.margin = margin())
## Scale for y is already present.
## Adding another scale for y, which will replace the existing scale.
## Scale for fill is already present.
## Adding another scale for fill, which will replace the existing scale.
h1

A continuación, añadimos las mutaciones de resistencia a la ciprofloxacina después de añadir otra capa de colores representando los genes que confieren resistencia antimicrobiana:

h2 <- h1 + new_scale_fill()
h3 <- gheatmap(h2, cipR,   
               offset = 0.004, 
               width = 0.1,
               color = "black",
                colnames = FALSE)+
  scale_fill_manual(name = "Ciprofloxacin resistance \n conferring mutation",
                    values = c("#fe9698","#ea0c92"),
                    breaks = c( "gyrA D87Y", "gyrA S83L"),
                    labels = c( "gyrA d87y", "gyrA s83l"))+
   theme(legend.position = "bottom",
        legend.title = element_text(size = 12),
        legend.text = element_text(size = 10),
        legend.box = "vertical", legend.margin = margin())+
  guides(fill = guide_legend(nrow = 2,byrow = TRUE))
## Scale for y is already present.
## Adding another scale for y, which will replace the existing scale.
## Scale for fill is already present.
## Adding another scale for fill, which will replace the existing scale.
 h3

A continuación, añadimos en forma de mapa de calor la concentración mínima inhibitoria determinada por el laboratorio (MIC):

h4 <- h3 + new_scale_fill()
h5 <- gheatmap(h4, MIC_Cip, 
               offset = 0.005,  
               width = 0.1,
               color = "black", 
                colnames = FALSE)+
  scale_fill_continuous(name = "MIC for Ciprofloxacin",
                      low = "yellow", high = "red",
                      breaks = c(0,0.50,1.00),
                      na.value = "white")+
   guides(fill = guide_colourbar(barwidth = 5, barheight = 1))+
   theme(legend.position = "bottom",
        legend.title = element_text(size = 10),
        legend.text = element_text(size = 8),
        legend.box = "horizontal", legend.margin = margin())+
  guides(shape = guide_legend(override.aes = list(size = 2)))
## Scale for y is already present.
## Adding another scale for y, which will replace the existing scale.
## Scale for fill is already present.
## Adding another scale for fill, which will replace the existing scale.
h5

38.6 Recursos

http://hydrodictyon.eeb.uconn.edu/eebedia/index.php/Ggtree# Clade_Colors

https://bioconductor.riken.jp/packages/3.2/bioc/vignettes/ggtree/inst/doc/treeManipulation.html

https://guangchuangyu.github.io/ggtree-book/chapter-ggtree.html

https://bioconductor.riken.jp/packages/3.8/bioc/vignettes/ggtree/inst/doc/treeManipulation.html

Ea Zankari, Rosa Allesøe, Katrine G Joensen, Lina M Cavaco, Ole Lund, Frank M Aarestrup, PointFinder: una novedosa herramienta web para la detección basada en WGS de la resistencia a los antimicrobianos asociada a mutaciones puntuales cromosómicas en patógenos bacterianos, Journal of Antimicrobial Chemotherapy, Volume 72, Issue 10, October 2017, Pages 2764-2768, https://doi.org/10.1093/jac/dkx217