Skip to content

An analysis of weather patterns with respect to latitude. Created using the OpenWeatherMap API and Matplotlib on a dataset of randomly selected cities.

Notifications You must be signed in to change notification settings

khmccurdy/weatherpy

Repository files navigation

"WeatherPy" Project

Latitude vs. Weather

Results and Summary dashboard: https://khmccurdy.github.io/weatherpy/

The purpose of this project was to analyze weather patterns with respect to latitude. To accomplish this, we used the OpenWeatherMap API to collect information on weather conditions for over 500 randomly selected cities.

After assembling the dataset, we used Matplotlib to plot multiple aspects of the weather with respect to latitude. These factors were temperature, cloud cover, wind speed, and humidity. The associated dashboard provides the source data and visualizations created for this analysis, as well as descriptions of trends observed.

import json
import openweathermapy.core as ow
from citipy import citipy
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
from config import apikey
import random
import requests
import urllib
import time
import os
def city_string(lat,long):
    c = citipy.nearest_city(lat,long)
    return c.city_name+","+c.country_code
outdir = "Resources"
jpath = os.path.join(outdir, "results.json")
csvpath = os.path.join(outdir, "cities.csv")
def imagepath(name):
    return os.path.join(outdir, f"{name}.png")
# Only run this once!
i=0
#numCities=10
numCities=600
cities = []
results = []

# Loop through random coordinates, until we have enough (600) unique cities
# that return data from OWM. In the event that the city doesn't match, 
# print the result but don't count it. Add all extracted city data to a list.
while i < numCities:
    lat = random.random()*180-90
    lng = random.random()*360-180
    query=city_string(lat,lng)
    
    if query not in cities:
        cities.append(query)
        time.sleep(0.1)
        try:
            res = ow.get_current(query, units="imperial", appid = apikey)
            print(f"{i}: Gathered data for {res['name']}")
            print(f"{ow.BASE_URL}weather?q={query}&units=imperial&appid=(get your own)")
            i+=1
            results.append(res)
        except urllib.error.HTTPError as err:
            if err.code == 404:
                print(f"[{i}.x]: No data for {query}")
                print(f"{ow.BASE_URL}weather?q={query}&units=imperial&appid=(get your own)")
            elif err.code == 401:
                print("api code, man.")
                break
            else:
                raise

