{"id":249,"date":"2023-02-06T18:31:29","date_gmt":"2023-02-06T23:31:29","guid":{"rendered":"https:\/\/jazzgraphs.com\/wordpress\/?p=249"},"modified":"2024-02-04T22:36:38","modified_gmt":"2024-02-04T22:36:38","slug":"six-new-saxophonist-networks","status":"publish","type":"post","link":"https:\/\/jazzgraphs.com\/wp2\/2023\/02\/06\/six-new-saxophonist-networks\/","title":{"rendered":"Six New Saxophonist Networks"},"content":{"rendered":"\r\n<div class=\"boldgrid-section\">\r\n<div class=\"container\">\r\n<div class=\"row\">\r\n<div class=\"col-lg-12 col-md-12 col-xs-12 col-sm-12\">\r\n<p>Decided to play with the latest version of Gephi by creating a new musician network, and wound up creating six using MusicBrainz data. This was a fun project and will be followed by additional work covering more great jazz musicians. Here&#8217;s a quick screenshot of one of the graphs showing the artist, album releases, and songs associated with those releases:<\/p>\r\n<\/div>\r\n<\/div>\r\n<\/div>\r\n<\/div>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image size-large\">\r\n<p class=\"mod-reset\"><img decoding=\"async\" class=\"wp-image-261\" src=\"https:\/\/jazzgraphs.com\/wordpress\/wp-content\/uploads\/2023\/02\/dexter_gordon-1024x479.png\" alt=\"\"><\/p>\r\n<figcaption class=\"wp-element-caption\">Dexter Gordon music network<\/figcaption>\r\n<\/figure>\r\n\r\n\r\n\r\n<div class=\"boldgrid-section\">\r\n<div class=\"container\">\r\n<div class=\"row\">\r\n<div class=\"col-lg-12 col-md-12 col-xs-12 col-sm-12\">\r\n<p>I&#8217;ll post the links to each network below and then take a walk through the creation process. Note that the graphs are all interactive, with panning, zooming, edge removal, and other features all available. More on those features later in the post. Here are the links to each network graph:<\/p>\r\n<ul>\r\n<li><a href=\"https:\/\/jazzgraphs.com\/graphs\/dexter_gordon\/\" target=\"_blank\" rel=\"noreferrer noopener\" data-type=\"URL\" data-id=\"https:\/\/jazzgraphs.com\/graphs\/dexter_gordon\/\">Dexter Gordon<\/a><\/li>\r\n\r\n\r\n\r\n<li><a href=\"https:\/\/jazzgraphs.com\/graphs\/sonny_rollins\" target=\"_blank\" rel=\"noreferrer noopener\" data-type=\"URL\" data-id=\"https:\/\/jazzgraphs.com\/graphs\/sonny_rollins\">Sonny Rollins<\/a><\/li>\r\n\r\n\r\n\r\n<li><a href=\"https:\/\/jazzgraphs.com\/graphs\/coleman_hawkins\" target=\"_blank\" rel=\"noreferrer noopener\" data-type=\"URL\" data-id=\"https:\/\/jazzgraphs.com\/graphs\/coleman_hawkins\">Coleman Hawkins<\/a><\/li>\r\n\r\n\r\n\r\n<li><a href=\"https:\/\/jazzgraphs.com\/graphs\/lester_young\" target=\"_blank\" rel=\"noreferrer noopener\" data-type=\"URL\" data-id=\"https:\/\/jazzgraphs.com\/graphs\/lester_young\">Lester Young<\/a><\/li>\r\n\r\n\r\n\r\n<li><a href=\"https:\/\/jazzgraphs.com\/graphs\/stan_getz\" target=\"_blank\" rel=\"noreferrer noopener\" data-type=\"URL\" data-id=\"https:\/\/jazzgraphs.com\/graphs\/stan_getz\">Stan Getz<\/a><\/li>\r\n\r\n\r\n\r\n<li><a href=\"https:\/\/jazzgraphs.com\/graphs\/kenny_garrett\" target=\"_blank\" rel=\"noreferrer noopener\" data-type=\"URL\" data-id=\"https:\/\/jazzgraphs.com\/graphs\/kenny_garrett\">Kenny Garrett<\/a><\/li>\r\n<\/ul>\r\n<p>Note that there are at least two major omissions among saxophonists &#8211; Charlie Parker and John Coltrane, and of course some other notable names. I&#8217;ll plan to address those omissions in a future post.<\/p>\r\n<p class=\"\">To create each of these graphs I followed a simple set of steps and then used the same settings to create graphs with a consistent look &amp; feel. The goal is to have users focus on the structure and content of the network as opposed to having to deal with changing shapes, sizes, and colors. Perhaps I&#8217;ll alter this for different instruments &#8211; piano or trumpet, for example may have a different color palette. For now, the color palette I have used conveys an appropriately jazzy aura, with the dark background and contrasting pastel-like node colors and subtle gray edges connecting the nodes.<\/p>\r\n<p>The data for this project is sourced from the impressive <a href=\"https:\/\/musicbrainz.org\" target=\"_blank\" rel=\"noreferrer noopener\" data-type=\"URL\" data-id=\"https:\/\/musicbrainz.org\">MusicBrainz<\/a> database. Note that MusicBrainz data covers many genres beyond jazz, but for my current purposes the focus is on jazz. I have created a local version of the data using <a href=\"https:\/\/dbeaver.io\" target=\"_blank\" rel=\"noreferrer noopener\" data-type=\"URL\" data-id=\"https:\/\/dbeaver.io\">DBeaver<\/a> for writing and running SQL queries to retrieve data for ingestion by Gephi. DBeaver is a great solution for me &#8211; all of my other databases are in MySQL, while the MusicBrainz data is in PostgreSQL format. No problem, as DBeaver can handle both types (as well as many other data formats) with ease.<\/p>\r\n<p>Here&#8217;s an example of the code used for node creation for Sonny Rollins:<\/p>\r\n<\/div>\r\n<\/div>\r\n<\/div>\r\n<\/div>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<pre class=\"wp-block-code has-small-font-size\"><code><em>SELECT a.* \r\nFROM\r\n((SELECT CONCAT(ac.name, ' (Artist)') AS id, ac.name AS name, ac.name AS label, 'Artist' AS type, 50 AS size\r\n\r\nFROM public.artist_credit ac\r\n\r\nWHERE ac.id = 21832)\r\n\r\nUNION ALL\r\n\r\n(SELECT CONCAT(r.name, ' (Release)') AS id, r.name AS name, r.name AS label, 'Release' AS type, COUNT(DISTINCT rl.release) AS size\r\n\r\nFROM public.release r\r\nINNER JOIN public.artist_credit ac\r\nON r.artist_credit = ac.id\r\nINNER JOIN public.medium m \r\nON r.id = m.release\r\nINNER JOIN public.medium_format mf \r\nON m.format = mf.id\r\nINNER JOIN public.release_label rl\r\nON r.id = rl.release\r\nINNER JOIN public.label l\r\nON rl.label = l.id\r\n\r\nWHERE r.artist_credit = 21832 \r\nGROUP BY r.name\r\n)\r\n\r\nUNION ALL \r\n\r\n(SELECT CONCAT(ta.name, ' (Song)') AS id, ta.name AS name, ta.name AS label, 'Song' AS type, COUNT(DISTINCT rl.release)\r\nAS Size\r\nFROM public.release r\r\nINNER JOIN public.artist_credit ac\r\nON r.artist_credit = ac.id\r\nINNER JOIN public.medium m \r\nON r.id = m.release\r\nINNER JOIN public.medium_format mf \r\nON m.format = mf.id\r\nINNER JOIN public.release_label rl\r\nON r.id = rl.release\r\nINNER JOIN public.label l\r\nON rl.label = l.id\r\nINNER JOIN public.track t\r\nON m.id = t.medium\r\nINNER JOIN public.track_aggregate ta\r\nON t.name = ta.name\r\n\r\nWHERE r.artist_credit = 21832 \r\nGROUP BY ta.name\r\n)) a<\/em>\r\n<\/code><\/pre>\r\n\r\n\r\n\r\n<div class=\"boldgrid-section\">\r\n<div class=\"container\">\r\n<div class=\"row\">\r\n<div class=\"col-lg-12 col-md-12 col-xs-12 col-sm-12\">\r\n<p>While the code may appear complex, it&#8217;s goal is simple &#8211; retrieve all releases and songs for the artist Sonny Rollins, who has the &#8216;21832&#8217; id. This code creates nodes for the artist (first section), all releases (second section) and all songs (third section). It uses the UNION ALL statement to combine the three sections into a single output file.<\/p>\r\n<p>We then run similar code to create an edges source file:<\/p>\r\n<\/div>\r\n<\/div>\r\n<\/div>\r\n<\/div>\r\n\r\n\r\n\r\n\r\n\r\n<pre class=\"wp-block-code has-small-font-size\"><code><em>SELECT a.*\r\nFROM\r\n((SELECT CONCAT(ac.name, ' (Artist)') AS source, CONCAT(r.name, ' (Release)') AS Target, 'Artist' AS source_type, 'Release' AS target_type\r\nFROM public.artist_credit ac\r\nINNER JOIN public.release r\r\nON ac.id = r.artist_credit\r\nINNER JOIN public.release_label rl\r\nON r.id = rl.release\r\nWHERE ac.id = 21832)\r\n\r\nUNION ALL\r\n\r\n(SELECT CONCAT(r.name, ' (Release)') AS Source, CONCAT(ta.name, ' (Song)') AS Target, 'Release' AS source_type, 'Song' AS target_type\r\nFROM public.release r\r\nINNER JOIN public.release_label rl\r\nON r.id = rl.release\r\nINNER JOIN public.medium m\r\nON r.id = m.release\r\nINNER JOIN public.track t\r\nON m.id = t.medium\r\nINNER JOIN public.track_aggregate ta\r\n ON t.name = ta.name\r\n \r\nWHERE r.artist_credit = 21832)) a\r\nGROUP BY a.source, a.target, a.source_type, a.target_type<\/em><\/code><\/pre>\r\n\r\n\r\n\r\n<div class=\"boldgrid-section\">\r\n<div class=\"container\">\r\n<div class=\"row\">\r\n<div class=\"col-lg-12 col-md-12 col-xs-12 col-sm-12\">\r\n<p>This output will instruct Gephi to use the artist as a source node and all releases as target nodes (first section) and then to use all releases as source nodes with songs as target nodes. Think of this as a hierarchy of Artist &#8211;&gt; Releases &#8211;&gt; Songs where individual songs are associated with the release they appeared on. Of course, in jazz, many of the most popular songs will appear connected to multiple releases, ultimately making for a more interesting graph.<\/p>\r\n<p>Now that we have created the source files, let&#8217;s shift to Gephi to see how we use them.<\/p>\r\n<p>Gephi allows us to pull in spreadsheet files as long as they meet certain criteria. Node files should have a name, label, id, and preferably a size attribute, although this can be created within Gephi based on the data. Edge files must have source and target fields, and ideally a weight value corresponding to the strength of network connections.<\/p>\r\n<p>Here&#8217;s our data after ingestion, starting with the nodes:<\/p>\r\n<\/div>\r\n<\/div>\r\n<\/div>\r\n<\/div>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<figure class=\"wp-block-image size-large is-resized\">\r\n<p class=\"mod-reset\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"535\" class=\"wp-image-450\" style=\"object-fit: cover; width: 842px; height: 500px;\" src=\"https:\/\/jazzgraphs.com\/wp2\/wp-content\/uploads\/2024\/02\/sax_nodes_20230206-1024x535.png\" alt=\"\" srcset=\"https:\/\/jazzgraphs.com\/wp2\/wp-content\/uploads\/2024\/02\/sax_nodes_20230206-1024x535.png 1024w, https:\/\/jazzgraphs.com\/wp2\/wp-content\/uploads\/2024\/02\/sax_nodes_20230206-300x157.png 300w, https:\/\/jazzgraphs.com\/wp2\/wp-content\/uploads\/2024\/02\/sax_nodes_20230206-768x401.png 768w, https:\/\/jazzgraphs.com\/wp2\/wp-content\/uploads\/2024\/02\/sax_nodes_20230206.png 1280w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/p>\r\n<figcaption class=\"wp-element-caption\">Dexter Gordon nodes in Gephi<\/figcaption>\r\n<\/figure>\r\n\r\n\r\n\r\n<div class=\"boldgrid-section\">\r\n<div class=\"container\">\r\n<div class=\"row\">\r\n<div class=\"col-lg-12 col-md-12 col-xs-12 col-sm-12\">\r\n<p>I forget to mention the usefulness of having a &#8216;type&#8217; column; this will make it simple to set node colors in Gephi. Now the edges file:<\/p>\r\n<\/div>\r\n<\/div>\r\n<\/div>\r\n<\/div>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image size-large\">\r\n<p class=\"mod-reset\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"533\" class=\"wp-image-449\" src=\"https:\/\/jazzgraphs.com\/wp2\/wp-content\/uploads\/2024\/02\/sax_edges_20230206-1024x533.png\" alt=\"\" srcset=\"https:\/\/jazzgraphs.com\/wp2\/wp-content\/uploads\/2024\/02\/sax_edges_20230206-1024x533.png 1024w, https:\/\/jazzgraphs.com\/wp2\/wp-content\/uploads\/2024\/02\/sax_edges_20230206-300x156.png 300w, https:\/\/jazzgraphs.com\/wp2\/wp-content\/uploads\/2024\/02\/sax_edges_20230206-768x400.png 768w, https:\/\/jazzgraphs.com\/wp2\/wp-content\/uploads\/2024\/02\/sax_edges_20230206.png 1280w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/p>\r\n<figcaption class=\"wp-element-caption\">Dexter Gordon edges in Gephi<\/figcaption>\r\n<\/figure>\r\n\r\n\r\n\r\n<div class=\"boldgrid-section\">\r\n<div class=\"container\">\r\n<div class=\"row\">\r\n<div class=\"col-lg-12 col-md-12 col-xs-12 col-sm-12\">\r\n<p>You can see the source and target values, which are critical to how the graph will be displayed. Our edge weights are all set to 1 in this network, but frequently we will have varying numbers to indicate stronger versus weaker connections.<\/p>\r\n<p>Here&#8217;s our completed graph in Gephi, after using a number of settings:<\/p>\r\n<ul>\r\n<li>Setting the node colors by type in the Partition tab<\/li>\r\n\r\n\r\n\r\n<li>Sizing the nodes in the Ranking tab<\/li>\r\n\r\n\r\n\r\n<li>Choosing a layout algorithm &#8211; Force Atlas 2 is a popular choice<\/li>\r\n\r\n\r\n\r\n<li>Scaling the graph to an appropriate size<\/li>\r\n\r\n\r\n\r\n<li>Preventing overlap of nodes<\/li>\r\n<\/ul>\r\n<p>This process can be very iterative, playing with different settings until you are pleased with the results. For graphs like this with hundreds of nodes, different options can be tried very quickly.<\/p>\r\n<\/div>\r\n<\/div>\r\n<\/div>\r\n<\/div>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n<figure class=\"wp-block-image size-full\">\r\n<p class=\"mod-reset\"><img loading=\"lazy\" decoding=\"async\" width=\"941\" height=\"661\" class=\"wp-image-458\" src=\"https:\/\/jazzgraphs.com\/wp2\/wp-content\/uploads\/2024\/02\/gordon_graph_20230206-1.png\" alt=\"\" srcset=\"https:\/\/jazzgraphs.com\/wp2\/wp-content\/uploads\/2024\/02\/gordon_graph_20230206-1.png 941w, https:\/\/jazzgraphs.com\/wp2\/wp-content\/uploads\/2024\/02\/gordon_graph_20230206-1-300x211.png 300w, https:\/\/jazzgraphs.com\/wp2\/wp-content\/uploads\/2024\/02\/gordon_graph_20230206-1-768x539.png 768w\" sizes=\"auto, (max-width: 941px) 100vw, 941px\" \/><\/p>\r\n<figcaption class=\"wp-element-caption\">Dexter Gordon graph in Gephi<\/figcaption>\r\n<\/figure>\r\n\r\n\r\n\r\n<div class=\"boldgrid-section\">\r\n<div class=\"container\">\r\n<div class=\"row\">\r\n<div class=\"col-lg-12 col-md-12 col-xs-12 col-sm-12\">\r\n<p>The next step is to export the underlying data as a graph file &#8211; .gexf is my choice for the web template I use. Here&#8217;s a small subset of the Dexter Gordon .gexf file showing the name, type, and size associated with each node.<\/p>\r\n<\/div>\r\n<\/div>\r\n<\/div>\r\n<\/div>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image size-full\">\r\n<p class=\"mod-reset\"><img loading=\"lazy\" decoding=\"async\" width=\"596\" height=\"500\" class=\"wp-image-453\" src=\"https:\/\/jazzgraphs.com\/wp2\/wp-content\/uploads\/2024\/02\/gexf_20230206.png\" alt=\"\" srcset=\"https:\/\/jazzgraphs.com\/wp2\/wp-content\/uploads\/2024\/02\/gexf_20230206.png 596w, https:\/\/jazzgraphs.com\/wp2\/wp-content\/uploads\/2024\/02\/gexf_20230206-300x252.png 300w\" sizes=\"auto, (max-width: 596px) 100vw, 596px\" \/><\/p>\r\n<figcaption class=\"wp-element-caption\">Data from the Dexter Gordon .gexf file<\/figcaption>\r\n<\/figure>\r\n\r\n\r\n\r\n<div class=\"boldgrid-section\">\r\n<div class=\"container\">\r\n<div class=\"row\">\r\n<div class=\"col-lg-12 col-md-12 col-xs-12 col-sm-12\">\r\n<p>Next, we can update settings in the config.js file; These will adjust the display parameters for the nodes and edges; note that there is also a .css (Cascading Style Sheet) file where many more modifications can be made.<\/p>\r\n<\/div>\r\n<\/div>\r\n<\/div>\r\n<\/div>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image size-full\">\r\n<p class=\"mod-reset\"><img loading=\"lazy\" decoding=\"async\" width=\"486\" height=\"511\" class=\"wp-image-454\" src=\"https:\/\/jazzgraphs.com\/wp2\/wp-content\/uploads\/2024\/02\/configjs_20230206.png\" alt=\"\" srcset=\"https:\/\/jazzgraphs.com\/wp2\/wp-content\/uploads\/2024\/02\/configjs_20230206.png 486w, https:\/\/jazzgraphs.com\/wp2\/wp-content\/uploads\/2024\/02\/configjs_20230206-285x300.png 285w\" sizes=\"auto, (max-width: 486px) 100vw, 486px\" \/><\/p>\r\n<figcaption class=\"wp-element-caption\">Set graph options in the config.js file<\/figcaption>\r\n<\/figure>\r\n\r\n\r\n\r\n<div class=\"boldgrid-section\">\r\n<div class=\"container\">\r\n<div class=\"row\">\r\n<div class=\"col-lg-12 col-md-12 col-xs-12 col-sm-12\">\r\n<p>Finally, we have the index.html file that contains links to several scripts as well as the config file. This is where we can also add a title and small bits of information about the graph content.<\/p>\r\n<\/div>\r\n<\/div>\r\n<\/div>\r\n<\/div>\r\n\r\n\r\n\r\n<figure class=\"wp-block-image size-full\">\r\n<p class=\"mod-reset\"><img loading=\"lazy\" decoding=\"async\" width=\"565\" height=\"511\" class=\"wp-image-452\" src=\"https:\/\/jazzgraphs.com\/wp2\/wp-content\/uploads\/2024\/02\/index_20230206.png\" alt=\"\" srcset=\"https:\/\/jazzgraphs.com\/wp2\/wp-content\/uploads\/2024\/02\/index_20230206.png 565w, https:\/\/jazzgraphs.com\/wp2\/wp-content\/uploads\/2024\/02\/index_20230206-300x271.png 300w\" sizes=\"auto, (max-width: 565px) 100vw, 565px\" \/><\/p>\r\n<figcaption class=\"wp-element-caption\">The index.html file is used for titles, script references, and other display options<\/figcaption>\r\n<\/figure>\r\n\r\n\r\n\r\n<div class=\"boldgrid-section\">\r\n<div class=\"container\">\r\n<div class=\"row\">\r\n<div class=\"col-lg-12 col-md-12 col-xs-12 col-sm-12\">\r\n<p>I&#8217;ll be creating additional network graphs using this same end to end approach. The process becomes easier once the code has been tested and validated, and the settings have been standardized in Gephi and the resulting output files; much of the effort will simply involve copying and pasting existing settings. Watch this space for new graphs, and thanks for reading!<\/p>\r\n<p>&nbsp;<\/p>\r\n<\/div>\r\n<\/div>\r\n<\/div>\r\n<\/div>\r\n\r\n\r\n","protected":false},"excerpt":{"rendered":"<p>Decided to play with the latest version of Gephi by creating a new musician network, and wound up creating six using MusicBrainz data. This was a fun project and will be followed by additional work covering more great jazz musicians. Here&#8217;s a quick screenshot of one of the graphs showing the artist, album releases, and [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3,4],"tags":[20,16,6,22,21,7,19,11],"class_list":["post-249","post","type-post","status-publish","format-standard","hentry","category-jazz","category-network-graph","tag-coleman-hawkins","tag-dexter-gordon","tag-gephi","tag-kenny-garrett","tag-lester-young","tag-sigma-js","tag-sonny-rollins","tag-stan-getz"],"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/jazzgraphs.com\/wp2\/wp-json\/wp\/v2\/posts\/249","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/jazzgraphs.com\/wp2\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/jazzgraphs.com\/wp2\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/jazzgraphs.com\/wp2\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/jazzgraphs.com\/wp2\/wp-json\/wp\/v2\/comments?post=249"}],"version-history":[{"count":22,"href":"https:\/\/jazzgraphs.com\/wp2\/wp-json\/wp\/v2\/posts\/249\/revisions"}],"predecessor-version":[{"id":522,"href":"https:\/\/jazzgraphs.com\/wp2\/wp-json\/wp\/v2\/posts\/249\/revisions\/522"}],"wp:attachment":[{"href":"https:\/\/jazzgraphs.com\/wp2\/wp-json\/wp\/v2\/media?parent=249"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/jazzgraphs.com\/wp2\/wp-json\/wp\/v2\/categories?post=249"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/jazzgraphs.com\/wp2\/wp-json\/wp\/v2\/tags?post=249"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}