This template allows you to run an analysis on any work you want (that MusicBrainz knows about of course). Just fill the MBID of the work you want!
# for example, Schubert Klavierstück D. 946 no. 1
work_mbid = '83fbc6a7-6808-342e-aea7-ae68a1b87a64'
%run startup.ipy
work = sql("""
SELECT name
  FROM work
 WHERE gid = %(work_mbid)s;
    """, work_mbid=work_mbid)
work_name = work.name[0]
def recording_list(work_mbid):
    recordings = sql("""
SELECT a.name AS artist,
       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,
       r.length * interval '1ms' AS duration,
       p.name AS place,
       p.coordinates
  FROM work               AS w
  JOIN l_recording_work   AS lrw ON w.id = lrw.entity1
  JOIN recording          AS r   ON r.id = lrw.entity0
LEFT OUTER JOIN l_place_recording  AS lpr ON r.id = lpr.entity1
LEFT OUTER JOIN place              AS p   ON p.id = lpr.entity0
LEFT OUTER JOIN l_artist_recording AS lar ON r.id = lar.entity1
LEFT OUTER JOIN artist             AS a   ON a.id = lar.entity0
LEFT OUTER JOIN link               AS l   ON l.id = lar.link
 WHERE w.gid = %(work_mbid)s
ORDER BY start;
""", work_mbid=work_mbid)
    recordings.duration = recordings.duration.fillna(0).apply(lambda t: t.round('s'))
    recordings['seconds'] = recordings.duration.apply(lambda s: s.total_seconds())
    recordings.duration = recordings.duration.apply(lambda s: str(s).replace('0 days 00:', ''))
    recordings['url'] = recordings.mbid.apply(mb_recording_link)
    recordings.drop('mbid', axis=1, inplace=True)
    return recordings
    
recordings = recording_list(work_mbid)
print('Number of recordings: %d' % len(recordings))
print('First recordings (chronological order): ')
iplot(ff.create_table(recordings[['start', 'artist', 'duration', 'url']].head(10)))
recordings.groupby('artist').count().url.sort_values(ascending=False).head(10)
# Transform into JSON
data = [{'start': line.start.isoformat(),         
         'content': line.artist,
        } for _, line in recordings.iterrows() if line.start]
# Send to Javascript
import json
from IPython.display import Javascript
Javascript("""window.recordingData={};""".format(json.dumps(data, indent=4)))
%%html
<link rel="stylesheet" type="text/css"
      href="https://cdnjs.cloudflare.com/ajax/libs/vis/4.20.1/vis-timeline-graph2d.min.css" />
%%javascript
element.append('<div id="vis-container" style="width: 100%;height: 100%;"></div>');
requirejs.config({
    paths: {
        vis: '//cdnjs.cloudflare.com/ajax/libs/vis/4.20.1/vis'
    }
});
require(['vis'], function(vis){
  var data = new vis.DataSet(window.recordingData);
  var options = {
    editable: false
  };
  // create the timeline
  var container = document.getElementById('vis-container');
  var timeline = new vis.Timeline(container, data, options);
})
recordings_by_duration = recordings.sort_values(by='seconds', ascending=True)
# attribute unique random color to each pianist (black=unknown)
from hashlib import md5
color = recordings_by_duration.artist.apply(lambda s: '#' + md5(bytes(s, 'utf-8')).hexdigest()[:6] if s else '#000000')
# legend displayed on mouse hover
text = (recordings_by_duration.artist 
        + '<br>' 
        + recordings_by_duration.start.apply(lambda s: s.strftime('%Y-%m-%d') if pandas.notnull(s) else 'date unknown')
        + '<br>'
        + recordings_by_duration.duration.astype(str))
iplot({'data': [{'type': 'bar', 'y': recordings_by_duration.seconds,
                 'text': text, 'hoverinfo': 'text',
                 'marker': {'color': color}}],
       'layout': {'title': '{} recordings by duration'.format(work_name),
                  'xaxis1': {'title': 'Recording (arbitrary) number'},
                  'yaxis1': {'title': 'Duration (seconds)'}}})
recordings_by_place = recordings[['place', 'artist', 'start', 
                                  'coordinates']][~recordings.coordinates.isnull()]
import datetime
recordings_by_place['text'] = recordings_by_place[['place', 'artist', 'start']].apply(
    lambda s: '<br>'.join([el.isoformat() if isinstance(el, datetime.date) 
                                          else (el or '') for el in s]), axis=1)
iplot({'data': [{'type': 'scattergeo',
                 'lat': recordings_by_place.coordinates.apply(lambda t: eval(t)[0]),
                 'lon': recordings_by_place.coordinates.apply(lambda t: eval(t)[1]),
                 'text': recordings_by_place.text}],
       'layout': {'geo': {'showland': True,
                          'showcountries': True,
                          'projection': {'type': 'stereographic'}},
                  'title': 'Recordings by place'}})