GOOGLE ADS

sábado, 30 de abril de 2022

¿Cómo replicar el gráfico de correlación con coeficientes de escala de grises en la mitad inferior y círculos en la mitad superior?

Estoy buscando replicar este gráfico de correlación, o al menos acercarme lo más posible a él.

Específicamente, quiero:


  • los valores de correlación en la mitad inferior, con valores que varían en una escala de grises basada en el valor absoluto

  • los círculos en la mitad superior, con diámetro variable y en la escala de colores.

  • Quiero poder editar las etiquetas de escala del eje para que las descripciones completas estén en el eje y y las referencias numéricas en el eje x.


Me he acercado relativamente, pero no he logrado una replicación lo suficientemente precisa. Describo mis intentos más cercanos a continuación con código reproducible. El corrplotpaquete me ha acercado más.

 # general preparation
library(car)
correlations = cor(mtcars)

  • paquete corrupto

  •  library(corrplot)

    corrplot.mixed(correlations,
    upper = "number", #upper.col =???
    lower = "circle", #lower.col =???
    tl.pos = "lt", tl.col = "black", tl.cex = 0.5)

    Notas:


    • hay una forma de hacer los coeficientes en escala de grises, pero no la entiendo: https://rdrr.io/cran/corrplot/man/COL1.html

    • Por alguna extraña razón, cuando uso mis propios datos (a diferencia de mtcar), los colores de los coeficientes no coinciden con los valores de correlación reales. No puedo dar un ejemplo de código reproducible aquí, porque funciona bien con los mtcardatos.


  • paquete cormat

  •  source("http://www.sthda.com/upload/rquery_cormat.r")
    rquery.cormat(mtcar)

  • ggcorrplot

  •  library("ggcorrplot")

    # circles separate
    ggcorrplot(correlations, # correlation matrix
    method = "circle", # circles instead of squares
    type = "upper", # show only upped triangle
    show.diag = F, # don't show diagonal values (1)
    lab = F, # don't show cor coeffs
    outline.col = "white", # no outline of circles
    ggtheme = theme_bw, # theme
    colors = c("#440154FF","#238A8DFF","#FDE725FF"))

    # coefs separate
    ggcorrplot(correlations, # correlation matrix
    method = "circle", # circles instead of squares
    type = "upper", # show only upped triangle
    show.diag = F, # don't show diagonal values (1)
    lab = T, # don't show cor coeffs
    outline.col = NA, # don't show circles
    ggtheme = theme_bw, # theme
    colors = c("#440154FF","#238A8DFF","#FDE725FF"))

    # can't combine both plots?

  • paquete de corrección

  •  library(corrgram)

    corrgram(correlations,
    labels = indices_all,
    lower.panel = "panel.fill",
    upper.panel = "panel.cor")

    Algunas otras notas:


    • Parece que las mitades de las gráficas tienden a correr a través de la diagonal opuesta que en la gráfica de ejemplo, pero supongo que eso no es una gran preocupación.



    Solución del problema

    Las opciones listas para usar son rápidas y agradables. Sin embargo, cuando se trata de personalizar, en mi humilde opinión, puede valer la pena construir la trama desde cero usando ggplot2. Como primer paso, esto implica algunas disputas de datos para que su matriz de correlación tenga la forma correcta. También en este paso convierto las categorías a factors y una identificación numérica. Según los identificadores, dividí los datos en los valores diagonales superior e inferior que luego podrían trazarse por separado usando a geom_pointy a geom_text. Además de eso, es importante agregar drop=FALSEa la escala x e y para mantener todos los niveles de los factores y el orden correcto. También uso algunas funciones para obtener las etiquetas de eje deseadas:

    EDITAR: siguiendo la sugerencia de @AllanCameron, agregué un coord_equaltoque "final" para obtener una apariencia agradable de matriz cuadrada. Y gracias a @RichtieSacramento, el código ahora asigna el valor absoluto en el sizeaes.

    library(dplyr)
    library(tidyr)
    library(ggplot2)
    correlations = cor(mtcars)
    levels <- colnames(mtcars)
    corr_long <- correlations %>%
    data.frame() %>%
    mutate(row = factor(rownames(.), levels = levels),
    rowid = as.numeric(row)) %>%
    pivot_longer(-c(row, rowid), names_to = "col") %>%
    mutate(col = factor(col, levels = levels),
    colid = as.numeric(col))
    ggplot(corr_long, aes(col, row)) +
    geom_point(aes(size = abs(value), fill = value),
    data = ~filter(.x, rowid > colid), shape = 21) +
    geom_text(aes(label = scales::number(value, accuracy =.01), color = abs(value)),
    data = ~filter(.x, rowid < colid), size = 8 /.pt) +
    scale_x_discrete(labels = ~ attr(.x, "pos"), drop = FALSE) +
    scale_y_discrete(labels = ~ paste0(.x, " (", attr(.x, "pos"), ")"), drop = FALSE) +
    scale_fill_viridis_c(limits = c(-1, 1)) +
    scale_color_gradient(low = grey(.8), high = grey(.2)) +
    coord_equal() +
    guides(size = "none", color = "none") +
    theme(legend.position = "bottom",
    panel.grid = element_blank(),
    axis.ticks = element_blank()) +
    labs(x = NULL, y = NULL, fill = NULL)

    ingrese la descripción de la imagen aquí

    No hay comentarios:

    Publicar un comentario

    Regla de Firestore para acceder a la generación de subcolección Permisos faltantes o insuficientes

    Tengo problemas con las reglas de Firestore para permitir el acceso a algunos recursos en una subcolección. Tengo algunos requests document...