Group Part II: Data Modeling and Visualization

Q8: Interacting with Web APIs Problem Statement: Analyzing Weather Data from OpenWeatherMap API Dataset: Weather data retrieved from OpenWeatherMap API Description: The goal is to interact with the OpenWeatherMap API to retrieve weather data for a specific location and perform data modeling and visualization to analyze weather patterns over time. Tasks to Perform: 1. Register and obtain an API key from OpenWeatherMap. 2. Interact with the OpenWeatherMap API using the API key to retrieve weather data for a specific location. 3. Extract relevant weather attributes such as temperature, humidity, wind speed, and precipitation from the API response. 4. Clean and preprocess the retrieved data, handling missing values or inconsistent formats. 5. Perform data modeling to analyze weather patterns, such as calculating average temperature, maximum/minimum values, or trends over time. 6. Visualize the weather data using appropriate plots, such as line charts, bar plots, or scatter plots, to represent temperature changes, precipitation levels, or wind speed variations. 7. Apply data aggregation techniques to summarize weather statistics by specific time periods (e.g., daily, monthly, seasonal). 8. Incorporate geographical information, if available, to create maps or geospatial visualizations representing weather patterns across different locations. 9. Explore and visualize relationships between weather attributes, such as temperature and humidity, using correlation plots or heatmaps.

Interacting with Web APIs

Solution and implementation for Q8 from Data Modeling & Visualization (dmv).

8_openweathermap_api.ipynb Download

Q8: Interacting with Web APIs

Problem Statement: Analyzing Weather Data from OpenWeatherMap API

Code Cell [In]
# Request the API when a key is available; otherwise use the offline sample.
import json
import os
import requests
import pandas as pd
import matplotlib.pyplot as plt

api_key = os.getenv("OPENWEATHER_API_KEY")
if api_key:
    try:
        response = requests.get(
            "https://api.openweathermap.org/data/2.5/forecast",
            params={"q": "Pune,IN", "appid": api_key, "units": "metric"},
            timeout=20,
        )
        response.raise_for_status()
        weather_json = response.json()
        print("Live OpenWeatherMap forecast loaded.")
    except requests.RequestException as error:
        print("Live request failed; using local sample:", error)
        weather_json = json.loads(open("OpenWeatherMap_sample.json", encoding="utf-8").read())
else:
    print("No OPENWEATHER_API_KEY set; using synthetic local sample.")
    weather_json = json.loads(open("OpenWeatherMap_sample.json", encoding="utf-8").read())
print("Location:", weather_json["city"]["name"], "records:", len(weather_json["list"]))
Code Cell [In]
# Extract temperature, humidity, wind and precipitation from each response item.
rows = []
for item in weather_json["list"]:
    rows.append({
        "time": pd.to_datetime(item["dt"], unit="s", utc=True),
        "temperature_c": item.get("main", {}).get("temp"),
        "humidity_pct": item.get("main", {}).get("humidity"),
        "wind_m_s": item.get("wind", {}).get("speed"),
        "rain_mm": item.get("rain", {}).get("3h", 0),
    })
weather = pd.DataFrame(rows).sort_values("time")
numeric = ["temperature_c", "humidity_pct", "wind_m_s", "rain_mm"]
weather[numeric] = weather[numeric].apply(pd.to_numeric, errors="coerce")
weather[numeric] = weather[numeric].interpolate(limit_direction="both").fillna(0)
print(weather.head().to_string(index=False))
print("Missing measurements:", int(weather[numeric].isna().sum().sum()))
Code Cell [In]
# Model daily summaries and inspect changes over the forecast period.
daily = weather.set_index("time").resample("D").agg({
    "temperature_c": ["mean", "min", "max"],
    "humidity_pct": "mean",
    "wind_m_s": "mean",
    "rain_mm": "sum",
})
daily.columns = ["temp_mean", "temp_min", "temp_max", "humidity_mean", "wind_mean", "rain_total"]
print(daily.round(2).to_string())
print("Overall temperature range:", weather["temperature_c"].min(), "to", weather["temperature_c"].max(), "°C")
Code Cell [In]
# Plot weather trends and daily rainfall.
fig, axes = plt.subplots(2, 1, figsize=(10, 7))
weather.plot(x="time", y="temperature_c", ax=axes[0], legend=False, color="tomato")
axes[0].set_title("Forecast temperature")
axes[0].set_ylabel("°C")
daily["rain_total"].plot.bar(ax=axes[1], color="steelblue", title="Daily precipitation")
axes[1].set_ylabel("mm")
axes[1].tick_params(axis="x", rotation=45)
plt.tight_layout()
plt.show()
Code Cell [In]
# Show the location, then visualize correlations between weather variables.
coords = weather_json["city"]["coord"]
fig, axes = plt.subplots(1, 2, figsize=(11, 4))
axes[0].scatter(coords["lon"], coords["lat"], s=140, color="darkorange")
axes[0].annotate(weather_json["city"]["name"], (coords["lon"], coords["lat"]), xytext=(5, 5), textcoords="offset points")
axes[0].set(xlabel="Longitude", ylabel="Latitude", title="Forecast location")
axes[0].grid(alpha=0.3)
correlation = weather[numeric].corr()
image = axes[1].imshow(correlation, vmin=-1, vmax=1, cmap="coolwarm")
axes[1].set_xticks(range(len(numeric)), numeric, rotation=35, ha="right")
axes[1].set_yticks(range(len(numeric)), numeric)
axes[1].set_title("Weather correlations")
fig.colorbar(image, ax=axes[1], shrink=0.8)
plt.tight_layout()
plt.show()

Other Questions in Data Modeling & Visualization

See All Available Questions
Download