Freedom Sale
Independence Day Special — Unlock the AI Path 70% off our most popular AI course · Limited time offer
--Days
--Hrs
--Min
--Sec
Claim Your Discount
✦ Beginner ⏱ 35 min

🌤️ Build a Weather Data Visualiser with Pandas

🎯 What You'll Build

Fetch historical weather data from a free API and visualise monthly temperature trends, rainfall patterns, and seasonal statistics with pandas and matplotlib.

📋 What You'll Need

1

Fetch historical weather data

Open-Meteo provides free historical weather data for any coordinates — no sign-up needed.

import requests
import pandas as pd

def fetch_weather(lat, lon, start='2024-01-01', end='2024-12-31'):
    url = 'https://archive-api.open-meteo.com/v1/archive'
    params = {
        'latitude':              lat,
        'longitude':             lon,
        'start_date':            start,
        'end_date':              end,
        'daily':                 'temperature_2m_max,temperature_2m_min,precipitation_sum',
        'temperature_unit':      'celsius',
        'timezone':              'auto',
    }
    r    = requests.get(url, params=params, timeout=30)
    data = r.json()['daily']
    df   = pd.DataFrame(data)
    df['time'] = pd.to_datetime(df['time'])
    df['temp_avg'] = (df['temperature_2m_max'] + df['temperature_2m_min']) / 2
    return df

# Mumbai coordinates
df = fetch_weather(19.08, 72.88)
print(df.head())
print(f"\nFetched {len(df)} days of weather data")
2

Monthly aggregations

Group by month to get monthly averages and total rainfall.

df['month']     = df['time'].dt.month
df['month_name']= df['time'].dt.strftime('%b')

monthly = df.groupby(['month','month_name']).agg(
    avg_temp  = ('temp_avg',           'mean'),
    max_temp  = ('temperature_2m_max', 'mean'),
    min_temp  = ('temperature_2m_min', 'mean'),
    rainfall  = ('precipitation_sum',  'sum'),
).reset_index().sort_values('month')

print(monthly[['month_name','avg_temp','rainfall']].to_string(index=False))
month_name  avg_temp  rainfall
        Jan      22.0      0.2
        Feb      23.5      0.0
        Mar      26.9      0.0
        Apr      29.6      1.0
        May      31.1     20.4
        Jun      27.3    543.4
        Jul      26.0    785.6
        Aug      26.0    510.8
        Sep      26.8    325.0
        Oct      28.2     64.3
        Nov      27.2      2.5
        Dec      24.0      0.5
3

Plot temperature and rainfall charts

A dual-axis chart shows both temperature and rainfall on the same plot.

import matplotlib.pyplot as plt
import matplotlib.ticker as ticker

fig, ax1 = plt.subplots(figsize=(11, 5))

# Temperature line
ax1.fill_between(monthly['month_name'], monthly['min_temp'], monthly['max_temp'],
                 alpha=0.2, color='#f59e0b', label='Temp range')
ax1.plot(monthly['month_name'], monthly['avg_temp'],
         'o-', color='#f59e0b', linewidth=2.5, label='Avg temp')
ax1.set_ylabel('Temperature (degC)', color='#f59e0b')
ax1.tick_params(axis='y', labelcolor='#f59e0b')

# Rainfall bars on secondary axis
ax2 = ax1.twinx()
ax2.bar(monthly['month_name'], monthly['rainfall'],
        alpha=0.4, color='#3b82f6', label='Rainfall (mm)')
ax2.set_ylabel('Rainfall (mm)', color='#3b82f6')
ax2.tick_params(axis='y', labelcolor='#3b82f6')

plt.title('Mumbai — Monthly Weather 2024')
lines, labels = ax1.get_legend_handles_labels()
bars, blabels = ax2.get_legend_handles_labels()
ax1.legend(lines + bars, labels + blabels, loc='upper left')
plt.tight_layout()
plt.savefig('weather_chart.png', dpi=120)
plt.show()
💡 Tip: Change the lat/lon coordinates to any city. London: 51.51, -0.13. New York: 40.71, -74.01. Tokyo: 35.68, 139.76. Dubai: 25.20, 55.27. The Open-Meteo archive covers 1940 to present for most locations.

🎉 You Did It!

You fetched real-world data from a live API, cleaned it, aggregated it by month, and built a publication-quality dual-axis chart. This exact workflow is used in climate research, agritech, and logistics planning.

Found something wrong?

Spotted a bug, broken code, or something that doesn't look right? Tell us what's off and we'll fix it.