Here is the R code for graphing and tabulating local weather data from Open-Meteo. Below it is an AI-refined version.

# ============================================================
# HISTORICAL WEATHER DATA: Murfreesboro, TN (Past 730 Days)
# Source: Open-Meteo Archive API
# ============================================================

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

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

base_url <- "https://archive-api.open-meteo.com/v1/archive"
start_date <- Sys.Date() - (365 * 2)
end_date <- Sys.Date()

url <- paste0(
  base_url,
  "?latitude=35.82913501174874",
  "&longitude=-86.50940847281211",
  "&start_date=", start_date,
  "&end_date=", end_date,
  "&daily=temperature_2m_max,temperature_2m_min,precipitation_sum,windgusts_10m_max,weathercode,uv_index_max,sunrise,sunset",
  "&timezone=America%2FChicago"
)

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

response <- fromJSON(content(GET(url), "text"))
weather_data <- response$daily

df <- as_tibble(weather_data) %>%
  mutate(
    MaxInF = round((temperature_2m_max * 9 / 5) + 32, 1),
    MinInF = round((temperature_2m_min * 9 / 5) + 32, 1),
    PrecipIn = round(precipitation_sum / 25.4, 2),  # Convert mm to inches
    Weather = case_when(
      weathercode == 0 ~ "Clear sky",
      weathercode == 1 ~ "Mainly clear",
      weathercode == 2 ~ "Partly cloudy",
      weathercode == 3 ~ "Overcast",
      weathercode == 45 ~ "Fog",
      weathercode == 48 ~ "Depositing 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 fall",
      weathercode == 73 ~ "Moderate snow fall",
      weathercode == 75 ~ "Heavy snow fall",
      weathercode == 80 ~ "Rain showers (slight)",
      weathercode == 81 ~ "Rain showers (moderate)",
      weathercode == 82 ~ "Rain showers (violent)",
      weathercode == 95 ~ "Thunderstorm (light)",
      weathercode == 96 ~ "Thunderstorm + hail",
      weathercode == 99 ~ "Thunderstorm + heavy hail",
      TRUE ~ "Unknown"
    )
  )

# ============================================================
# 3. FILTER FOR MOST RECENT 730 DAYS AND ADD CONVERSIONS
# ============================================================

df_recent <- df %>%
  mutate(date = as.Date(time)) %>%
  filter(date >= Sys.Date() - 730) %>%
  mutate(WindGustsMPH = round(windgusts_10m_max / 1.609344, 1))

# ============================================================
# 4. PLOTLY VISUALIZATIONS
# ============================================================

# --- 4a. Maximum Temperature (°F) ---
MaxTempPlot <- plot_ly(
  data = df_recent,
  x = ~date,
  y = ~MaxInF,
  type = "scatter",
  mode = "lines",
  line = list(color = "firebrick"),
  hoverinfo = "text",
  text = ~paste0("Date: ", date, "<br>Max Temp: ", MaxInF, " °F")
) %>%
  layout(
    title = list(text = "Daily Maximum Temperature (°F) — Murfreesboro, TN", y = 0.95),
    xaxis = list(title = "Date"),
    yaxis = list(title = "Temperature (°F)"),
    hovermode = "closest",
    margin = list(t = 100)
  )

# --- 4b. Minimum Temperature (°F) ---
MinTempPlot <- plot_ly(
  data = df_recent,
  x = ~date,
  y = ~MinInF,
  type = "scatter",
  mode = "lines",
  line = list(color = "steelblue"),
  hoverinfo = "text",
  text = ~paste0("Date: ", date, "<br>Min Temp: ", MinInF, " °F")
) %>%
  layout(
    title = list(text = "Daily Minimum Temperature (°F) — Murfreesboro, TN", y = 0.95),
    xaxis = list(title = "Date"),
    yaxis = list(title = "Temperature (°F)"),
    hovermode = "closest",
    margin = list(t = 100)
  )

# --- 4c. Rainfall (inches) ---
RainPlot <- plot_ly(
  data = df_recent,
  x = ~date,
  y = ~PrecipIn,
  type = "bar",
  marker = list(color = "skyblue3"),
  hoverinfo = "text",
  text = ~paste0("Date: ", date, "<br>Rainfall: ", PrecipIn, " in")
) %>%
  layout(
    title = list(text = "Daily Rainfall (inches) — Murfreesboro, TN", y = 0.95),
    xaxis = list(title = "Date"),
    yaxis = list(title = "Rainfall (inches)"),
    hovermode = "closest",
    margin = list(t = 100)
  )

# --- 4d. Wind Gusts (mph) ---
WindPlot <- plot_ly(
  data = df_recent,
  x = ~date,
  y = ~WindGustsMPH,
  type = "scatter",
  mode = "lines",
  line = list(color = "royalblue"),
  hoverinfo = "text",
  text = ~paste0("Date: ", date, "<br>Wind Gust: ", WindGustsMPH, " mph")
) %>%
  layout(
    title = list(text = "Daily Maximum Wind Gusts (mph) — Murfreesboro, TN", y = 0.95),
    xaxis = list(title = "Date"),
    yaxis = list(title = "Wind Gusts (mph)"),
    hovermode = "closest",
    margin = list(t = 100)
  )

# ============================================================
# 5. DATA TABLE OUTPUT (DT)
# ============================================================

Wind <- df_recent %>%
  select(date, WindGustsMPH, MinInF, MaxInF, PrecipIn, Weather)

WindTable <- datatable(
  Wind,
  colnames = c("Date", "Max gust (mph)", "Min temp (°F)", "Max temp (°F)", "Rainfall (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 — Weather Data (Last 730 Days, from Open-Meteo)"
)

# ============================================================
# 6. DISPLAY PLOTS AND TABLE
# ============================================================

MaxTempPlot
MinTempPlot
RainPlot
WindPlot
WindTable

AI-refined version

And here is a refined version of the script I got after a short conversation with ChatGPT about making improvements to the chart:

# ============================================================
# HISTORICAL WEATHER DATA: Murfreesboro, TN (Past 730 Days)
# 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 <- Sys.Date() - (365 * 2)
end_date <- Sys.Date()

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

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

response <- fromJSON(content(GET(url), "text"))
weather_data <- response$daily

df <- as_tibble(weather_data) %>%
  mutate(
    MaxInF = round((temperature_2m_max * 9/5) + 32, 1),
    MinInF = round((temperature_2m_min * 9/5) + 32, 1),
    PrecipIn = round(precipitation_sum / 25.4, 2),  # mm → inches
    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"
    )
  )

# ============================================================
# 3. FILTER FOR LAST 730 DAYS + CONVERSIONS
# ============================================================

df_recent <- df %>%
  mutate(date = as.Date(time)) %>%
  filter(date >= Sys.Date() - 730) %>%
  mutate(WindGustsMPH = round(windgusts_10m_max / 1.609344, 1))

# ============================================================
# 4. PLOT 1 — HIGH & LOW TEMPERATURES
# ============================================================

TempPlot <- plot_ly(df_recent) %>%
  add_lines(
    x = ~date, y = ~MaxInF,
    name = "High Temp (°F)",
    line = list(color = "firebrick", width = 2)
  ) %>%
  add_lines(
    x = ~date, y = ~MinInF,
    name = "Low Temp (°F)",
    line = list(color = "steelblue", width = 2)
  ) %>%
  add_lines(
    x = ~date, y = rep(90, nrow(df_recent)),
    name = "90°F Reference",
    line = list(color = "black", dash = "dash"),
    showlegend = FALSE
  ) %>%
  add_lines(
    x = ~date, y = rep(32, nrow(df_recent)),
    name = "32°F Reference",
    line = list(color = "black", dash = "dash"),
    showlegend = FALSE
  ) %>%
  layout(
    title = "Daily High & Low Temperatures — Murfreesboro, TN",
    xaxis = list(title = "Date"),
    yaxis = list(title = "Temperature (°F)"),
    hovermode = "x unified",
    legend = list(orientation = "h", x = 0.3, y = -0.15)
  )

# ============================================================
# 5. PLOT 2 — WIND GUSTS & RAINFALL
# ============================================================

WindRainPlot <- plot_ly(df_recent) %>%
  add_lines(
    x = ~date, y = ~WindGustsMPH,
    name = "Wind Gusts (mph)",
    line = list(color = "darkred", width = 2)
  ) %>%
  add_lines(
    x = ~date, y = ~PrecipIn,
    name = "Rainfall (in)",
    line = list(color = "royalblue", dash = "dot", width = 2),
    yaxis = "y2"
  ) %>%
  layout(
    title = "Daily Wind Gusts & Rainfall — Murfreesboro, TN",
    xaxis = list(title = "Date"),
    yaxis = list(title = "Wind Gusts (mph)", color = "darkred"),
    yaxis2 = list(
      title = "Rainfall (in)",
      overlaying = "y",
      side = "right",
      color = "royalblue"
    ),
    hovermode = "x unified",
    legend = list(orientation = "h", x = 0.3, y = -0.15)
  )

# ============================================================
# 6. DATA TABLE OUTPUT (DT)
# ============================================================

Wind <- df_recent %>%
  select(date, WindGustsMPH, MinInF, MaxInF, PrecipIn, Weather)

WindTable <- datatable(
  Wind,
  colnames = c("Date", "Max gust (mph)", "Min temp (°F)", "Max temp (°F)", "Rainfall (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 — Weather Data (Last 730 Days, from Open-Meteo)"
)

# ============================================================
# 7. DISPLAY PLOTS AND TABLE
# ============================================================

TempPlot
WindRainPlot
WindTable

AI-refined graphics

And here are the refined graphics: