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
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
And here are the refined graphics: