Step 5 of 6

Draw a chart

Numbers are fine. A picture is better.

Goal for this lesson: make a line chart of the forecast and save it as an image.

Step 1: Add a chart function

You installed matplotlib in lesson 1. Add import matplotlib and the draw_chart function below. The matplotlib.use("Agg") line tells it to draw into a file instead of opening a window, which works everywhere.

import csv

import matplotlib

matplotlib.use("Agg")
import matplotlib.pyplot as plt
import requests

URL = (
    "https://api.open-meteo.com/v1/forecast"
    "?latitude=29.42&longitude=-98.49"
    "&hourly=temperature_2m&temperature_unit=fahrenheit&forecast_days=2&timezone=auto"
)


def get_forecast():
    response = requests.get(URL, timeout=10)
    response.raise_for_status()
    return response.json()


def hourly_readings(data, count=12):
    hourly = data["hourly"]
    return list(zip(hourly["time"], hourly["temperature_2m"]))[:count]


def save_readings(readings, path="readings.csv"):
    with open(path, "w", newline="") as f:
        writer = csv.writer(f)
        writer.writerow(["time", "temperature_f"])
        writer.writerows(readings)


def draw_chart(readings, path="forecast.png"):
    hours = [time[11:16] for time, _ in readings]
    temps = [temp for _, temp in readings]
    plt.figure(figsize=(8, 4))
    plt.plot(hours, temps, marker="o")
    plt.title("Forecast for San Antonio")
    plt.ylabel("Temperature (°F)")
    plt.xticks(rotation=45)
    plt.tight_layout()
    plt.savefig(path)
    plt.close()


if __name__ == "__main__":
    readings = hourly_readings(get_forecast())
    save_readings(readings)
    draw_chart(readings)
    print("Saved readings.csv and forecast.png")

Step 2: Run it

python3 weather.py

Open forecast.png. That’s your forecast, drawn by a program you wrote.

Check yourself

You should see a line with 12 dots, hours along the bottom and temperature up the side. If the labels overlap, try changing count=12 to a smaller number.