{"id":70,"date":"2024-11-14T06:44:17","date_gmt":"2024-11-14T01:44:17","guid":{"rendered":"http:\/\/localblog.local\/?p=70"},"modified":"2026-06-19T19:09:02","modified_gmt":"2026-06-20T00:09:02","slug":"metal-music-graphs-with-d3","status":"publish","type":"post","link":"https:\/\/alanahryding.me\/blog\/programming\/metal-music-graphs-with-d3\/","title":{"rendered":"Metal (Music) Graphs with Python and D3"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">I am a big metal music fan, and as a lot of metal fans might know, metal musicians&#8217; careers can span multiple bands, and some of the bigger stars will even come together to make a supergroup. I thought it would be fun to see how various bands are related, and luckily, <a href=\"https:\/\/www.metal-archives.com\/bands\/Dissection\/183\">Encyclopedia Metallum<\/a> is a great source. (Metalheads tend to be quite into metal, and <a href=\"https:\/\/www.mic.com\/articles\/119928\/spotify-just-discovered-that-metal-fans-are-way-more-loyal-than-any-other-fans\">loyal<\/a>.)<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Traversal Method<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">My general method of approach was to start with one input band and collect a list of that band&#8217;s members, and for each of those members, iterate over any other band associated with that member.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">One band page provides basic info like the band genre, the years active, origin, etc., along with a list of all members associated with a set of specific info. This info includes the instrument(s) they play\/played (vocals in this case is listed as an instrument), the years associated with the instrument(s), <em>and<\/em> any other bands associated with this person. The associated bands list shows whether or not a band was before&#8211;denoted by an &#8220;ex-&#8221; prefix before the band&#8217;s name, e.g., ex-<a href=\"https:\/\/www.metal-archives.com\/bands\/Gorgoroth\/770\">Gorgoroth<\/a>&#8211;or concurrent with or after this band. This last piece of information is important because it allowed me to make <strong>directed<\/strong> graphs, that is graphs with arrows that denote direction (<a href=\"https:\/\/networkx.org\/documentation\/stable\/reference\/classes\/digraph.html\">read more here<\/a>).<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Diagrams<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The diagram below shows an example of how the traversal worked. Members are enclosed within bands, and associated bands are linked by their respective members, the arrows showing the direction (chronologically) of movement. This is a fairly simple example as most bands usually have more members, thus more bands. <\/p>\n\n\n\n<figure class=\"wp-block-image size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"471\" src=\"https:\/\/alanahryding.me\/blog\/wp-content\/uploads\/2026\/06\/Screenshot-2024-11-13-at-20.59.42-1-1024x471.png\" alt=\"diagram showing how bands are related via members\" class=\"wp-image-371\" style=\"width:730px;height:auto\" srcset=\"https:\/\/alanahryding.me\/blog\/wp-content\/uploads\/2026\/06\/Screenshot-2024-11-13-at-20.59.42-1-1024x471.png 1024w, https:\/\/alanahryding.me\/blog\/wp-content\/uploads\/2026\/06\/Screenshot-2024-11-13-at-20.59.42-1-300x138.png 300w, https:\/\/alanahryding.me\/blog\/wp-content\/uploads\/2026\/06\/Screenshot-2024-11-13-at-20.59.42-1-768x353.png 768w, https:\/\/alanahryding.me\/blog\/wp-content\/uploads\/2026\/06\/Screenshot-2024-11-13-at-20.59.42-1.png 1099w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">The below are different ways of representing the above as graphs. The one on the left is a generic example of the final output graph. On the left, note the arrows showing directions between the bands as well as the line weight. If multiple people travel from one band to another in the same direction, that increases the weight of the edge.  The graph on the right is just a graph of relations between people based on the bands they were in. <\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"732\" height=\"320\" src=\"https:\/\/alanahryding.me\/blog\/wp-content\/uploads\/2026\/06\/Screenshot-2024-11-13-at-21.04.43.png\" alt=\"\" class=\"wp-image-347\" srcset=\"https:\/\/alanahryding.me\/blog\/wp-content\/uploads\/2026\/06\/Screenshot-2024-11-13-at-21.04.43.png 732w, https:\/\/alanahryding.me\/blog\/wp-content\/uploads\/2026\/06\/Screenshot-2024-11-13-at-21.04.43-300x131.png 300w\" sizes=\"auto, (max-width: 732px) 100vw, 732px\" \/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Implementation &amp; Output<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">I implemented a Python script (with <a href=\"https:\/\/selenium-python.readthedocs.io\/\">Selenium<\/a>) to crawl bands and associated bands (using a first in, first out approach), stopping at 3 iterations, writing output to a set of .json\/.csv files and\/or mysql tables. As I didn&#8217;t have a goal of doing any ad hoc traversal or querying, the implementation isn&#8217;t too fancy. And as this was intended to be a POC\/limited project just for fun, I also opted against using Redis and the like, storing files locally should I have to grab the same page again.  <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I used <a href=\"http:\/\/gephi.org\" data-type=\"link\" data-id=\"gephi.org\">Gephi<\/a> initially to explore the data, and eventually moved to <a href=\"https:\/\/d3js.org\/\">D3<\/a> (old version) for rendering the graphs in an .html page. Here are some pages for <a href=\"http:\/\/alanahryding.me\/d3_tests\/inflames_new.html\" data-type=\"link\" data-id=\"http:\/\/alanahryding.me\/d3_tests\/inflames_new.html\">In Flames<\/a> and <a href=\"http:\/\/alanahryding.me\/d3_tests\/necrophobic.html\">Necrophobic<\/a>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Screenshots<\/h3>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"816\" src=\"https:\/\/alanahryding.me\/blog\/wp-content\/uploads\/2026\/06\/dissection_screenshot1-2-1024x816.png\" alt=\"\" class=\"wp-image-368\" srcset=\"https:\/\/alanahryding.me\/blog\/wp-content\/uploads\/2026\/06\/dissection_screenshot1-2-1024x816.png 1024w, https:\/\/alanahryding.me\/blog\/wp-content\/uploads\/2026\/06\/dissection_screenshot1-2-300x239.png 300w, https:\/\/alanahryding.me\/blog\/wp-content\/uploads\/2026\/06\/dissection_screenshot1-2-768x612.png 768w, https:\/\/alanahryding.me\/blog\/wp-content\/uploads\/2026\/06\/dissection_screenshot1-2-1536x1225.png 1536w, https:\/\/alanahryding.me\/blog\/wp-content\/uploads\/2026\/06\/dissection_screenshot1-2-2048x1633.png 2048w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">These are screenshots of <a href=\"https:\/\/www.metal-archives.com\/bands\/Death\/141\">Death<\/a> network maps\/graphs. The various colors represent different genres.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"823\" src=\"https:\/\/alanahryding.me\/blog\/wp-content\/uploads\/2026\/06\/death4-1024x823.png\" alt=\"\" class=\"wp-image-365\" srcset=\"https:\/\/alanahryding.me\/blog\/wp-content\/uploads\/2026\/06\/death4-1024x823.png 1024w, https:\/\/alanahryding.me\/blog\/wp-content\/uploads\/2026\/06\/death4-300x241.png 300w, https:\/\/alanahryding.me\/blog\/wp-content\/uploads\/2026\/06\/death4-768x617.png 768w, https:\/\/alanahryding.me\/blog\/wp-content\/uploads\/2026\/06\/death4-1536x1234.png 1536w, https:\/\/alanahryding.me\/blog\/wp-content\/uploads\/2026\/06\/death4.png 1659w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"598\" src=\"https:\/\/alanahryding.me\/blog\/wp-content\/uploads\/2026\/06\/encyclopediametallum_map_-1024x598.png\" alt=\"\" class=\"wp-image-337\" srcset=\"https:\/\/alanahryding.me\/blog\/wp-content\/uploads\/2026\/06\/encyclopediametallum_map_-1024x598.png 1024w, https:\/\/alanahryding.me\/blog\/wp-content\/uploads\/2026\/06\/encyclopediametallum_map_-300x175.png 300w, https:\/\/alanahryding.me\/blog\/wp-content\/uploads\/2026\/06\/encyclopediametallum_map_-768x449.png 768w, https:\/\/alanahryding.me\/blog\/wp-content\/uploads\/2026\/06\/encyclopediametallum_map_-1536x898.png 1536w, https:\/\/alanahryding.me\/blog\/wp-content\/uploads\/2026\/06\/encyclopediametallum_map_.png 1694w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Future Work?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"> Aside from migrating the code to a different repo and refactoring, I&#8217;ve also explored different, more up-to-date libraries, like <a href=\"https:\/\/dash.plotly.com\/\">Plotly<\/a> (and Dash), and want to use <a href=\"https:\/\/networkx.org\/\">networkx<\/a> a bit more for data management and dynamic queries.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">However, this is a project I started <em>many years<\/em> ago that I eventually got around to reviving temporarily, so I may be ready to move onto finishing one of my many other projects first before committing this code to a publicly available repo as I judge my own code harshly and worry about security, AI, and all the other things out there.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Other Related Stuff for Fun<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">For an extensive (metal) genre map, check out <a href=\"https:\/\/everynoise.com\/#item2946\">Every Noise at Once<\/a>. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For an interesting look into the source, see the <a href=\"https:\/\/alanahryding.me\/blog\/programming\/automated-updating-of-spotify-playlist-of-artists-with-upcoming-shows-draft\/\" data-type=\"post\" data-id=\"107\">genre examples here<\/a>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">At some point I may dig up the pictures I got of my metal-themed alphabet fridge magnets using letters from various metal band logos. I ended up with a couple sets because there were so many options for the letters D, M, G, etc.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I am a big metal music fan, and as a lot of metal fans might know, metal musicians&#8217; careers can span multiple bands, and some of the bigger stars will even come together to make a supergroup. I thought it would be fun to see how various bands are related, and luckily, Encyclopedia Metallum is [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":77,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[12,18,20,22,23,25,26,31,33,41],"class_list":["post-70","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-programming","tag-d3","tag-gephi","tag-graph","tag-metal","tag-music","tag-network","tag-networkx","tag-python","tag-selenium","tag-visualization"],"_links":{"self":[{"href":"https:\/\/alanahryding.me\/blog\/wp-json\/wp\/v2\/posts\/70","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/alanahryding.me\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/alanahryding.me\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/alanahryding.me\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/alanahryding.me\/blog\/wp-json\/wp\/v2\/comments?post=70"}],"version-history":[{"count":2,"href":"https:\/\/alanahryding.me\/blog\/wp-json\/wp\/v2\/posts\/70\/revisions"}],"predecessor-version":[{"id":375,"href":"https:\/\/alanahryding.me\/blog\/wp-json\/wp\/v2\/posts\/70\/revisions\/375"}],"wp:attachment":[{"href":"https:\/\/alanahryding.me\/blog\/wp-json\/wp\/v2\/media?parent=70"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/alanahryding.me\/blog\/wp-json\/wp\/v2\/categories?post=70"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/alanahryding.me\/blog\/wp-json\/wp\/v2\/tags?post=70"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}