Indian States Meteorological Data

Author

Jaspreet Singh Pabla

Introduction

This document presents a table displaying meteorological data for various Indian states for the first four months of 2020. The table incorporates interactive elements, such as sparklines and color-coded cells, to provide a visually appealing and informative representation of the data.

The table is designed with a theme inspired by the beloved Kung Fu Panda movies, featuring warm, earthy tones and vibrant accents reminiscent of the films’ color palette and overall aesthetic.

Why ApexCharts and Toast UI?

I chose to use ApexCharts for visualizations and Toast UI Datagrid for interactive tables due to their robust features and customization options:

  • ApexCharts: Known for its modern and visually appealing chart designs, ApexCharts offers rich customization capabilities that align well with presenting meteorological data effectively.

  • Toast UI Datagrid: Provides a powerful and interactive table component that supports pagination, sorting, and filtering out of the box. Its seamless integration with R makes it ideal for displaying large datasets like meteorological data with ease.

“You must be like the soil, strong and unmovable, yet rich and fertile.” - Master Oogway

Data Generation

First, we set a seed for reproducibility and define a list of Indian states.

Code
set.seed(123)

states <- c("Andhra Pradesh", "Arunachal Pradesh", "Assam", "Bihar", "Chhattisgarh", 
            "Goa", "Gujarat", "Haryana", "Himachal Pradesh", "Jharkhand", "Karnataka", 
            "Kerala", "Madhya Pradesh", "Maharashtra", "Manipur", "Meghalaya", 
            "Mizoram", "Nagaland", "Odisha", "Punjab", "Rajasthan", "Sikkim", 
            "Tamil Nadu", "Telangana", "Tripura", "Uttar Pradesh", "Uttarakhand", 
            "West Bengal")

Next, we create a function to generate random meteorological data for each state and month.

Code
generate_random_data <- function(state) {
  months <- c("January", "February", "March", "April")
  data <- tibble(
    State = state,
    Month = rep(months, each = 1),
    Temp = list(
      tibble(date = seq.Date(as.Date("2020-01-01"), as.Date("2020-01-31"), by = "day"), Temp = runif(31, min = 10, max = 35)),
      tibble(date = seq.Date(as.Date("2020-02-01"), as.Date("2020-02-29"), by = "day"), Temp = runif(29, min = 10, max = 35)),
      tibble(date = seq.Date(as.Date("2020-03-01"), as.Date("2020-03-31"), by = "day"), Temp = runif(31, min = 10, max = 35)),
      tibble(date = seq.Date(as.Date("2020-04-01"), as.Date("2020-04-30"), by = "day"), Temp = runif(30, min = 10, max = 35))
    ),
    rh = list(
      tibble(date = seq.Date(as.Date("2020-01-01"), as.Date("2020-01-31"), by = "day"), rh = runif(31, min = 30, max = 90)),
      tibble(date = seq.Date(as.Date("2020-02-01"), as.Date("2020-02-29"), by = "day"), rh = runif(29, min = 30, max = 90)),
      tibble(date = seq.Date(as.Date("2020-03-01"), as.Date("2020-03-31"), by = "day"), rh = runif(31, min = 30, max = 90)),
      tibble(date = seq.Date(as.Date("2020-04-01"), as.Date("2020-04-30"), by = "day"), rh = runif(30, min = 30, max = 90))
    )
  )
  return(data)
}

We then create the dataset for all states by applying the generate_random_data function to each state using bind_rows and lapply.

Code
met_india <- bind_rows(lapply(states, generate_random_data))

Finally, we calculate the minimum and maximum temperatures for each state and month, rounding the values to one decimal place.

Code
met_india <- met_india %>%
  mutate(min_temp = purrr::map_dbl(Temp, ~ min(.$Temp, na.rm = TRUE)),
         max_temp = purrr::map_dbl(Temp, ~ max(.$Temp, na.rm = TRUE)))

met_india <- met_india %>%
  mutate(
    min_temp = round(min_temp, 1),
    max_temp = round(max_temp, 1)
  )

Table Creation

To create the table, we first define a function to determine the font color based on the background color intensity.

Code
get_font_color <- function(background_color) {
  rgb <- col2rgb(background_color)
  luminance <- (0.299 * rgb[1] + 0.587 * rgb[2] + 0.114 * rgb[3]) / 255
  
  if (luminance > 0.5) {
    return("black")
  } else {
    return("white")
  }
}

Next, we set the table theme using the set_grid_theme function from the toastui package. The chosen theme is inspired by the warm, earthy tones and vibrant accents featured in theKung Fu Panda movies.

“Ho ya! That’s the stuff!” - Po

Code
set_grid_theme(
  row.even.background = "#f7e9d1", 
  row.odd.background = "#eddcbc", 
  cell.normal.border = "#8b4513", 
  cell.normal.showVerticalBorder = TRUE,
  cell.normal.showHorizontalBorder = TRUE,
  cell.header.background = "#cd853f", 
  cell.header.text = "#ffffff", 
  cell.selectedHeader.background = "#8b4513", 
  cell.focused.border = "#4d2600", 
  cell.normal.text = "#4d2600", 
  cell.normal.background = "#fff8dc" 
)

“Your mind is like this water, my friend. When it is agitated, it becomes difficult to see. But if you allow it to settle, the answer becomes clear.” - Master Oogway

The table is created using the datagrid function from the toastui package, with various customizations and interactive elements added.



Resulting Table

Code
datagrid(met_india, colwidths = "auto", pagination = 8, sortable = TRUE, filters = TRUE) %>%
  grid_complex_header(
    "Indian States Meteorological Data" = names(met_india)
  ) %>%
  grid_columns(
    columns = c("State", "Month", "min_temp", "max_temp"), width = 150
  ) %>%
  grid_sparkline(
    column = "Temp",
    renderer = function(data) {
      apex(data, aes(x = date, y = Temp), type = "area") %>%
        ax_chart(sparkline = list(enabled = TRUE)) %>%
        ax_yaxis(min = 10, max = 40) %>%
        ax_colors(c("#e67e22"))
    }
  ) %>%
  grid_sparkline(
    column = "rh",
    renderer = function(data) {
      apex(data, aes(x = date, y = rh), type = "column") %>%
        ax_chart(sparkline = list(enabled = TRUE)) %>%
        ax_yaxis(min = 30, max = 90) %>%
        ax_colors(c("#27ae60"))  # Setting custom color for the line
    }
  ) %>%
  grid_style_column(
    column = "min_temp",
    background = col_numeric("Blues", domain = range(met_india$min_temp))(met_india$min_temp),
    fontWeight = "bold",
    color = sapply(col_numeric("Blues", domain = range(met_india$min_temp))(met_india$min_temp), get_font_color),
    textAlign = "center"  # Center align the text in max_temp column
  ) %>%
  grid_style_column(
    column = "max_temp",
    background = col_numeric("Reds", domain = range(met_india$max_temp))(met_india$max_temp),
    fontWeight = "bold",
    color = sapply(col_numeric("Reds", domain = range(met_india$max_temp))(met_india$max_temp), get_font_color),
    textAlign = "center"  # Center align the text in max_temp column
  )

Conclusion