print(f"{numCities} out of {len(cities)} matched")
0: Gathered data for Avarua
http://api.openweathermap.org/data/2.5/weather?q=avarua,ck&units=imperial&appid=(get your own)
1: Gathered data for Yarada
http://api.openweathermap.org/data/2.5/weather?q=yarada,in&units=imperial&appid=(get your own)
2: Gathered data for Mahebourg
http://api.openweathermap.org/data/2.5/weather?q=mahebourg,mu&units=imperial&appid=(get your own)
[3.x]: No data for taolanaro,mg
http://api.openweathermap.org/data/2.5/weather?q=taolanaro,mg&units=imperial&appid=(get your own)
3: Gathered data for Atuona
http://api.openweathermap.org/data/2.5/weather?q=atuona,pf&units=imperial&appid=(get your own)
4: Gathered data for Cabo San Lucas
http://api.openweathermap.org/data/2.5/weather?q=cabo san lucas,mx&units=imperial&appid=(get your own)
[5.x]: No data for airai,pw
http://api.openweathermap.org/data/2.5/weather?q=airai,pw&units=imperial&appid=(get your own)
5: Gathered data for Kabinda
http://api.openweathermap.org/data/2.5/weather?q=kabinda,cd&units=imperial&appid=(get your own)
6: Gathered data for Mahmudabad
http://api.openweathermap.org/data/2.5/weather?q=mahmudabad,in&units=imperial&appid=(get your own)
7: Gathered data for Inta
http://api.openweathermap.org/data/2.5/weather?q=inta,ru&units=imperial&appid=(get your own)
8: Gathered data for Hay River
http://api.openweathermap.org/data/2.5/weather?q=hay river,ca&units=imperial&appid=(get your own)
9: Gathered data for Lewisporte
http://api.openweathermap.org/data/2.5/weather?q=lewisporte,ca&units=imperial&appid=(get your own)
10: Gathered data for Bichena
http://api.openweathermap.org/data/2.5/weather?q=bichena,et&units=imperial&appid=(get your own)
11: Gathered data for Falun
http://api.openweathermap.org/data/2.5/weather?q=falun,se&units=imperial&appid=(get your own)
12: Gathered data for Hithadhoo
http://api.openweathermap.org/data/2.5/weather?q=hithadhoo,mv&units=imperial&appid=(get your own)
13: Gathered data for Chokurdakh
http://api.openweathermap.org/data/2.5/weather?q=chokurdakh,ru&units=imperial&appid=(get your own)
14: Gathered data for Kapaa
http://api.openweathermap.org/data/2.5/weather?q=kapaa,us&units=imperial&appid=(get your own)
15: Gathered data for Bandundu
http://api.openweathermap.org/data/2.5/weather?q=bandundu,cd&units=imperial&appid=(get your own)
[16.x]: No data for tingrela,ci
http://api.openweathermap.org/data/2.5/weather?q=tingrela,ci&units=imperial&appid=(get your own)
16: Gathered data for Bambous Virieux
http://api.openweathermap.org/data/2.5/weather?q=bambous virieux,mu&units=imperial&appid=(get your own)
17: Gathered data for Carnarvon
http://api.openweathermap.org/data/2.5/weather?q=carnarvon,au&units=imperial&appid=(get your own)
[18.x]: No data for mocambique,mz
http://api.openweathermap.org/data/2.5/weather?q=mocambique,mz&units=imperial&appid=(get your own)
[18.x]: No data for zhanatas,kz
http://api.openweathermap.org/data/2.5/weather?q=zhanatas,kz&units=imperial&appid=(get your own)
18: Gathered data for Novomalorossiyskaya
http://api.openweathermap.org/data/2.5/weather?q=novomalorossiyskaya,ru&units=imperial&appid=(get your own)
19: Gathered data for Rancho Palos Verdes
http://api.openweathermap.org/data/2.5/weather?q=rancho palos verdes,us&units=imperial&appid=(get your own)
20: Gathered data for Saldanha
http://api.openweathermap.org/data/2.5/weather?q=saldanha,za&units=imperial&appid=(get your own)
...
... [Output condensed for obvious reasons - all 600 logs are available 
...  in the associated .ipynb file if you really want to see all of them.]
...
590: Gathered data for Sao Pedro do Sul
http://api.openweathermap.org/data/2.5/weather?q=sao pedro do sul,br&units=imperial&appid=(get your own)
591: Gathered data for Kamenka
http://api.openweathermap.org/data/2.5/weather?q=kamenka,ru&units=imperial&appid=(get your own)
592: Gathered data for Port Hedland
http://api.openweathermap.org/data/2.5/weather?q=port hedland,au&units=imperial&appid=(get your own)
593: Gathered data for Broken Hill
http://api.openweathermap.org/data/2.5/weather?q=broken hill,au&units=imperial&appid=(get your own)
594: Gathered data for Ystad
http://api.openweathermap.org/data/2.5/weather?q=ystad,se&units=imperial&appid=(get your own)
595: Gathered data for Irtyshskiy
http://api.openweathermap.org/data/2.5/weather?q=irtyshskiy,ru&units=imperial&appid=(get your own)
596: Gathered data for Kormilovka
http://api.openweathermap.org/data/2.5/weather?q=kormilovka,ru&units=imperial&appid=(get your own)
597: Gathered data for Limenaria
http://api.openweathermap.org/data/2.5/weather?q=limenaria,gr&units=imperial&appid=(get your own)
598: Gathered data for Te Anau
http://api.openweathermap.org/data/2.5/weather?q=te anau,nz&units=imperial&appid=(get your own)
599: Gathered data for Veydelevka
http://api.openweathermap.org/data/2.5/weather?q=veydelevka,ru&units=imperial&appid=(get your own)
600 out of 684 matched
#json.dump(results, jpath)
with open(jpath,'w') as jfile:
    jfile.write(json.dumps(results,indent=2,sort_keys=True))
#results = json.load(jpath)
# Create Pandas table from the relevant datapoints
cities_df=pd.DataFrame({"City":[x["name"]+", "+x["sys"]["country"] for x in results],
             "Latitude": [x["coord"]["lat"] for x in results],
             "Longitude": [x["coord"]["lon"] for x in results],
             "Temperature (F)": [x["main"]["temp"] for x in results],
             "Humidity (%)": [x["main"]["humidity"] for x in results],
             "Wind Speed (mph)": [x["wind"]["speed"] for x in results],
             "Cloudiness (%)": [x["clouds"]["all"] for x in results]
             })
cities_df.head(10)
City Cloudiness (%) Humidity (%) Latitude Longitude Temperature (F) Wind Speed (mph)
0 Avarua, CK 75 74 -21.21 -159.78 84.20 8.05
1 Yarada, IN 8 100 17.65 83.27 81.18 4.97
2 Mahebourg, MU 40 88 -20.41 57.70 78.80 4.70
3 Atuona, PF 80 99 -9.80 -139.03 82.17 19.51
4 Cabo San Lucas, MX 5 64 22.89 -109.91 75.45 9.17
5 Kabinda, CD 80 94 -6.14 24.49 67.05 2.84
6 Mahmudabad, IN 0 76 27.30 81.13 55.40 4.41
7 Inta, RU 48 63 66.04 60.13 -8.29 2.73
8 Hay River, CA 40 51 60.82 -115.79 35.60 11.41
9 Lewisporte, CA 90 86 49.25 -55.06 28.40 26.40
cities_df.to_csv(csvpath)
#cities_df = pd.read_csv(csvpath)

Temperature (F) vs. Latitude

plt.scatter(cities_df["Latitude"],cities_df["Temperature (F)"],s=10)
plt.title("Temperature (F) vs. Latitude", fontsize=14)
plt.xlabel("Latitude (degrees)",fontsize=12)
plt.ylabel("Temperature (F)",fontsize=12)
#plt.vlines(0,-50,150,colors="r",)
plt.axvline(x=0,c="r",alpha=0.6)
plt.xlim(-90,90)
plt.grid(alpha=0.3)
plt.savefig(imagepath("temperature"))
plt.show()

png

Humidity (%) vs. Latitude

plt.scatter(cities_df["Latitude"],cities_df["Humidity (%)"],s=10)
plt.title("Humidity (%) vs. Latitude", fontsize=14)
plt.xlabel("Latitude (degrees)",fontsize=12)
plt.ylabel("Humidity (%)",fontsize=12)
#plt.vlines(0,-50,150,colors="r",)
plt.axvline(x=0,c="r",alpha=0.6)
plt.axhline(100, c="k",alpha=0.2,lw=1)
plt.axhline(0, c="k",alpha=0.2,lw=1)
plt.xlim(-90,90)
plt.grid(alpha=0.3)
plt.savefig(imagepath("humidity"))
plt.show()

png

Cloudiness (%) vs. Latitude

plt.scatter(cities_df["Latitude"],cities_df["Cloudiness (%)"],s=10)
plt.title("Cloudiness (%) vs. Latitude", fontsize=14)
plt.xlabel("Latitude (degrees)",fontsize=12)
plt.ylabel("Cloudiness (%)",fontsize=12)
#plt.vlines(0,-50,150,colors="r",)
plt.axvline(x=0,c="r",alpha=0.6)
plt.axhline(100, c="k",alpha=0.2,lw=1)
plt.axhline(0, c="k",alpha=0.2,lw=1)
plt.xlim(-90,90)
plt.ylim(-5,105)
plt.grid(alpha=0.3)
plt.savefig(imagepath("clouds"))
plt.show()

png

Wind Speed (mph) vs. Latitude

plt.scatter(cities_df["Latitude"],cities_df["Wind Speed (mph)"],s=10)
plt.title("Wind Speed (mph) vs. Latitude", fontsize=14)
plt.xlabel("Latitude (degrees)",fontsize=12)
plt.ylabel("Wind Speed (mph)",fontsize=12)
#plt.vlines(0,-50,150,colors="r",)
plt.axvline(x=0,c="r",alpha=0.6)
plt.axhline(0, c="k",alpha=0.2,lw=1)
plt.xlim(-90,90)
plt.grid(alpha=0.3)
plt.savefig(imagepath("wind"))
plt.show()

png

Three Observations

  1. There is a strong correlation between latitude and temperature, with temperature decreasing as distance from the equator increases.

  2. There are fairly weak correlations with humidity and wind speed, with the equator having somewhat lower winds and higher humidity than more temperate regions.

  3. There is almost no discernible correlation between latitude and cloud cover.

About

An analysis of weather patterns with respect to latitude. Created using the OpenWeatherMap API and Matplotlib on a dataset of randomly selected cities.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published