Weather Forecasts API

Author

Nate Holtz - Undergraduate at Xavier University

Published

March 20, 2024

Introduction

The data used for this exercise comes from the WeatherAPI.com which serves as a host server for weather API use. The data is hosted at www.weatherapi.com and requests for a API Key can also be made at this site. Once an API key is granted, the user can gather weather forecast data from a location of their choosing.

Some of the variables that are available to choose from are as follows:

  • Location

    • City
    • State
    • Latitude and Longitude
  • Current Weather

    • Condition
    • Temperature
    • Wind
    • Precipitation
  • Forecast

    • Condition
    • Temperature
    • Wind
    • Precipitation
    • Sunrise/Sunset Time
    • Hourly Weather
  • Alerts

    • Any National Weather Service alerts that may be active in the selected location

Weather Variables

The API allows you to make a few selections:

  • Location
  • Number of days you would like to forecast
  • Whether or not you would like to include air quality
  • Whether or not you would like to include alerts

That selection process looks like this:

q<-"q=Cincinnati"
days<-"days=10"
aqi<-"aqi=no"
alerts<-"alerts=yes"

API URL

When the API is completed, it’s URL looks like this:

http://api.weatherapi.com/v1/forecast.json?&key=myAPIKEY&q=Cincinnati&days=10&aqi=no&alerts=yes

Formatting Raw Data

Once the API gathers and runs your request, it creates a list in your RStudio environment that contains four additional lists.

Those lists are named: Location, Current, Forecast, and Alert. If you included air quality in your request, there will be an additional list for that information as well.

Converting lists into data frames

To convert the raw data lists into data frames that are usable, we can use the Json package in R. For this example, I just wanted to convert forecast and location information and exclude current weather.

There also were not any alerts at this particular time from the National Weather Service but while running the code prior to making this final example, there was a wind warning that could have been used.

The following code achieved the goal of converting those lists into two different data frames.

location_df<-weather_api_GET %>%
  eval() %>%
  fromJSON() %>% 
  use_series(location) %>%
  bind_rows()
forecast_df <- weather_api_GET %>%
  eval() %>%
  fromJSON() %>% 
  use_series(forecast) %>%
  bind_rows()

Interestingly, this code had to be modified a few times in order for RStudio to recognize it as data frame in the global environment. The function bind_rows() was necessary at the end of each code block in order for the output to be recognized as a data frame.

This is a portion of the raw data that is included in the forecast data frame:

date date_epoch day.maxtemp_c day.maxtemp_f day.mintemp_c day.mintemp_f day.avgtemp_c day.avgtemp_f day.maxwind_mph day.maxwind_kph day.totalprecip_mm day.totalprecip_in day.totalsnow_cm day.avgvis_km day.avgvis_miles day.avghumidity day.daily_will_it_rain day.daily_chance_of_rain day.daily_will_it_snow day.daily_chance_of_snow day.condition.text day.condition.icon day.condition.code day.uv astro.sunrise astro.sunset astro.moonrise astro.moonset astro.moon_phase astro.moon_illumination astro.is_moon_up astro.is_sun_up
2024-03-20 1710892800 9.6 49.3 0.4 32.7 5.7 42.2 14.8 23.8 0.00 0.00 0 10.0 6 55 0 0 0 0 Sunny //cdn.weatherapi.com/weather/64x64/day/113.png 1000 5 07:41:00 19:51:00 03:32 PM 05:49:00 Waxing Gibbous 77 1 0
2024-03-21 1710979200 9.1 48.4 -2.4 27.7 2.7 36.8 7.2 11.5 0.01 0.00 0 10.0 6 41 0 0 0 3 Partly Cloudy //cdn.weatherapi.com/weather/64x64/day/116.png 1003 5 07:39:00 19:52:00 04:33 PM 06:18:00 Waxing Gibbous 84 1 0
2024-03-22 1711065600 9.2 48.6 2.5 36.5 6.1 43.0 7.8 12.6 3.14 0.12 0 6.5 4 72 1 80 0 0 Patchy rain nearby //cdn.weatherapi.com/weather/64x64/day/176.png 1063 1 07:37:00 19:53:00 05:35 PM 06:43:00 Waxing Gibbous 91 1 0
2024-03-23 1711152000 8.1 46.6 1.6 34.9 5.7 42.3 15.4 24.8 0.98 0.04 0 8.5 5 65 1 80 0 0 Patchy rain nearby //cdn.weatherapi.com/weather/64x64/day/176.png 1063 5 07:36:00 19:54:00 06:33 PM 07:05:00 Waxing Gibbous 95 1 0
2024-03-24 1711238400 12.6 54.7 -2.1 28.1 2.5 36.5 9.8 15.8 0.00 0.00 0 10.0 6 51 0 0 0 0 Sunny //cdn.weatherapi.com/weather/64x64/day/113.png 1000 1 07:34:00 19:55:00 07:32 PM 07:25:00 Waxing Gibbous 98 1 0

This is a portion of the raw data that is included in the location data frame:

name region country lat lon tz_id
Cincinnati Ohio United States of America 39.16 -84.46 America/New_York

Combining the Data Frames

In order to get one clean data frame, combining the two individual data frames is necessary. Unfortunately, it’s not a simple as a left_join() as the two data frames do not share any characteristics to join on. Additionally, the observation number is different for the two frames so just appending those columns using a function such as cbind() as it would result in an error.

To overcome this issue, the length of observations in the location data frame should be the same as the length of observations in the forecast data frame and then the cbind() can be used to combine the two data frames into a single data frame that is navigable. The code to configure this loop is as follows:

