import json | |
from datetime import datetime | |
from collections import namedtuple | |
from itertools import groupby, takewhile | |
from statistics import median, mean | |
from matplotlib import pyplot | |
import numpy as np | |
from geopy.distance import geodesic | |
Point = namedtuple('Point', 'latitude, longitude, datetime') | |
def read_points(): | |
with open('data.json') as f: | |
data = json.load(f) | |
for point in data['locations']: | |
yield Point( | |
point['latitudeE7'] / 10 ** 7, | |
point['longitudeE7'] / 10 ** 7, | |
datetime.fromtimestamp(int(point['timestampMs']) / 1000) | |
) | |
home = (52.350879, 4.893817) | |
work = (52.3657573, 4.8980648) | |
max_distance = 0.050 | |
from_date = datetime(2017, 11, 1) | |
from_hour = 7 | |
to_hour = 12 | |
points = read_points() | |
after_move = takewhile(lambda point: point.datetime >= from_date, points) | |
work_days = (point for point in after_move | |
if point.datetime.weekday() < 5) | |
commute_time = (point for point in work_days | |
if from_hour <= point.datetime.hour < to_hour) | |
by_days = groupby(commute_time, key=lambda point: point.datetime.date()) | |
def last_at_home(points): | |
result = None | |
for point in points: | |
if geodesic(home, point[:2]).km <= max_distance: | |
result = point | |
return result | |
def first_at_work(points, after): | |
for point in points: | |
if point.datetime > after.datetime and geodesic(work, point[:2]).km <= max_distance: | |
return point | |
Commute = namedtuple('Commute', 'day, start, end, took') | |
def get_commute(): | |
for day, points in by_days: | |
points = [*points][::-1] | |
start = last_at_home(points) | |
if start is None: | |
continue | |
end = first_at_work(points, start) | |
if end is None: | |
continue | |
yield Commute( | |
day, start.datetime, end.datetime, end.datetime - start.datetime, | |
) | |
commutes = [*get_commute()][::-1] | |
fig, ax = pyplot.subplots() | |
ax.plot([commute.day for commute in commutes], | |
[commute.took.total_seconds() / 60 for commute in commutes]) | |
ax.set(xlabel='day', ylabel='commute (minutes)', | |
title='Daily commute') | |
ax.grid() | |
pyplot.show() | |
# http://www.knmi.nl/nederland-nu/klimatologie/daggegevens | |
from dateutil.parser import parse | |
Weather = namedtuple('Weather', 'windspeed, temperature, wind_direction') | |
def read_weather(): | |
result = {} | |
with open('weather.txt') as f: | |
for line in f.readlines(): | |
if not line.startswith(' '): | |
continue | |
data = [part.strip() for part in line.split(',')] | |
result[parse(data[1]).date()] = Weather( | |
int(data[4]) / 10, | |
int(data[11]) / 10, | |
int(data[2]), | |
) | |
return result | |
weather = read_weather() | |
normalized = [commute for commute in commutes | |
if commute.took.total_seconds() < 60 * 20] | |
fig, ax = pyplot.subplots() | |
ax.grid() | |
ax.scatter([commute.took.total_seconds() / 60 for commute in normalized], | |
[weather[commute.day].windspeed for commute in normalized]) | |
ax.set(xlabel='Commute time', ylabel='Wind speed', | |
title='Commute and wind') | |
ax.legend() | |
pyplot.show() | |
from mpl_toolkits.mplot3d import Axes3D | |
fig, ax = pyplot.subplots(subplot_kw={'projection': '3d'}) | |
ax.grid() | |
ax.scatter([weather[commute.day].temperature for commute in normalized], | |
[weather[commute.day].windspeed for commute in normalized], | |
[commute.took.total_seconds() / 60 for commute in normalized]) | |
ax.set(xlabel='Wind speed', ylabel='Temperature', zlabel='Commute time', | |
title='Commute and weather') | |
ax.legend() | |
pyplot.show() | |
from matplotlib import cm | |
colors = iter(cm.Reds(np.linspace(0, 1, len(normalized)))) | |
fig, ax = pyplot.subplots() | |
ax.grid() | |
for commute in sorted(normalized, key=lambda commute: commute.took.total_seconds() / 60): | |
ax.scatter(weather[commute.day].windspeed, | |
weather[commute.day].wind_direction, | |
color=next(colors)) | |
ax.set(xlabel='Wind speed', ylabel='Wind direction', | |
title='Commute and wind') | |
ax.grid() | |
pyplot.show() | |
from matplotlib import cm | |
colors = iter(cm.Reds(np.linspace(0, 1, len(normalized)))) | |
fig, ax = pyplot.subplots(subplot_kw={'projection': 'polar'}) | |
for commute in sorted(normalized, key=lambda commute: commute.took.total_seconds() / 60): | |
ax.scatter(weather[commute.day].wind_direction, | |
weather[commute.day].windspeed, | |
color=next(colors)) | |
ax.set(title='Commute and wind') | |
ax.grid() | |
pyplot.show() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment