Mostrando entradas con la etiqueta labs. Mostrar todas las entradas
Mostrando entradas con la etiqueta labs. Mostrar todas las entradas

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-02

    Representar shapefiles (SHP) con ggplot2

    Problema

    Deseamos representar shapefiles (SHP) con ggplot2. Obtendremos los datos de las regiones administratitvas siguiendo los pasos de esta entrada.

    Solución

    Voy a representar los municipios de España. Generaré unos datos aleatorios para cada uno de ellos y asignarles luego una escala continua. Creo dos gráficos separados para península y Baleares, y Canarias para ganar en claridad. Finalmente represento Castilla-La Mancha, y dejo un enlace a un pdf para poder hacer zoom en el resto de la península y Baleares y apreciar el detalle.

    library(tidyverse)
    library(raster)
    shp <- getData("GADM", country = "ES", level = 4)
    shp.pen <- shp[shp@data$NAME_1 != "Islas Canarias", ]
    shp.can <- shp[shp@data$NAME_1 == "Islas Canarias", ]
    
    # Convertimos shapefiles a data frames
    df.spain <- fortify(shp, region = "NAME_4")
    df.pen <- fortify(shp.pen, region = "NAME_4")
    df.can <- fortify(shp.can, region = "NAME_4")
    
    # Datos aleatorios
    set.seed(2015)
    random.df <- data.frame(id = unique(df.spain[, 'id']),
                            random = runif(
                              n = length(unique(df.spain[, 'id'])),
                              min = 25,
                              max = 75
                            ))
    df.pen <-
      merge(df.pen, random.df, by = 'id', all.x = TRUE)
    df.can <-
      merge(df.can, random.df, by = 'id', all.x = TRUE)
    
    # Gráficos con ggplot2
    # Península y Baleares
    p.pen <-
      ggplot(df.pen, aes(x = long, y = lat, group = group)) +
      geom_polygon(aes(fill = random), colour = "white", size = 0.1) +
      labs(x = " ", y = " ") +
      theme_bw() +
      scale_fill_viridis_c('Datos aleatorios', option = "magma", direction = -1) +
      coord_map() +
      theme(
        panel.grid.minor = element_blank(),
        panel.grid.major = element_blank(),
        panel.border = element_blank(),
        axis.ticks = element_blank(),
        axis.text.x = element_blank(),
        axis.text.y = element_blank(),
        legend.position = "bottom"
      )
    
    # Canarias
    p.can <-
      ggplot(df.can, aes(x = long, y = lat, group = group)) +
      geom_polygon(aes(fill = random), colour = "white", size = 0.1) +
      labs(x = " ", y = " ") +
      theme_bw() +
      scale_fill_viridis_c('Datos aleatorios', option = "magma", direction = -1) +
      coord_map() +
      theme(
        panel.grid.minor = element_blank(),
        panel.grid.major = element_blank(),
        panel.border = element_blank(),
        axis.ticks = element_blank(),
        axis.text.x = element_blank(),
        axis.text.y = element_blank(),
        legend.position = "bottom"
      )
    
    
    # Mostramos los gráficos
    p.pen
    p.can
    

    Mapas

    Enlace al pdf.

  • Península y Baleares
  • Canarias
  • Castilla-La Mancha
  • Entradas relacionadas

    Referencias

    2018-12-17

    Gráficos de An Introduction to Statistical Learning con ggplot2 - Figura 3.1.

    Gráfico a replicar

    Continuamos con la serie iniciada sobre la creación de gráficos del libro An Introduction to Statistical Learning. En esta ocasión replicaremos el gráfico de la figura 3.1. Utiliza el conjunto de datos Advertising.Los puntos rojos representan los valores observados de ventas (sales) y los presupuestos de televisión (TV). La línea azul representa la recta de regresión. Las líneas grises verticales representan el error asociado con cada observación. Hay errores positivos (si la observación se sitúa por encima de la líneaazul) y negativos (si la observación se sitúa por debajo de la curva).

    Solución

    Con la función theme personalizamos el formato: rotamos las etiquetas del eje y, eliminamos el color de fondo, y añadimos el borde.

    library(tidyverse)
    ggplot(ad_fitted, aes(x = budgets, y = sales)) +
      geom_point(colour = "red") +
      geom_smooth(se = FALSE, method = lm) +
      geom_segment(aes(
        x = budgets,
        y = sales,
        xend = budgets,
        yend = fitted
      )) +
      scale_x_continuous(breaks = seq(0, 300, by = 50)) +
      scale_y_continuous(breaks = seq(0, 25, by = 5)) +
      theme(
        axis.text.y = element_text(angle = 90, hjust = 1),
        panel.background = element_blank(),
        panel.border = element_rect(fill = NA)
      )
    
    Si deseamos mantener la cuadrícula, pero eliminar el color de fondo (theme_bw) y modificar el título del eje x (labs):

    ggplot(ad_fitted, aes(x = budgets, y = sales)) +
      geom_point(colour = "red") +
      geom_smooth(se = FALSE, method = lm) +
      geom_segment(aes(
        x = budgets,
        y = sales,
        xend = budgets,
        yend = fitted
      )) +
      labs(x = "TV")+
      scale_x_continuous(breaks = seq(0, 300, by = 50)) +
      scale_y_continuous(breaks = seq(0, 25, by = 5)) +
      theme_bw()+
      theme(axis.text.y = element_text(angle = 90, hjust = 1))
    

    Entradas relacionadas

    Referencias

    2018-08-14

    Gráficos de An Introduction to Statistical Learning con ggplot2 - Figura 1.2

    Gráfico a replicar

    Continuamos con la serie iniciada sobre la creación de gráficos del libro An Introduction to Statistical Learning con ggplot2 parte 1. En esta ocasión replicaremos el gráfico de la figura 1.2. Se trata de tres pares de diagramas de caja, representando el índice S&P 500 entre 2001 y 2005. En cada uno de ellos se representa si el índice subió o bajó respecto al día anterior para tres momentos en el tiempo: ayer, hace dos días y hace tres días.

    Solución

    No lo replicamos idénticamente a propósito. Es más eficinet usar facet_grid para mostrar los tres en un solo gráfico y no repetir títulos de los ejes 3 veces. La parte esencial para obtenerlo es la transformación del data frame de formato ancho a largo con la función gather de tidyr. Renombramos los niveles de la variable key y añadimos colores similares, títulos de los ejes y cierto nivel de transparencia para los valores atípicos (outliers).

    library(tidyr)
    library(dplyr)
    Smarket %>%
      gather(key, value, Lag1:Lag3) %>%
      mutate(key = recode(
        factor(key),
        Lag1 = "Yesterday",
        Lag2 = "Two Days Previous",
        Lag3 = "Three Days Previous"
      )) %>% 
      ggplot(aes(x = Today, y = value, fill = Direction)) +
      geom_boxplot(outlier.alpha = .5) +
      facet_grid( ~ key) +
      scale_fill_manual(values = c("royalblue", "orangered")) +
      labs(x = "Today's Direction", y = "Percentage change in S&P")+
      theme(panel.background = element_blank())
    
  • Alternativa
  • Podríamos haber creado los tres gráficos de manera independiente como mostramos a continuación y unirlos con gridExtra. En este caso necesitamos repetir cada argumento o refinamiento del gráfico tres veces.

    library(gridExtra)
    # Yesterday
    p1 <-
      ggplot(Smarket, aes(x = Direction, y = Lag1, fill = Direction)) +
      geom_boxplot(show.legend = FALSE, outlier.alpha = .5) + ggtitle("Yesterday") +
      scale_fill_manual(values = c("royalblue", "orangered")) +
      labs(x = "Today's Direction", y = "Percentage change in S&P")
    # Two Days Previous
    p2 <-
      ggplot(Smarket, aes(x = Direction, y = Lag2, fill = Direction)) +
      geom_boxplot(show.legend = FALSE, outlier.alpha = .5) + ggtitle("Two Days Previous") +
      scale_fill_manual(values = c("royalblue", "orangered")) +
      labs(x = "Today's Direction", y = "Percentage change in S&P")
    # Three Days Previous
    p3 <-
      ggplot(Smarket, aes(x = Direction, y = Lag3, fill = Direction)) +
      geom_boxplot(show.legend = FALSE, outlier.alpha = .5) + ggtitle("Three Days Previous") +
      scale_fill_manual(values = c("royalblue", "orangered")) +
      labs(x = "Today's Direction", y = "Percentage change in S&P")
    grid.arrange(p1, p2, p3, ncol = 3)
    

    Entradas relacionadas

    2017-11-16

    Cambiar el color y añadir leyenda en un diagrama de barras por subgrupos en ggplot2

    Problema

    Cuando creamos un diagrama de barras por subgrupos (facet_grid), aunque especifiquemos color para el eje x, ggplot2 crea un gráfico monocromático, sin cambiar el color de cada columna.

    library("ggplot2")    
    ggplot(data = diamonds) + 
          geom_bar(mapping = aes(x = color, y = ..prop.., group = 2)) + 
          scale_y_continuous(labels=scales::percent) +
          facet_grid(~cut)
    

    Solución

    Al calcular la proporción por grupo, necesitamos especificar en una aesthetics (aes) diferente el color para alterar el comportamiento por defecto de ggplot2. Una dentro de la función ggplot y otra dentro de geom_bar con fill.

    ggplot(data = diamonds, aes(x = color, y = ..prop.., group = cut)) + 
      geom_bar(aes(fill = factor(..x.., labels = LETTERS[seq(from = 4, to = 10 )]))) + 
      labs(fill = "color") + 
      scale_y_continuous(labels = scales::percent) + 
      facet_grid(~ cut)
    

    Referencias

    Nube de datos