-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlocal_setlists_combine.py
More file actions
149 lines (121 loc) · 4.35 KB
/
local_setlists_combine.py
File metadata and controls
149 lines (121 loc) · 4.35 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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
"""
Routines for working with full setlist data and comparing these setlists across a tour.
"""
__author__ = "Mark Gotham"
import json
import matplotlib.pyplot as plt
from numpy import arange, linspace
import pandas as pd
from pathlib import Path
THIS_DIR = Path.cwd()
def setlist_2_song_list(
setlist_data: dict
) -> list:
"""
Given full setlist information,
prune the trimmings, to return only a list of song names.
Args:
setlist_data (dict): The json dict for a setlist exactly as retrieved from setlist.fm.
"""
songs = []
for top_level_item in setlist_data:
if "song" in top_level_item.keys():
for song in top_level_item["song"]:
songs.append(song["name"])
return songs
def event_id_2_song_list(event_id: str = "1b94b560") -> list:
"""
Retrieve full setlist data from a file at "setlists/{event_id}.json".
Extract the list of songs in order, and return that alone.
Args:
event_id: a Valid setlist.fm event ID which corresponds to a file at "setlists/{event_id}.json".
Returns:
list
"""
file_path = THIS_DIR / "setlists" / f"{event_id}.json"
with open(file_path, "r") as file:
data = json.load(file)
return setlist_2_song_list(data)
def all_events_on_tour(
artist_name: str,
tour_name: str,
) -> list:
"""
Get event IDs for every event in a tour, in order.
"""
path_to_file = THIS_DIR / "data" / f"{artist_name}_event_date_tour_venue.csv"
df = pd.read_csv(path_to_file, sep=",", engine="python")
df.sort_values(by="date")
return df.event_id[df.tour_name == tour_name]
def all_songlists_on_tour(
artist_name: str,
tour_name: str,
) -> list:
"""
Retrieve the list of songs for every set on a named tour.
"""
all_songlists = []
event_ids = all_events_on_tour(artist_name, tour_name)
for event_id in event_ids:
songlist = event_id_2_song_list(event_id)
all_songlists.append(songlist)
return all_songlists
def plot_cross_tour_correspondence(
artist_name: str,
tour_name: str,
proportional_position=True
) -> None:
"""
Plot lists with correspondence.
Args:
artist_name (str): Valid artist name
tour_name (str): Valid tour name. See `all_songlists_on_tour`
proportional_position (bool, optional): Whether to use proportional position or the index. Defaults to True.
"""
lists = all_songlists_on_tour(artist_name, tour_name)
# Define the x-coordinates of the lists
x_coords = arange(len(lists))
# Create a dictionary to store the y-coordinates of each item
y_coords = {}
for i, lst in enumerate(lists):
for j, item in enumerate(lst):
if item not in y_coords:
y_coords[item] = []
if proportional_position:
proportional_position_val = (j + 1) / (len(lst) + 1)
y_coords[item].append((i, proportional_position_val))
else:
y_coords[item].append((i, j))
plt.figure(figsize=(30, 10))
for item, coords in y_coords.items():
x = [x for x, _ in coords]
y = [y for _, y in coords]
plt.scatter(x, y, label=item)
for i in range(len(coords) - 1):
plt.plot(
[coords[i][0], coords[i + 1][0]],
[coords[i][1], coords[i + 1][1]],
label=None,
color="gray",
alpha=0.5
)
plt.xticks(x_coords, [str(i + 1) for i in range(len(lists))]) # 1-index
if proportional_position:
plt.ylim(0, 1)
plt.yticks(
linspace(0, 1, 11),
[f"{int(p * 100)}%" for p in linspace(0, 1, 11)]
)
else:
plt.ylim(-1, max(len(lst) for lst in lists))
plt.yticks(arange(max(len(lst) for lst in lists)),
[f"Item {i + 1}" for i in range(max(len(lst) for lst in lists))])
# plt.legend()
plt.tight_layout()
plt.savefig(THIS_DIR / "plots" / f"{artist_name}_{tour_name}_cross_tour.pdf")
if __name__ == "__main__":
plot_cross_tour_correspondence(
"Coldplay",
"Music of the Spheres",
proportional_position=True
)