Playing in snow is fun. But playing in snow data can be fun, too - at least for R nerds. You don’t get nearly as cold and wet, either. Here’s interactive accumulation info for every snowfall since January of 2000 at my ZIP code: 37153, a.k.a. the Franklin Road area of Rutherford County, Tennessee.

The data come from the Open-Meteo API. Here is the R script that produced the graphic and table:

# ============================================================
# HISTORICAL SNOWFALL: Murfreesboro, TN (Since Jan 1, 2000)
# Source: Open-Meteo Archive API
# ============================================================

# --- Load Required Libraries ---
library(tidyverse)
library(httr)
library(jsonlite)
library(lubridate)
library(plotly)
library(DT)

# ============================================================
# 1. DEFINE PARAMETERS AND API URL
# ============================================================

base_url <- "https://archive-api.open-meteo.com/v1/archive"
start_date <- as.Date("2000-01-01")
end_date <- Sys.Date()

url <- paste0(
  base_url,
  "?latitude=35.82913501174874",
  "&longitude=-86.50940847281211",
  "&start_date=", start_date,
  "&end_date=", end_date,
  "&daily=weathercode,snowfall_sum",
  "&timezone=America%2FChicago"
)

# ============================================================
# 2. FETCH AND PROCESS DATA
# ============================================================

response <- fromJSON(content(GET(url), "text", encoding = "UTF-8"))
weather_data <- response$daily

df <- as_tibble(weather_data) %>%
  # Safety: treat missing snowfall_sum as 0
  mutate(snowfall_sum = coalesce(snowfall_sum, 0)) %>%
  mutate(
    date        = as.Date(time),
    SnowIn_raw  = snowfall_sum / 2.54,        # cm -> inches (unrounded, for hover)
    SnowIn      = round(SnowIn_raw, 2),       # rounded for the bars/table
    Weather = case_when(
      weathercode == 0 ~ "Clear sky",
      weathercode == 1 ~ "Mainly clear",
      weathercode == 2 ~ "Partly cloudy",
      weathercode == 3 ~ "Overcast",
      weathercode == 45 ~ "Fog",
      weathercode == 48 ~ "Rime fog",
      weathercode == 51 ~ "Light drizzle",
      weathercode == 53 ~ "Moderate drizzle",
      weathercode == 55 ~ "Dense drizzle",
      weathercode == 61 ~ "Slight rain",
      weathercode == 63 ~ "Moderate rain",
      weathercode == 65 ~ "Heavy rain",
      weathercode == 71 ~ "Slight snow",
      weathercode == 73 ~ "Moderate snow",
      weathercode == 75 ~ "Heavy snow",
      weathercode == 80 ~ "Rain showers (slight)",
      weathercode == 81 ~ "Rain showers (moderate)",
      weathercode == 82 ~ "Rain showers (violent)",
      weathercode == 95 ~ "Thunderstorm",
      weathercode == 96 ~ "Thunderstorm + hail",
      weathercode == 99 ~ "Thunderstorm + heavy hail",
      TRUE ~ "Unknown"
    )
  )

# Optional quick diagnostic to verify there ARE any non-zero days:
# print(summary(df$SnowIn))
# print(sum(df$SnowIn > 0, na.rm = TRUE))

# ============================================================
# 3. PLOT — DAILY SNOWFALL (INCHES)
#    Uses precise (unrounded) values in hover, bars still rounded.
# ============================================================

SnowPlot <- plot_ly(
  df,
  x = ~date,
  y = ~SnowIn,
  type = "bar",
  marker = list(color = "darkblue"),
  # Provide unrounded value as customdata for hover display
  customdata = ~round(SnowIn_raw, 3),
  hovertemplate = paste(
    "Date: %{x|%Y-%m-%d}",
    "<br>Snowfall: %{customdata} in",
    "<extra></extra>"
  )
) %>%
  layout(
    title = "Daily Snowfall — Murfreesboro, TN (Since Jan 1, 2000)",
    xaxis = list(title = "Date"),
    yaxis = list(title = "Snowfall (in)"),
    hovermode = "closest",
    legend = list(orientation = "h", x = 0.3, y = -0.15)
  )

# ============================================================
# 4. DATA TABLE — SNOWFALL (DT)
# ============================================================

Snow <- df %>%
  select(date, SnowIn, Weather)

SnowTable <- datatable(
  Snow,
  colnames = c("Date", "Snowfall (in)", "Weather"),
  escape = FALSE,
  extensions = c("Buttons", "ColReorder", "FixedHeader", "Scroller", "KeyTable"),
  options = list(
    dom = "Bfrtip",
    buttons = c("copy", "csv", "excel", "pdf", "print"),
    colReorder = TRUE,
    fixedHeader = TRUE,
    scrollY = 400,
    scroller = TRUE,
    keys = TRUE,
    order = list(list(0, "desc"))
  ),
  filter = "top",
  rownames = FALSE,
  caption = "Murfreesboro, TN — Daily Snowfall (inches) since Jan 1, 2000"
)

# ============================================================
# 5. DISPLAY
# ============================================================

SnowPlot
SnowTable