Skip to content

Instantly share code, notes, and snippets.

@airalcorn2
Last active August 28, 2024 14:34
Show Gist options
  • Save airalcorn2/b10feffd6b52c387e0836e8ff8ea5dcd to your computer and use it in GitHub Desktop.
Save airalcorn2/b10feffd6b52c387e0836e8ff8ea5dcd to your computer and use it in GitHub Desktop.
A script for plotting Foursquare/Swarm check-in data.
# Adapted from: https://stackoverflow.com/a/77261943/1316276.
import matplotlib
matplotlib.use("Agg")
import geodatasets
import geopandas as gpd
import glob
import json
import matplotlib.pyplot as plt
import os
import pandas as pd
import requests
from datetime import datetime, timedelta
from json import JSONDecodeError
from shapely.geometry import Point
def get_checkins(foursquare_path):
api_key_path = f"{foursquare_path}/fsq_api_key.txt"
with open(api_key_path) as f:
api_key = f.read().strip()
headers = {"accept": "application/json", "Authorization": api_key}
url = "https://api.foursquare.com/v3/places/{fsq_id}?fields=geocodes"
rows = []
checkin_jsons = glob.glob(f"{foursquare_path}/checkins*.json")
for checkin_json in checkin_jsons:
with open(checkin_json) as f:
checkins = json.load(f)
for checkin in checkins["items"]:
try:
fsq_id = checkin["venue"]["id"]
except KeyError:
continue
response = requests.get(url.format(fsq_id=fsq_id), headers=headers)
try:
locations = response.json()
rows.append(
{
"name": checkin["venue"]["name"],
"fsq_id": fsq_id,
"date": checkin["createdAt"],
"lat": locations["geocodes"]["main"]["latitude"],
"lon": locations["geocodes"]["main"]["longitude"],
}
)
except JSONDecodeError:
continue
except KeyError:
continue
df = pd.DataFrame(rows)
df.to_csv(f"{foursquare_path}/all_checkins.csv", index=False)
def save_maps(foursquare_path):
df = pd.read_csv(f"{foursquare_path}/all_checkins.csv")
geometry = [Point(xy) for xy in zip(df["lon"], df["lat"])]
gdf = gpd.GeoDataFrame(df, geometry=geometry)
gdf.set_crs(epsg=4326, inplace=True)
world = gpd.read_file(geodatasets.get_path("naturalearth.land"))
output_dir = "maps"
os.makedirs(output_dir)
cur_date = datetime.strptime(df["date"].min().split()[0], "%Y-%m-%d")
end_date = datetime.strptime(df["date"].max().split()[0], "%Y-%m-%d")
days = (end_date - cur_date).days
for day in range(days + 1):
plt.close("all")
ax = world.plot(figsize=(10, 6), color="lightgray", edgecolor="black")
cur_date_start = cur_date.strftime("%Y-%m-%d 00:00:00.000000")
prev_checkins = gdf[gdf["date"] < cur_date_start]
if len(prev_checkins) > 0:
prev_checkins.plot(ax=ax, color="blue", markersize=20)
cur_date_end = cur_date.strftime("%Y-%m-%d 24:00:00.000000")
today_checkins = gdf[
(cur_date_start < gdf["date"]) & (gdf["date"] < cur_date_end)
]
if len(today_checkins) > 0:
today_checkins.plot(ax=ax, color="red", markersize=40)
checkins = gdf[gdf["date"] < cur_date_end]
n_checkins = len(checkins)
n_places = len(checkins["fsq_id"].unique())
cur_date_str = cur_date_start.split()[0]
ax.set_title(f"{cur_date_str} Check-ins: {n_checkins} Places: {n_places}")
ax.axis("off")
ax.set_aspect("equal")
plt.savefig(f"{output_dir}/{cur_date_str}.png", dpi=300, bbox_inches="tight")
cur_date += timedelta(days=1)
def main():
foursquare_path = "/home/airalcorn2/Documents/Foursquare"
get_checkins(foursquare_path)
save_maps(foursquare_path)
# To create a video of the saved images, in the maps directory, run:
# ffmpeg -framerate 14 -pattern_type glob -i 'maps/*.png' -c:v libx264 out.mp4
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment