2019-04-25

Plot median and quartiles in ggplot2 using geom_pointrange

Problem

We would like to plot the interquartile range (IQR) and the median in ggplot2.

Solution

In this case we use the function geom_pointrange. We need to specify the interval (interquartile range) with the arguments fun.ymin and fun.ymax, and fun.y to plot the median.

library(ggplot2)
ggplot(data = diamonds) +
  geom_pointrange(mapping = aes(x = cut, y = depth),
                  stat = "summary",
                  fun.ymin = function(z) {quantile(z,0.25)},
                  fun.ymax = function(z) {quantile(z,0.75)},
                  fun.y = median)

Results

Related posts

Spanish version

References

2019-04-08

Quantile-quantile (Q-Q) plots with ggplot2

Problem

We'd like to create quantile-quantile (Q-Q) plots using ggplot2.

Solution

  • Option 1: one column.
  • We create two examples using one column of a data frame. In the first example, we previously transform the vector rivers into a data frame. In the second, we use the column Volume from the data frame trees.

    library(tidyverse)
    ggplot(data.frame(rivers), aes(sample = rivers)) + stat_qq() + stat_qq_line()
    ggplot(trees, aes(sample = Volume)) + stat_qq() + stat_qq_line()
    
  • Option 2: multiple columns.
  • We compare the distribution of Miles/(US) gallon by number of cylinders (cyl).

    ggplot(mtcars, aes(sample = mpg, colour = factor(cyl))) +
      stat_qq() +
      stat_qq_line()
    
  • Option 3: multiple panels.
  • In this first example no transformation is needed because a column of the data frame contains the groups..

    ggplot(mtcars, aes(sample = mpg)) +
      facet_wrap( ~ factor(cyl)) +
      stat_qq() +
      stat_qq_line()
    
    In the second example, we convert the data frame from wide format to long format for faceting into multiple panels with facet_wrap. Instead of 31 observations for 3 variables, we will have one column condition containing 93 observaciones for the 3 variables.

    gather(trees, condition, measurement, Girth:Volume, factor_key = TRUE) %>%
      ggplot(aes(sample = measurement)) +
      facet_wrap( ~ condition, scales = "free") +
      stat_qq() +
      stat_qq_line()
    
    In the third example, we convert from wide to long, facet by chemical composition, and use a colour for each kiln.

    library(HSAUR2)
    gather(pottery, condition, measurement, Al2O3:BaO, factor_key = TRUE) %>%
      ggplot(aes(sample = measurement, colour = kiln)) +
      facet_wrap(~ condition, scales = "free") +
      stat_qq() +
      stat_qq_line()
    

References

2019-03-09

Gráficos Q-Q con ggplot2

Problema

En entradas anteriores explicamos como crear un gráfico Q-Q con el paquete stats preinstalado por defecto. En esa ocasión mostraremos cómo crear estos gráficos con ggplot2.

Solución

  • Opción 1: única columna.
  • Creamos dos ejemplos de una sola columna de un data frame. En el primero el vector rivers que transformamos previamente en un data frame, y en el segundo la columna Volume del data frame trees.

    library(tidyverse)
    ggplot(data.frame(rivers), aes(sample = rivers)) + stat_qq() + stat_qq_line()
    ggplot(trees, aes(sample = Volume)) + stat_qq() + stat_qq_line()
    
  • Opción 2: múltiples columnas.
  • Comparamos las distribuciones de Miles/(US) gallon por número de cilindros (cyl).

    ggplot(mtcars, aes(sample = mpg, colour = factor(cyl))) +
      stat_qq() +
      stat_qq_line()
    
  • Opción 3: múltiples paneles.
  • En este primer ejemplo no es necesario realizar ninguna transformación porque el data frame tiene una columna con los grupos.

    ggplot(mtcars, aes(sample = mpg)) +
      facet_wrap( ~ factor(cyl)) +
      stat_qq() +
      stat_qq_line()
    
    En este segundo ejemplo transformamos el data frame de formato ancho a largo para poder crear los paneles con facet_wrap. En lugar de tener 31 observaciones para 3 variables, tendremos una columna condition con las 3 variables y 93 observaciones.

    gather(trees, condition, measurement, Girth:Volume, factor_key = TRUE) %>%
      ggplot(aes(sample = measurement)) +
      facet_wrap( ~ condition, scales = "free") +
      stat_qq() +
      stat_qq_line()
    
    En este tercer ejemplo empleamos múltiples colores en función del kiln en cada panel por sustancia química encontrada.

    library(HSAUR2)
    gather(pottery, condition, measurement, Al2O3:BaO, factor_key = TRUE) %>%
      ggplot(aes(sample = measurement, colour = kiln)) +
      facet_wrap(~ condition, scales = "free") +
      stat_qq() +
      stat_qq_line()
    

