Skip to content

malbiruk/artistpath

Repository files navigation

artistpath

Explore music artist networks and discover connections using Last.fm's related artists data.

What is this?

An interactive web application for exploring artist networks and finding paths between artists. Visualize how artists are connected through musical similarity and discover related artists around any musician or along connection paths. Available as both a web interface and command-line tool covering more than 5.5M artists.

image

Artist Discovery

Ever wondered how indie folk connects to experimental electronic music? Or what bridges classic rock and modern trap? artistpath reveals these hidden connections and helps you discover new artists along unexpected musical journeys.

Try exploring paths between artists from completely different genres — you might find amazing artists you've never heard of sitting right in the middle, acting as musical bridges between worlds.

How connections work

Artist connections are based on Last.fm listener overlap — artists are similar if people listen to them together. The graph is directional, meaning that swapping artists gives different results since unpopular artists are often similar to popular ones, but not necessarily the other way around.

Web Interface

The interactive web interface provides visual exploration and pathfinding with real-time network visualization.

Features

  • Artist Exploration: Enter one artist to explore their network of similar artists (use either "from" or "to" field -- will show relations with opposite directions)
  • Path Finding: Enter two artists to find connection paths between them
  • Visual Network: Interactive graph showing artists as nodes and similarities as edges
  • Real-time Search: Instant results as you type and adjust parameters

Settings

  • Algorithm: Toggle between "simple" (BFS) and "weighted" (Dijkstra)
  • Max Relations: Limit connections per artist (1-250)
  • Min Similarity: Filter weak connections (0.0-1.0)
  • Max Artists: Budget limit for exploration/pathfinding (10-500)

Visual Features

  • Blue highlighting: Selected path/explored artist is highlighted in blue
  • Animated connections: Hover/tap on nodes or edges to see running ant animations showing connection direction
  • Bidirectional indicators: When connections exist in both directions, animations overlap creating a "blinking" effect, and the maximum similarity is displayed
  • Dynamic layout: Stronger connections (higher similarity) appear shorter and more rigid in the network
  • Adaptive text size: Artist font size reflects their local importance (connection count relative to the current network)

Algorithms

Both algorithms use bidirectional search for improved performance:

  • Simple (BFS): Wide layer-by-layer exploration, discovers diverse/distant clusters
  • Weighted (Dijkstra): Similarity-based exploration, finds tightly connected clusters and smoother musical transitions

Dataset Information

Current dataset: 5.4M+ artists with similarity connections. Each artist is keyed by its MusicBrainz ID when Last.fm provides one, otherwise a UUID derived from its Last.fm URL. The served binary graph is cleaned (see Data Cleaning); the NDJSON retains every collected artist.

Available formats from releases:

  • Binary format: Required for web/CLI apps - includes indexing and name lookup for fast performance
  • NDJSON format: For research/analysis - human-readable JSON lines:
    • Graph: {"id": uuid, "connections": [[uuid, similarity], ...]}
    • Metadata: {"id": uuid, "name": "Artist Name", "url": "..."}

Requires zstd for decompression (apt install zstd or brew install zstd).

Build Your Own Dataset

  1. Get a Last.fm API key
  2. cd data_collection && uv sync && echo "LASTFM_COLLECTOR_API_KEY=your_key" > .env
  3. uv run python run_collection.py (takes several days!)
  4. uv run python run_postprocessing.py

Requires Python 3.12+ with uv.

Data Cleaning

