Build Weather Plot - BitKnitting/should_I_water GitHub Wiki
The Python script is located at this GitHub location.
Use matplotlib to make the plot. Use the darknet weather APIs to get the chance of rain.
The Python script I used is avaialable at this GitHub location.
NOTE: Initially, I used Jupyter to try this stuff out.
Then it was on to getting this stuff to run on the Raspberry Pi....
After finally installing matplotlib on the Raspberry Pi, it wanted the GTK namespace. I googled and installed it. Then I got:
Gdk-CRITICAL **: gdk_cursor_new_for_display: assertion 'GDK_IS_DISPLAY (display)' failed
adding:
import matplotlib
matplotlib.use('Agg')
before adding:
import matplotlib.pyplot as plt
fixed this. I got this advice from https://github.com/BVLC/caffe/issues/861:
If you want to run totally headless....
# I had to use this directive to show the matplot lib plots within Jupyter.
%matplotlib inline
import certifi
from datetime import datetime,timedelta
import json
import matplotlib.pyplot as plt
import numpy as np
import urllib3# Use the darksky weather service to get today's forecast.
# The 24 hour clock is used. We pull out the probability of rain, the intensity of
# rain that will fall if it does rain, the cloud cover, and the temperature into a prediction_list.
def get_weather_forecast():
_NUMBER_OF_HOURS = 15
'''
Use the darksky weather service to get today's forecast.
The 24 hour clock is used. We pull out the probability of rain, the intensity of
rain that will fall if it does rain, the cloud cover, and the temperature into a prediction_list.
'''
http = urllib3.PoolManager(cert_reqs='CERT_REQUIRED',ca_certs=certifi.where())
url = "https://api.darksky.net/forecast/<your info here>"
request = http.request('GET',url)
# Try a five times in case there is a failure to connect
for i in range(5):
try:
weather_prediction = json.loads(request.data.decode('utf8'))
except HTTPError as e:
weather_prediction = None
else:
prediction_data = weather_prediction['hourly']['data']
first_hour = prediction_data[0]['time']
# Just predict for _NUMBER_OF_HOURS
last_hour = datetime.fromtimestamp(first_hour) + timedelta(hours=_NUMBER_OF_HOURS)
prediction_list = []
for hour_data in prediction_data:
hour_as_datetime = datetime.fromtimestamp(hour_data['time'])
int_hour = int(hour_as_datetime.strftime('%H'))
if hour_as_datetime >= last_hour or int_hour == 0:
return prediction_list
prediction_list.append([int_hour,hour_data['precipIntensity'],hour_data['precipProbability'],
hour_data['cloudCover'],hour_data['temperature']])
def plot_weather(prediction_list):
'''
Make a four plots: hour of the day (x-axis) vs probability of rain, intensity of rain,
cloud cover, and temperature. Each reading will be in it's own graph.
store in PNG file.
'''
# Set up the numpy array.
array = np.array(prediction_list)
# Set up the x-axis. The array's columns = hour, intensity, probability, cloud_cover, temperature.
# The first hour is at location [0,0] and the last hour with readings is at the end of the first
# column at [-1,0]
start_hour = array[0,0].astype(int)
end_hour = array[-1,0].astype(int)
x = np.linspace(start_hour,end_hour,num=len(array))
# set up the x-axis and y-axis data.
hour = array[:,0].astype('int')
intensity = array[:,1]
probability = array[:,2]
cloud_cover = array[:,3]
temperature = array[:,4]
# make room for 4 subplots. We picked a size that looks good when the plot is saved as a png.
fig, (ax1,ax2,ax3,ax4) = plt.subplots(nrows=4,figsize=(6,7))
# The first plot will be the probability of rain.
ax1.set_ylim([0,1])
ax1.plot(hour,probability)
ax1.set_ylabel('probability')
ax1.set_title('Probability of rain',fontsize = 14)
# The second plot will be the expected intensity of rain (assuming it rains at all).
ax2.set_ylim([0,1])
ax2.set_title('Rain Intensity',fontsize = 14)
ax2.set_ylabel('intensity')
ax2.plot(hour,intensity)
# Plot the cloud cover
ax3.set_ylim([0,1])
ax3.set_title('Cloud Cover',fontsize = 14)
ax3.set_ylabel('cloud cover')
ax3.plot(hour,cloud_cover)
# Plot the temperature
ax4.set_xlabel('Hour (24 hour clock)',fontsize = 16)
ax4.set_title('Temperature',fontsize = 14)
ax4.set_ylabel('temperature')
# Set the y - axis to fit the data within 10's.
y_min = np.amin(temperature)
rem = y_min % 10
y_min -= rem
y_max = np.amax(temperature)
rem = y_max % 10
y_max += (10-rem)
ax4.set_ylim(y_min,y_max)
ax4.plot(hour,temperature)
# plt.tight_layout()
# Adjust the layout
fig.subplots_adjust(hspace=1)
# Save as a png
fig.savefig('/<your path>/weather.png')
# Fun to see...just checking...
plt.show()
plt.close(fig)
# Make a plot of the weather and save into png.
prediction_list = get_weather_forecast()
plot_weather(prediction_list)