Entradas relacionadas

Referencias

2019-02-08

Calcular y representar la duración del día con R

Problema

Queremos calcular y representar la duración del día con R en función de unas coordinadas geográficas.

Solución

  • 1. Calculamos la salida y puesta de sol
  • Primero calculamos la salida y la puesta de sol con la función getSunlightTimes del paquete suncalc. Indicamos el intervalo deseado, las coordinadas (latitud y longitud), y el huso horario (tz, time zone) correspondiente.

    library(suncalc) 
    library(tidyverse)
    library(scales)
    df <-
      getSunlightTimes(
        date = seq.Date(as.Date("2017-12-01"), as.Date("2018-12-31"), by = 1),
        keep = c("sunrise", "sunriseEnd", "sunset", "sunsetStart"),
        lat = 39.8628,
        lon = 4.0273,
        tz = "CET"
      )
    
  • 2. Gráfico de la salida y puesta de sol
  • Necesitamos manipular los datos originales para calcular la diferencia entre el inicio del día, y la salida y puesta de sol. Después representamos las dos nuevas variables usando geom_ribbon de ggplot2. Luego personalizamos los ejes y el título.

    # Amanecer/ocaso
    df %>%
      mutate(
        date = as.POSIXct(date) - 12 * 60 * 60 ,
        sunrise = sunrise - date,
        sunset =  sunset - date,
      ) %>%
      ggplot() +
      geom_ribbon(aes(x = date, ymin = sunrise, ymax = sunset),
                  fill = "#FDE725FF",
                  alpha = .8) + # "#ffeda0"
      scale_x_datetime(
        breaks = seq(as.POSIXct(min(df$date)), as.POSIXct(max(df$date)), "month"),
        expand = c(0, 0),
        labels = date_format("%b %y"),
        minor_breaks = NULL
      ) +
      scale_y_continuous(
        limits = c(0, 24),
        breaks = seq(0, 24, 2),
        expand = c(0, 0),
        minor_breaks = NULL
      ) +
      labs(
        x = "Date",
        y = "Hours",
        title = sprintf(
          "Sunrise and Sunset for %s\n%s ",
          "Toledo (Spain)",
          paste0(as.Date(range(df$date)), sep = " ", collapse = "to ")
        )
      ) +
      theme(
        panel.background = element_rect(fill = "#180F3EFF"),
        panel.grid = element_line(colour = "grey", linetype = "dashed")
      )
    
  • 3. Duración del día
  • Muy similar al gráfico anterior. Ahora solamente necesitamos calcular la duración del día day_length y representar los resultados con geom_area and geom_line.

    df %>%
      mutate(
        date = as.POSIXct(date),
        day_length = as.numeric(sunset - sunrise)
      ) %>%
      ggplot(aes(x = date, y = day_length)) +
      geom_area(fill = "#FDE725FF", alpha = .4) +
      geom_line(color = "#525252") +
      scale_x_datetime(
        expand = c(0, 0),
        labels = date_format("%b '%y"),
        breaks =  seq(as.POSIXct(min(df$date)), as.POSIXct(max(df$date)), "month"),
        minor_breaks = NULL
      ) +
      scale_y_continuous(
        limits = c(0, 24),
        breaks = seq(0, 24, 2),
        expand = c(0, 0),
        minor_breaks = NULL
      ) +
      labs(x = "Date", y = "Hours", title = "Toledo (Spain) - Daytime duration") +
      theme_bw()
    

    Entradas relacionadas

    Referencias

    2019-02-04

    Calculate and plot sunrise and sunset times with R

    Problem

    We would like to calculate and plot the sunrise and sunset times based on any location's latitude and longitude coordinates with R.

    Solution

  • 1. Compute sunrise and sunset times
  • First we calculate the sunrise and sunset times using the function getSunlightTimes from the package suncalc. We pass the desired date interval, the appropiate latitude and longitude coordinates, and time zone (tz).

    library(suncalc) 
    library(tidyverse)
    library(scales)
    df <-
      getSunlightTimes(
        date = seq.Date(as.Date("2017-12-01"), as.Date("2018-12-31"), by = 1),
        keep = c("sunrise", "sunriseEnd", "sunset", "sunsetStart"),
        lat = 39.8628,
        lon = 4.0273,
        tz = "CET"
      )
    
  • 2. Sunrise and sunset times plot
  • We need to manipulate the original data frame to calculate the difference between midnight start of day, and the sunrise and sunset times. Then we plot those two new variables using geom_ribbon from ggplot2. We further customize the axes, and title.

    # Sunrise/set
    df %>%
      mutate(
        date = as.POSIXct(date) - 12 * 60 * 60 ,
        sunrise = sunrise - date,
        sunset =  sunset - date,
      ) %>%
      ggplot() +
      geom_ribbon(aes(x = date, ymin = sunrise, ymax = sunset),
                  fill = "#FDE725FF",
                  alpha = .8) + # "#ffeda0"
      scale_x_datetime(
        breaks = seq(as.POSIXct(min(df$date)), as.POSIXct(max(df$date)), "month"),
        expand = c(0, 0),
        labels = date_format("%b %y"),
        minor_breaks = NULL
      ) +
      scale_y_continuous(
        limits = c(0, 24),
        breaks = seq(0, 24, 2),
        expand = c(0, 0),
        minor_breaks = NULL
      ) +
      labs(
        x = "Date",
        y = "Hours",
        title = sprintf(
          "Sunrise and Sunset for %s\n%s ",
          "Toledo (Spain)",
          paste0(as.Date(range(df$date)), sep = " ", collapse = "to ")
        )
      ) +
      theme(
        panel.background = element_rect(fill = "#180F3EFF"),
        panel.grid = element_line(colour = "grey", linetype = "dashed")
      )
    
  • 3. Daytime duration
  • Very similar to the preceding plot. This time we only need to calculate the day_length and plot the results using geom_area and geom_line.

    df %>%
      mutate(
        date = as.POSIXct(date),
        day_length = as.numeric(sunset - sunrise)
      ) %>%
      ggplot(aes(x = date, y = day_length)) +
      geom_area(fill = "#FDE725FF", alpha = .4) +
      geom_line(color = "#525252") +
      scale_x_datetime(
        expand = c(0, 0),
        labels = date_format("%b '%y"),
        breaks =  seq(as.POSIXct(min(df$date)), as.POSIXct(max(df$date)), "month"),
        minor_breaks = NULL
      ) +
      scale_y_continuous(
        limits = c(0, 24),
        breaks = seq(0, 24, 2),
        expand = c(0, 0),
        minor_breaks = NULL
      ) +
      labs(x = "Date", y = "Hours", title = "Toledo (Spain) - Daytime duration") +
      theme_bw()
    

    Related posts

    References

    2019-01-31

    Cómo controlar la dispersión de puntos dentro de un diagrama de violín con ggplot2

    Problem

    Queremos controlar la dispersión de puntos dentro de un diagrama de violín con ggplot2.

    library(tidyverse)
    p <- ggplot(mpg, aes(class, hwy))
    p + geom_violin() + geom_jitter()
    

    Solución

    • Opción 1
    • Ampliamos la anchura del diagrama de violín (width = 1.3), y jugamos con la transparencia y la variación horizontal de geom_ jitter con (width = .02). No es una opción enteramente satisfactoria. Al restringir la variación horizontal de geom_ jitter, limitamos la propia finalidad de la función que es evitar la superposición de puntos.

      p + geom_violin(width = 1.3) + geom_jitter(alpha = 0.2, width = .02)
      
    • Opción 2
    • Empleamos la función geom_quasirandom del paquete geom_beeswarm:

      The quasirandom geom is a convenient means to offset points within categories to reduce overplotting. Uses the vipor package

      library(ggbeeswarm)
      p + geom_violin(width = 1.3) + geom_quasirandom(alpha = 0.2, width = 0.2)
      

    Entradas relacionadas

    Referencias

    Nube de datos