run_postprocessing.py removes three classes of noise when building the binary graph. It is delete-only — nodes are dropped, never merged, and no edges are rewritten — and the raw NDJSON is never modified (it's kept for incremental collection):

  • Duplicates — the same artist written differently (accents, punctuation, zero-width/stylization junk, homoglyph spoofs). Nodes that share a visual "skeleton" collapse to the highest in-degree spelling; byte-identical names are kept, so genuine same-name-different-artist cases survive.
  • Transliteration variants — the same artist spelled across scripts (a Cyrillic original and its Latin romanizations, e.g. Пошлая Молли / Poshlaya Molly / Poshlaja Molli), which the visual skeleton misses because the spellings share no letters. Names are grouped by a loose transliteration key (folding я=ia/ya/ja, х=kh/h, doubled letters, …) and collapse to the highest in-degree spelling — but only when a direct similarity edge links the spellings in the graph. The look-alike string alone is ~50% reliable (distinct artists often romanize alike, e.g. Russian Мот vs Korean MoT); requiring the edge raises that to ~100%, which limits the reach to dups popular enough to be linked but keeps every merge safe.
  • Collaboration / feature creditsA feat. B, A & B, A, B, C, A x B entries that aren't standalone artists. A name must first split on feat/ft/x or , & / + into ≥2 known artists (a standalone Cyrillic/Greek x look-alike folds to x first, so Russian A Х B credits split too). A feat/ft marker then removes it outright (no real artist is named "… feat. …"); otherwise it's removed if it's far less connected than its members, or if those members actually co-occur in the graph (so the name describes a real pairing, not a coincidence). Real-band shapes are spared — X & The Y backing bands and ≤2-char fragments like AC/DC (→ ac+dc).

All three rules are graph-aware (in-degree, direct similarity edges, and member co-occurrence). Cleaning is on by default; set ARTISTPATH_CLEANING=0 to disable it.

The Story

One summer Sunday in Tbilisi, after band rehearsal, my drummer and I went to a small park with some beers and started sharing music from our phones — you know how it is, one artist leads to another, exploring new sounds together.

That's when it hit me: Spotify shows similar artists, so wouldn't it be cool to build a program that finds the shortest path between any two artists through these musical connections?

I googled around and couldn't find anything like this, so I decided to build it myself. Started with Spotify, but of course they deprecated their similar artists API right when I needed it 🙄

So I switched to Last.fm instead — actually turned out better since they have up to 250 similar artists per artist (compared to Spotify's 80) plus similarity scores, and many users scrobble there their data from Spotify anyway.

The data collection took a couple of days because of API rate limits, ended up with 5.5GB of data and 850,658 unique artists.

Coming from a Python background but wanting to learn Rust, I thought this would be perfect for experimenting with both — Python for data collection, Rust for the actual pathfinding.

For performance, I couldn't load the whole graph into RAM, so I skipped the fancy graph libraries and implemented BFS and Dijkstra manually with binary files and memory mapping. Now most searches run in under a second!

I'm a musician myself — check out flowersinyoureyes.com if you're curious about my band "flowers in your eyes".

Support

If you find this project useful and want to support its development:

Support on Boosty

Run Locally

Standalone CLI Tool

cargo install artistpath

The CLI binary installs to ~/.cargo/bin/ and automatically downloads dataset to ~/.artistpath/ on first run.

Web Interface (Development)

For running the web interface locally:

git clone https://github.com/malbiruk/artistpath
cd artistpath

# Download and extract binary data (required for web app)
wget https://github.com/malbiruk/artistpath/releases/download/data-v1.0.0/artistpath-data-850k-binary.tar.zst
tar -I zstd -xvf artistpath-data-850k-binary.tar.zst -C data/

# Setup environment
cp .env.example .env
# Edit .env and add your Last.fm API key (for fetching artist cards)
# Put `const API_BASE_URL = "http://localhost:3050/api";` in web/frontend/src/config.js

# Start backend
cd web/backend
cargo run --release

# Start frontend (new terminal)
cd web/frontend
npm install
npm run dev

Open http://localhost:3001 in your browser.

Command Line Usage

The CLI version focuses on pathfinding between two specific artists.

Usage: artistpath [OPTIONS] <ARTIST1> <ARTIST2>

Arguments:
  <ARTIST1>  First artist name
  <ARTIST2>  Second artist name

Options:
      --data-path <PATH>        Path to data directory (defaults to ~/.artistpath/, auto-downloads if not found)
  -m, --min-match <SIMILARITY>  Only use connections with similarity >= threshold (0.0-1.0) [default: 0.0]
  -t, --top-related <COUNT>     Limit to top N connections per artist [default: 80]
  -w, --weighted                Use weighted pathfinding for best similarity (default: shortest path)
  -u, --hide-urls               Hide artist URLs from output (URLs shown by default)
  -i, --show-ids                Show artist UUIDs in output
  -s, --show-similarity         Show similarity scores between connected artists
      --no-color                Disable colored output
  -v, --verbose                 Verbose mode - show search info and statistics
  -q, --quiet                   Quiet mode - only show the path flow
      --json                    Output as JSON format
  -h, --help                    Print help

Example

$ artistpath "Taylor Swift" "Metallica"

"Taylor Swift" → "Halsey" → "Poppy" → "Slipknot" → "Metallica"

1. "Taylor Swift" - https://www.last.fm/music/Taylor+Swift
2. "Halsey" - https://www.last.fm/music/Halsey
3. "Poppy" - https://www.last.fm/music/Poppy
4. "Slipknot" - https://www.last.fm/music/Slipknot
5. "Metallica" - https://www.last.fm/music/Metallica

Try These Connections

Explore some unexpected musical bridges (use weighted algorithm for more gradual transitions):

  • Classical to Hip-Hop: "Johann Sebastian Bach" "Kendrick Lamar"
  • Country to Electronic: "Johnny Cash" "Aphex Twin"
  • Jazz to Death Metal: "Miles Davis" "Cannibal Corpse"
  • Folk to Trap: "Bob Dylan" "Future"

You'll discover artists you never knew existed, sitting right at the crossroads of different musical worlds.

License

About

Interactive music artists network explorer, finding the shortest connection paths between them using Last.fm's related artists data.

Topics

Resources

License

GPL-3.0, Unknown licenses found

Licenses found

GPL-3.0
LICENSE-CODE
Unknown
LICENSE-DATA

Stars

11 stars

Watchers

0 watching

Forks

Contributors