# This code will execute a command to duplicate the number
# of rows of the forecast data frame
location_df<-
  location_df[rep(seq_len(nrow(location_df)),
                  each=nrow(forecast_df)),]

To be fair, AI was utilized to create this code but the way it works is by repeating the duplication process based on the length of the forecast data frame. It works very similarly to a loop.

From there combining the data frames together was simple by using the cbind() function in R.

# Combine the two data frames by overwriting the forecast_df
forecast_df<-
  cbind(location_df, forecast_df)

The first few observations of the final forecast data frame looks something like this:

name region country lat lon tz_id date date_epoch day.maxtemp_c day.maxtemp_f day.mintemp_c day.mintemp_f day.avgtemp_c day.avgtemp_f day.maxwind_mph day.maxwind_kph day.totalprecip_mm day.totalprecip_in day.totalsnow_cm day.avgvis_km day.avgvis_miles day.avghumidity day.daily_will_it_rain day.daily_chance_of_rain day.daily_will_it_snow day.daily_chance_of_snow day.condition.text day.condition.icon day.condition.code day.uv astro.sunrise astro.sunset astro.moonrise astro.moonset astro.moon_phase astro.moon_illumination astro.is_moon_up astro.is_sun_up
Cincinnati Ohio United States of America 39.16 -84.46 America/New_York 2024-03-20 1710892800 9.6 49.3 0.4 32.7 5.7 42.2 14.8 23.8 0.00 0.00 0 10.0 6 55 0 0 0 0 Sunny //cdn.weatherapi.com/weather/64x64/day/113.png 1000 5 07:41:00 19:51:00 03:32 PM 05:49:00 Waxing Gibbous 77 1 0
Cincinnati Ohio United States of America 39.16 -84.46 America/New_York 2024-03-21 1710979200 9.1 48.4 -2.4 27.7 2.7 36.8 7.2 11.5 0.01 0.00 0 10.0 6 41 0 0 0 3 Partly Cloudy //cdn.weatherapi.com/weather/64x64/day/116.png 1003 5 07:39:00 19:52:00 04:33 PM 06:18:00 Waxing Gibbous 84 1 0
Cincinnati Ohio United States of America 39.16 -84.46 America/New_York 2024-03-22 1711065600 9.2 48.6 2.5 36.5 6.1 43.0 7.8 12.6 3.14 0.12 0 6.5 4 72 1 80 0 0 Patchy rain nearby //cdn.weatherapi.com/weather/64x64/day/176.png 1063 1 07:37:00 19:53:00 05:35 PM 06:43:00 Waxing Gibbous 91 1 0
Cincinnati Ohio United States of America 39.16 -84.46 America/New_York 2024-03-23 1711152000 8.1 46.6 1.6 34.9 5.7 42.3 15.4 24.8 0.98 0.04 0 8.5 5 65 1 80 0 0 Patchy rain nearby //cdn.weatherapi.com/weather/64x64/day/176.png 1063 5 07:36:00 19:54:00 06:33 PM 07:05:00 Waxing Gibbous 95 1 0
Cincinnati Ohio United States of America 39.16 -84.46 America/New_York 2024-03-24 1711238400 12.6 54.7 -2.1 28.1 2.5 36.5 9.8 15.8 0.00 0.00 0 10.0 6 51 0 0 0 0 Sunny //cdn.weatherapi.com/weather/64x64/day/113.png 1000 1 07:34:00 19:55:00 07:32 PM 07:25:00 Waxing Gibbous 98 1 0

Theoretically, a user could use multiple API calls to many different areas and compare forecasts based on a variety of variables, such as location or how close the location is to a body of water.

Visual

A few visuals can help users see what happens in the background before they see the weather report on the local news, for instance.

To create a 7 day forecast, this R code could be used:

forecast_df %>% 
  head(7) %>% 
  ### Convert date into a format that can be read by ggplot
  mutate(date = ymd(date),
         day = day(date),
         weekday = weekdays(date),
         ### Must add this next line to make sure days on the xaxis are in order 
         weekday = gsub(" ", "", paste(day, ", ", weekday))
  ) %>% 
  ### Define the aesthetics
  ggplot(aes(weekday, day.maxtemp_f)
  )+
  ### Define the type of chart
  geom_col(fill = "bisque1", color = "black"
  )+
  ### Add titles
  labs(title = "7 Day Temperature Forecast",
       subtitle = "In Cincinnati Ohio",
       x = "",
       y = ""
  )+
  ### Tilt x-axis and remove y-axis labels
  theme(axis.text.x = element_text(angle = 45, hjust = 1),
        axis.text.y = element_blank()
  )+
  ### Change y axis notation
  scale_y_continuous(labels = function(x) paste(x, "°F"), limits = c(0, 80)
  )+
  ### Add data callouts
  geom_text(aes(label = paste0(round(day.maxtemp_f), "°F"), y = day.maxtemp_f), 
            vjust = -0.5, color = "black", size = 4
  )

This is an example of a neat visual that can be created using the weather API. Looks like Cincinnati shouldn’t expect it to warm up anytime soon :(.

Summary

This is a pretty cool API for pulling up to the minute weather conditions from a specific location. What I found interesting was that there was no lag delay. If I ran an API request at 11:23am, the API returned the current weather conditions at 11:23am. I would have assumed there would have been some update delay of around 15 to 20 minutes but that was not the case. You could do some cool things with this and I would assume that similar APIs are used by companies such as Windows to display the weather at the bottom of Windows operating systems on the desktop.