Displaying a MusicBrainz performer data

Setup

The setup required to repeat these operations is explained in the introduction notebook. In case graphs do not appear in this page you can refer to the static version.

In [1]:
%run startup.ipy
Last notebook update: 2018-06-06
Git repo: git@bitbucket.org:loujine/musicbrainz-dataviz.git
Importing libs
Defining database parameters

Defining *sql* helper function
Last database update: 2018-06-02

Python packages versions:
numpy       1.14.3
pandas      0.23.0
sqlalchemy  1.2.8
CPython 3.7.0b5
IPython 6.4.0

Fetch data

In [2]:
def data(performer_name):
    performer = sql("""
SELECT gid AS mbid,
       name
  FROM artist
 WHERE name = %(performer_name)s;
    """, performer_name=performer_name)
    performer_mbid = performer['mbid'][0]

    df = sql("""
SELECT r.name            AS recording_name,
       to_date(to_char(l.begin_date_year, '9999') ||
               to_char(COALESCE(l.end_date_month, 1), '99') ||
               to_char(COALESCE(l.end_date_day, 1), '99'), 'YYYY MM DD') AS start,
       to_date(to_char(l.end_date_year, '9999') ||
               to_char(COALESCE(l.end_date_month, 1), '99') ||
               to_char(COALESCE(l.end_date_day, 1), '99'), 'YYYY MM DD') AS end,
       r.gid             AS mbid
  FROM recording          AS r
  JOIN l_artist_recording AS raw ON r.id = raw.entity1
  JOIN artist             AS a   ON a.id = raw.entity0
  JOIN link               AS l   ON l.id = raw.link
 WHERE a.gid = %(performer_mbid)s
   ;""", performer_mbid=performer_mbid)
    df['url'] = df.mbid.apply(mb_recording_link)
    return df
In [3]:
recordings = data('Dino Ciani')
iplot(ff.create_table(recordings.head()[['start', 'recording_name', 'url']]))
In [4]:
recordings_by_date = recordings[['start', 'recording_name']].groupby('start').agg(lambda s: '<br>'.join(s))

# Transform into JSON
data = [{'start': date.isoformat(),
         'content': line.recording_name
        } for date, line in recordings_by_date.iterrows()]

# Send to Javascript
import json
from IPython.display import Javascript
Javascript("""window.bandData={};""".format(json.dumps(data)))
Out[4]:
In [5]:
%%html
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/vis/4.20.1/vis-timeline-graph2d.min.css" />
In [6]:
%%javascript
// this must be executed before the "from IPython.display import Javascript" block
element.append('<div id="timeline2" style="width: 100%;height: 100%;"></div>');


requirejs.config({
    paths: {
        vis: '//cdnjs.cloudflare.com/ajax/libs/vis/4.20.1/vis'
    }
});

require(['vis'], function(vis){
    
  // note that months are zero-based in the JavaScript Date object
  var data = new vis.DataSet(window.bandData);
  // specify options
  var options = {
    editable: false
  };

  // create the timeline
  var container = document.getElementById('timeline2');
  timeline = new vis.Timeline(container, data, options);
})

Events timeline

Let's look at events where a certain band played. We can of course display a timeline:

In [7]:
def event_data(performer_name):
    performer = sql("""
SELECT gid AS mbid,
       name
  FROM artist
 WHERE name=%(performer_name)s;
    """, performer_name=performer_name)
    performer_mbid = performer['mbid'][0]

    df = sql("""
SELECT e.name            AS event_name,
       to_date(to_char(e.begin_date_year, '9999') || 
               to_char(e.begin_date_month, '99') || 
               to_char(e.begin_date_day, '99'), 'YYYY MM DD') AS start,
       to_date(to_char(e.end_date_year, '9999') || 
               to_char(e.end_date_month, '99') || 
               to_char(e.end_date_day, '99'), 'YYYY MM DD') AS end,
       e.gid             AS mbid
  FROM event          AS e
  JOIN l_artist_event AS lae ON e.id = lae.entity1
  JOIN artist         AS a   ON a.id = lae.entity0
  JOIN link           AS l   ON l.id = lae.link
 WHERE a.gid = %(performer_mbid)s
   ;""", performer_mbid=performer_mbid)
    return df

event = event_data('Radiohead')
In [8]:
# Transform into JSON
data = [{'start': line.start.isoformat(),
         'content': '<a href="' + str(line.mbid) + '">' + line.event_name + '</a>'
        } for _, line in event.iterrows() if line.start is not None]

import datetime
import json

# Send to Javascript
from IPython.display import Javascript
Javascript("""window.eventData={};""".format(json.dumps(data)))
Out[8]:
In [9]:
%%javascript
// this must be executed before the "from IPython.display import Javascript" block
element.append('<div id="timeline_event" style="width: 100%;height: 100%;"></div>');


requirejs.config({
    paths: {
        vis: '//cdnjs.cloudflare.com/ajax/libs/vis/4.20.1/vis'
    }
});

require(['vis'], function(vis){
    
  // note that months are zero-based in the JavaScript Date object
  var data = new vis.DataSet(window.eventData);
  // specify options
  var options = {
    editable: false
  };

  // create the timeline
  var container = document.getElementById('timeline_event');
  timeline = new vis.Timeline(container, data, options);
})

To be continued

Questions to answer:

  • how many recordings were recorded by this performer?
  • which are the "favorite" (most recorded) works? and composers?
  • which century/period/area works?

Plots to show:

  • plot recordings by date
  • plot recordings by place/area