Last active
May 5, 2022 23:17
Star
You must be signed in to star a gist
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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