I found these plots and thought they might work for the visual. I ended up using line charts for now. Line charts are a faster way to see if I can get the results into a visual that our family finds useful.
# Evenly spaced ticks on x axis labeled 0 to 24 for 24 hour clock.
x = np.linspace(0,24)
# Chance of precipitation for each hour.
# We have the intensity and the probability
y = np.cumsum(np.random.randn(50))+6
fig, (ax,ax2) = plt.subplots(nrows=2, sharex=True)
extent = [x[0]-(x[1]-x[0])/2., x[-1]+(x[1]-x[0])/2.,0,1]
ax.imshow(y[np.newaxis,:], cmap="plasma", aspect="auto", extent=extent)
ax.set_yticks([])
ax.set_xlim(extent[0], extent[1])
ax2.plot(x,y)
plt.tight_layout()
plt.show()
import numpy as np; np.random.seed(1)
a = np.array([[1,2,3], [4,5,6]])
print(a)
print(np.cumsum(a))
random = np.random.randn(50)
print(random)
y = np.cumsum(random) + 6
print(y)
[[1 2 3]
[4 5 6]]
[ 1 3 6 10 15 21]
[ 1.62434536 -0.61175641 -0.52817175 -1.07296862 0.86540763 -2.3015387
1.74481176 -0.7612069 0.3190391 -0.24937038 1.46210794 -2.06014071
-0.3224172 -0.38405435 1.13376944 -1.09989127 -0.17242821 -0.87785842
0.04221375 0.58281521 -1.10061918 1.14472371 0.90159072 0.50249434
0.90085595 -0.68372786 -0.12289023 -0.93576943 -0.26788808 0.53035547
-0.69166075 -0.39675353 -0.6871727 -0.84520564 -0.67124613 -0.0126646
-1.11731035 0.2344157 1.65980218 0.74204416 -0.19183555 -0.88762896
-0.74715829 1.6924546 0.05080775 -0.63699565 0.19091548 2.10025514
0.12015895 0.61720311]
[ 7.62434536 7.01258895 6.4844172 5.41144858 6.2768562 3.97531751
5.72012927 4.95892237 5.27796147 5.02859109 6.49069903 4.43055832
4.10814112 3.72408676 4.8578562 3.75796494 3.58553673 2.70767831
2.74989206 3.33270727 2.23208809 3.3768118 4.27840252 4.78089686
5.68175281 4.99802495 4.87513473 3.93936529 3.67147721 4.20183268
3.51017193 3.1134184 2.4262457 1.58104006 0.90979393 0.89712933
-0.22018102 0.01423468 1.67403686 2.41608102 2.22424546 1.3366165
0.58945821 2.28191281 2.33272056 1.69572492 1.8866404 3.98689554
4.10705449 4.7242576 ]