Skip to content

Commit e12d9c9

Browse files
committed
Final changes vignette
1 parent 2503b59 commit e12d9c9

2 files changed

Lines changed: 26 additions & 18 deletions

File tree

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
.pytest_cache/
88
.coverage
99

10+
# Jupyter notebook checkpoints
11+
**.ipynb_checkpoints
12+
1013
# CSV track lists: ignore all by default so a real personal Spotify/Exportify
1114
# export can't be committed by accident. The synthetic test fixture is the
1215
# only CSV that belongs in the repo, so it is explicitly re-included.

docs/vignette.ipynb

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
"cells": [
33
{
44
"cell_type": "markdown",
5+
"id": "07fbefe9",
56
"metadata": {},
67
"source": [
78
"# `playlistsmith`"
@@ -44,7 +45,7 @@
4445
"id": "c718ee1c",
4546
"metadata": {},
4647
"source": [
47-
"## 1. Obtain a .csv of you playlist\n",
48+
"## 1. Obtain a .csv of your playlist\n",
4849
"The package expects a .csv of the format that [Exportify](https://exportify.app/) provides. You can log-in with your Spotify account to see a list of your playlists. Simply press the \"Export\" button on the right, and you are ready to go. "
4950
]
5051
},
@@ -77,14 +78,14 @@
7778
"## 3. Upload the .csv\n",
7879
"After starting up the GUI, you'll find yourself looking at the screen below. Note that you can ignore the sidebar as only one feature extraction method is implemented at the moment.\n",
7980
"\n",
80-
"![csv_upload](./gui_screenshots/csv_upload.png){width=800px}\n",
81+
"<img src=\"./gui_screenshots/csv_upload.png\" alt=\"csv_upload\" width=\"800\">\n",
8182
"\n",
82-
"If you press the \"Upload\" button (indicated by the red box in the screenshot), you can select a .csv from you local drive to upload. Choose the Exportify generated file here.\n",
83+
"If you press the \"Upload\" button (indicated by the red box in the screenshot), you can select a .csv from your local drive to upload. Choose the Exportify generated file here.\n",
8384
"\n",
8485
"### 3.1 Running example\n",
8586
"For illustration, I created a mix of classical and rock music. After uploading the data, you can inspect the first 20 songs using the \"Preview tracklist\" expander. The first songs of the running example are shown below.\n",
8687
"\n",
87-
"![tracklist_preview](./gui_screenshots/tracklist_preview.png){width=800px}"
88+
"<img src=\"./gui_screenshots/tracklist_preview.png\" alt=\"tracklist_preview\" width=\"800\">"
8889
]
8990
},
9091
{
@@ -95,12 +96,12 @@
9596
"## 4. Extract features\n",
9697
"Scrolling down will reveal an expander with a list of features and an \"Extract features\" button. This will query the [ReccoBeats](https://reccobeats.com/) API for precomputed features.\n",
9798
"\n",
98-
"![feature_extraction](./gui_screenshots/feature_extraction.png){width=800px}\n",
99+
"<img src=\"./gui_screenshots/feature_extraction.png\" alt=\"feature_extraction\" width=\"800\">\n",
99100
"\n",
100101
"### 4.1 Running example\n",
101102
"Extracting features from the example playlist induces the following coverage report:\n",
102103
"\n",
103-
"![coverage_report](./gui_screenshots/coverage_report.png){width=800px}\n",
104+
"<img src=\"./gui_screenshots/coverage_report.png\" alt=\"coverage_report\" width=\"800\">\n",
104105
"\n",
105106
"Songs included in the table are not covered by ReccoBeats and therefore excluded from the analysis."
106107
]
@@ -113,19 +114,21 @@
113114
"## 5. Clustering\n",
114115
"Now, this is where the magic happens: running a clustering algorithm on the playlist to discover sub-collections of songs. `playlistsmith` offers three algorithms: a Gaussian Mixture Model (GMM), K-means and Hierarchical Density-Based Spatial Clustering of Applications with Noise (HDBSCAN). While the algorithms are described in a bit more detail in the info strings accessible by hovering over the \"?\" icon, suffice it to say here that GMM is suitable for most applications, K-means can be run in small samples or as a sanity check in addition to the GMM, and HDBSCAN is useful if you suspect that your playlist includes songs that are unique so that they would likely not fit into any sub-playlist. \n",
115116
"\n",
116-
"![algorithms](./gui_screenshots/algorithms.png){width=800px}\n",
117+
"<img src=\"./gui_screenshots/algorithms.png\" alt=\"algorithms\" width=\"800\">\n",
117118
"\n",
118119
"Before we can start clustering, we should take a minute to think about hyperparameters—settings that influence the outcome of each algorithm (more information accessible by hovering over the \"?\"). As we are going to run the GMM below, let's quickly discuss the choices made:\n",
119120
"\n",
120121
"1. `min_playlist_size`: What is the minimum amount of songs you would like to have in the sub-playlists? Smaller clusters will be assigned to an unclassified class. We stick with 5 (the default).\n",
121122
"2. `max_playlist_share`: The proportion of uploaded tracks a sub-playlist is maximally allowed to contain before returning a warning. As we know that two playlists underlie our running example and that they are unequal in size, the default (0.5) seems unreasonable. We opt for 0.65.\n",
122-
"3. `k range`: The range of cluster numbers to test and compare. The algorithm will be fit to discover each number of clusters within this range and the best fit will be retained. As we have a clear idea about how many clusters we would like to find, we select 2 by just dragging the knobs on top of each other[^1].\n",
123+
"3. `k range`: The range of cluster numbers to test and compare. The algorithm will be fit to discover each number of clusters within this range and the best fit will be retained. As we have a clear idea about how many clusters we would like to find, we select 2 by just dragging the knobs on top of each other<sup id=\"ref1-c7\"><a href=\"#fn1-c7\">1</a></sup>.\n",
123124
"\n",
124-
"![hyperparameters_cluster](./gui_screenshots/hyperparameters_cluster.png){width=800px}\n",
125+
"<img src=\"./gui_screenshots/hyperparameters_cluster.png\" alt=\"hyperparameters_cluster\" width=\"800\">\n",
125126
"\n",
126127
"Press \"Cluster\" to run the algorithm.\n",
127128
"\n",
128-
"[^1]: You can also try to fit a range of clusters, but the GMM will still discover that two clusters fit the data best."
129+
"\n",
130+
"---\n",
131+
"<p id=\"fn1-c7\" style=\"font-size:0.85em\"><sup>1</sup> You can also try to fit a range of clusters, but the GMM will still discover that two clusters fit the data best. <a href=\"#ref1-c7\">↩</a></p>\n"
129132
]
130133
},
131134
{
@@ -137,11 +140,11 @@
137140
"### 6.1 Running example\n",
138141
"If you select a range for k, the number of found clusters is determined based on fit indices. The \"Per-cluster z-profile heatmap\" indicates how songs in each cluster score on the extracted features on average.\n",
139142
"\n",
140-
"![heatmap](./gui_screenshots/heatmap.png){width=800px}\n",
143+
"<img src=\"./gui_screenshots/heatmap.png\" alt=\"heatmap\" width=\"800\">\n",
141144
"\n",
142145
"In the present example, Cluster 1 (bottom row) seems to score high on energy and loudness while Cluster 0 scores low on both of these features. This provides some evidence that Cluster 1 contains the rock songs whereas Cluster 0 is made up of classical songs. This is supported by the visualisation output in the GUI. Hovering over the data points shows the song title as well as artist names.\n",
143146
"\n",
144-
"![cluster_visualisation](./gui_screenshots/cluster_visualisation.png){width=800px}\n",
147+
"<img src=\"./gui_screenshots/cluster_visualisation.png\" alt=\"cluster_visualisation\" width=\"800\">\n",
145148
"\n",
146149
"A quick scan through both clusters confirms that Cluster 0 consists of classical songs and Cluster 1 of rock songs."
147150
]
@@ -155,12 +158,14 @@
155158
"The final stage in the GUI is exporting the created playlists as .csv files. \n",
156159
"\n",
157160
"### 7.1 Running example\n",
158-
"![export](./gui_screenshots/export.png){width=800px}\n",
161+
"<img src=\"./gui_screenshots/export.png\" alt=\"export\" width=\"800\">\n",
162+
"\n",
163+
"You can specify the output directory<sup id=\"ref1-c9\"><a href=\"#fn1-c9\">1</a></sup>, choose to also export the unclassified songs<sup id=\"ref2-c9\"><a href=\"#fn2-c9\">2</a></sup>, or write a combined file that includes the cluster assignment in a separate column. Additionally, you can rename the .csv files (last column in the table). Ready to export? Simply click \"Write CSVs\".\n",
159164
"\n",
160-
"You can specify the output directory[^1], choose to also export the unclassified songs[^2], or write a combined file that includes the cluster assignment in a separate column. Additionally, you can rename the .csv files (last column in the table). Ready to export? Simply click \"Write CSVs\".\n",
161165
"\n",
162-
"[^1]: If the directory does not exist, it will be created.\n",
163-
"[^2]: This is common when using HDBSCAN or when a playlist smaller than `min_playlist_size` is discovered.\n"
166+
"---\n",
167+
"<p id=\"fn1-c9\" style=\"font-size:0.85em\"><sup>1</sup> If the directory does not exist, it will be created. <a href=\"#ref1-c9\">↩</a></p>\n",
168+
"<p id=\"fn2-c9\" style=\"font-size:0.85em\"><sup>2</sup> This is common when using HDBSCAN or when a playlist smaller than <code>min_playlist_size</code> is discovered. <a href=\"#ref2-c9\">↩</a></p>\n"
164169
]
165170
},
166171
{
@@ -175,7 +180,7 @@
175180
"3. Open the Spotify desktop app and create a new playlist. \n",
176181
"4. Press CMD + V/CTRL + V to paste the songs into the playlist. \n",
177182
"\n",
178-
"And voilà, you have split up your tediously long playlist into smaller chunks. Hopefully, you'll find the right song for your mood faster next time!\n",
183+
"And voilà, you have split up your tediously long playlist into smaller chunks. Hopefully, you'll find the right song for your mood faster next time! Want to split up another playlist? Press \"Reset session\" in the sidebar, and you can start fresh.\n",
179184
"\n",
180185
"If you are only interested in using the GUI, you should be ready to go now. For users who prefer the pure Python experience and who are interested in the internal workings of `playlistsmith`, I'll quickly mirror the above-mentioned steps using the underlying package."
181186
]
@@ -189,7 +194,7 @@
189194
"\n",
190195
"Before turning to the Python usage, here is how the GUI steps you just saw map onto the underlying functions. The right column (*User*) is exactly the click-path from sections 1–8. The left column (*Software*) is the code each click triggers. The dashed box marks everything that a single `ps.cluster(...)` call wraps: Preprocessing, the fit, ordering, the small-cluster collapse and interpretation all happen inside that one function. The pure-Python usage in the next section walks the same software path, just through calling `playlistsmith`'s publicly exported functions.\n",
191196
"\n",
192-
"![mermaid_diagram](./gui_screenshots/mermaid_diagram.png){width=1000px}"
197+
"<img src=\"./gui_screenshots/mermaid_diagram.png\" alt=\"mermaid_diagram\" width=\"1000\">"
193198
]
194199
},
195200
{

0 commit comments

Comments
 (0)