Repository navigation
Expand file tree
/
Copy pathopenweather_map_pcolormesh_api_uk.py
More file actions
133 lines (108 loc) · 4.96 KB
/
Copy pathopenweather_map_pcolormesh_api_uk.py
File metadata and controls
133 lines (108 loc) · 4.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
import pandas as pd
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap
from scipy.interpolate import griddata
import numpy as np
import sklearn as sk
import xlsxwriter as xlw
import os
import html
import re
#################### configure lats/lons of interest ###########################
api_key = "" # api key for openweathermap.org
lat1 = 45 # positive number means North, negative number means South
lat2 = 75 # positive number means North, negative number means South
lon1 = -20 # positive number means East, negative number means West
lon2 = 10 # positive number means East, negative number means West
# the lat2 - lat1 and lon2 - lon1 range should be the same
if (lat2-lat1) == (lon2-lon1):
print("Lat2-Lat1 and Lon2-Lon1 match... continuing")
else:
raise ValueError("Lat2-Lat1 and Lon2-Lon1 do not match. Please make them equal")
increment = 1 # to increase lat/lon co-ordinates by this amount
################################################################################
# create a dataframe of the latitude points of interest to query for weather stations
lats = pd.DataFrame(data={'lat':np.arange(lat1,lat2,increment)}) # increment in 0.5 steps
# create a numpy array of the longitude points of interest
lon_range=[]
rngr = int((lon2-lon1)/increment)
for i in range(0,rngr,1):
lon_rng = np.arange((lon1+i),(lon2+i),increment) # increment in 0.5 steps
lon_range.append(lon_rng)
# configuring df
d1 = pd.DataFrame(data={'data':[0]})
d2 = pd.DataFrame(data={'data':[0]})
# for each longitude array, join the latitude entries
for each in lon_range:
lon_df = pd.DataFrame(data={'lon':each})
d1 = pd.concat([lats,lon_df],axis=1)
d2 = pd.concat([d2,d1])
# remove things we do not need
d2 = d2[~pd.isnull(d2['lat'])]
d2 = d2[d2['lat']<=90] # filter to maximum latitude
d2 = d2[d2['lat']>=-90] # filter for minimum latitude
d2 = d2[d2['lon']<=180] # filter for maximum longitude
d2 = d2[d2['lon']>=-180] # filter for minimum longitude
d2 = d2.drop(columns=['data'])
d2 = d2.reset_index()
# configuring df
dff = pd.DataFrame(data={'name':['xyz']})
################################################################################
# make an api call for each lat/long combination as created earlier and store results in a dataframe
for ii in range(0,len(d2),1):
city = "https://api.openweathermap.org/data/2.5/weather?lat="+str(d2['lat'][ii])+"&lon="+str(d2['lon'][ii])+"&apikey="+api_key+"&units=imperial"
city = pd.read_json(city, lines=True)
co_ords = pd.DataFrame([city.coord[0]])
name = city.name
wind = pd.DataFrame([city.wind[0]])
df = pd.concat([co_ords,name,wind],axis=1)
dff = pd.concat([dff,df])
dff = dff[dff['name']!='xyz']
dff = dff.reset_index()
################################################################################
# graph definitions
def base_map_plot(sdata,bar,title):
# 1. Draw the map background
fig = plt.figure(figsize=(10, 7))
m = Basemap(projection='lcc', resolution='h',
lat_0=54, lon_0=-1,
width=0.1E7, height=0.1E7)
#m.shadedrelief()
m.drawmapboundary(fill_color='#99ffff') # or hex colour
m.fillcontinents(color='#FFFFFF', lake_color='#99ffff')
m.drawcoastlines(color='#FFFFFF')
m.drawcountries(color='#FFFFFF')
#m.drawstates(color='gray')
m.drawparallels(np.arange(-90, 100, 1))#, linewidth=0.5, dashes=[4, 2], labels=[1,0,0,1], color='r', zorder=0 )
m.drawmeridians(np.arange(-100,100,1))#, linewidth=0.5, dashes=[4, 2], labels=[1,0,0,1], color='r', zorder=0 )
# 2. scatter data
# and size reflecting area
m.pcolormesh(xi, yi, zi,latlon=True,
cmap="jet")#, zorder=2)#, alpha=0.5)
# 3. create colorbar and legend
m.drawparallels(range(-90, 100, 1), linewidth=0.5, dashes=[4, 2], labels=[1,0,0,1], color='r', zorder=0 )
m.drawmeridians(range(-100,100,1), linewidth=0.5, dashes=[4, 2], labels=[1,0,0,1], color='r', zorder=0 )
if bar==True:
plt.colorbar(label="Wind speed/mph")
plt.title(title)
################################################################################
# apply lat/lon checkers
X_dat = dff['lon']
Y_dat = dff['lat']
Z_dat = dff['speed']
# convert from pandas to numpy array
X, Y, Z = np.array([]), np.array([]), np.array([])
for iii in range(len(X_dat)):
X = np.append(X, X_dat[iii])
Y = np.append(Y, Y_dat[iii])
Z = np.append(Z, Z_dat[iii])
# create x-y points to be used in heatmap
xi = np.linspace((X.min()), (X.max()), len(dff['lon']))
yi = np.linspace((Y.min()), (Y.max()), len(dff['lon']))
# Interpolate for plotting
zi = griddata((X, Y), Z, (xi[None,:], yi[:,None]), method='cubic')
# graph the data
base_map_plot(sdata=1,bar=True,
title="Wind speed UK 06/02/2023")
#save plot
plt.savefig('C:\\Users\\kelvi\\Desktop\\wxr_map11_uk.png', dpi=400, bbox_inches='tight')