A library for computer-aided musicology.

Bruna Wundervald (Maynooth University) , Julio Trecenti (Curso-R)

The goal of music21 is to have an pipe-able API of music21 python library (Cuthbert and Ariza 2010). It uses reticulate package in the backend (Allaire, Ushey, and Tang, n.d.).

According to music21’s site, it can be used to answer questions like:

Actually, music21 is more limited than the original python library. However, it is really easy to run any functions from music21 inside R.


music21 package is based on the music21 python library. To install this package, you may want to use reticulate. However, there are some issues:

I recommend the workflow as follows.

Install Anaconda

Anaconda is a platform to install python packages without pain. You can access download and install the latest version here. Please make sure to install Python 3.x. If you use Ubuntu, there is a great tutorial from DigitalOcean.

Create a conda environment

Environments are folders where you install Python packages. Environments are useful because Python usually has many installation paths and it is difficult to have a consistent general configuration. New virtual environments usually come with some basic packages and a new path to a python command line binary.

Conda environments are Anaconda-optimized environments that install some data science packages automatically.

# Upgrade pip to latest version
reticulate::conda_install("r-py3", "pip")

Install music21 Python package

You can install music21 using conda_install():

reticulate::conda_install("r-py3", "music21", pip = TRUE)

You must use pip=TRUE because music21 is not available in the default conda channels.

Install music21 R package

music21 is not on CRAN as the main functions are very likely to change. You can install music21 from github with:

# install.packages("devtools")

Make sure you are using the environment you just created

reticulate::use_condaenv("r-py3", required = TRUE)


[1] 5

[1] 3

[1] 0

[1] ""

If your VERSION it is not 5.3.0, you may try to force your python version to


so that your py_config() returns


python:         /home/jtrecenti/anaconda3/envs/r-py3/bin/python
libpython:      /home/jtrecenti/anaconda3/envs/r-py3/lib/
pythonhome:     /home/jtrecenti/anaconda3/envs/r-py3:/home/jtrecenti/anaconda3/envs/r-py3
version:        3.7.0 (default, Jun 28 2018, 13:15:42)  [GCC 7.2.0]
numpy:           [NOT FOUND]
music21:        /home/jtrecenti/anaconda3/envs/r-py3/lib/python3.7/site-packages/music21

NOTE: Python version was forced by use_python function

Extra: install lilypond

To use the plot and view methods, you’ll also have to install lilypond. On Ubuntu, run:

sudo apt-get install lilypond

If you use Windows or Mac, you can find detailed instructions here.

The music21 object

#> Module(music21)

music21 object stores the python module. It is possible to run any function from it just by using $, treating it as a Reference Class object.

note <- music21$note$Note("C#")

<music21.note.Note C#>


Example 1: bach chorales

Show bach chorales

get_composer("bach") %>% 
#> [1] "/home/jtrecenti/anaconda3/envs/r-py3/lib/python3.7/site-packages/music21/corpus/bach/bwv1.6.mxl"  
#> [2] "/home/jtrecenti/anaconda3/envs/r-py3/lib/python3.7/site-packages/music21/corpus/bach/bwv10.7.mxl" 
#> [3] "/home/jtrecenti/anaconda3/envs/r-py3/lib/python3.7/site-packages/music21/corpus/bach/bwv101.7.mxl"
#> [4] "/home/jtrecenti/anaconda3/envs/r-py3/lib/python3.7/site-packages/music21/corpus/bach/bwv102.7.mxl"
#> [5] "/home/jtrecenti/anaconda3/envs/r-py3/lib/python3.7/site-packages/music21/corpus/bach/bwv103.6.mxl"
#> [6] "/home/jtrecenti/anaconda3/envs/r-py3/lib/python3.7/site-packages/music21/corpus/bach/bwv104.6.mxl"

Let’s get one of these paths and read:

bach_music <- get_composer("bach")[[61]] %>% 

Plot bwv165.6 music

Now let’s plot the music!


In RStudio, you can use the view function to see the music inside viewer pane.

#> {0.0} <music21.instrument.Instrument P1: Soprano: Instrument 1>
#> {0.0} < 0 offset=0.0>
#>     {0.0} <music21.clef.TrebleClef>
#>     {0.0} <music21.key.Key of G major>
#>     {0.0} <music21.meter.TimeSignature 4/4>
#>     {0.0} <music21.note.Note G>
#> {1.0} < 1 offset=1.0>
#>     {0.0} <music21.note.Note G>
#>     {1.0} <music21.note.Note F#>
#>     {2.0} <music21.note.Note E>
#>     {2.5} <music21.note.Note F#>
#>     {3.0} <music21.note.Note G>
#>     {3.5} <music21.note.Note A>
#> {5.0} < 2 offset=5.0>
#>     {0.0} <music21.note.Note B>
#>     {0.5} <music21.note.Note C>
#>     {1.0} <music21.note.Note A>
#>     {2.0} <music21.note.Note G>
#>     {3.0} <music21.note.Note G>
#> {9.0} < 3 offset=9.0>
#>     {0.0} <music21.note.Note G>
#>     {1.0} <music21.note.Note A>
#>     {1.5} <music21.note.Note G>
#>     {2.0} <music21.note.Note F#>
#>     {2.5} <music21.note.Note E>
#>     {3.0} <music21.note.Note D>
#> {13.0} < 4 offset=13.0>
#>     {0.0} <music21.note.Note G>
#>     {2.0} <music21.note.Note F#>
#>     {3.0} <music21.note.Note F#>
#> {17.0} < 5 offset=17.0>
#>     {0.0} <music21.layout.SystemLayout>
#>     {0.0} <music21.note.Note G>
#>     {1.0} <music21.note.Note G>
#>     {2.0} <music21.note.Note A>
#>     {3.0} <music21.note.Note B>
#> {21.0} < 6 offset=21.0>
#>     {0.0} <music21.note.Note A>
#>     {2.0} <music21.note.Note A>
#>     {3.0} <music21.note.Note B>
#> {25.0} < 7 offset=25.0>
#>     {0.0} <music21.note.Note C>
#>     {1.0} <music21.note.Note B>
#>     {2.0} <music21.note.Note A>
#>     {3.0} <music21.note.Note B>
#>     {3.5} <music21.note.Note C>
#> {29.0} < 8 offset=29.0>
#>     {0.0} <music21.note.Note A>
#>     {2.0} <music21.note.Note G>
#>     {3.0} < style=final>

Example 2: Random chord generator

Last year I made a random chord generator package to study relative pitch perception. My goal was to hear random chords and figure out what was the chord and the inversion. The result was this nice R package made on top of music21.

chordgen package has just one function. It generates n chords and return a music21 object. There are many options to the list of chords it can generate.

# devtools::install_github("r-music/chordgen")

chordgen(18, n_notes = 3:4, 
         triad_types = 1:2, 
         octave = 0, 
         transpose = 0, 
         add_lyric = FALSE) %>% 

It is also possible to add lyrics, thanks to the chordify algorithm implemented in music21.

chordgen(18, n_notes = 3, 
         triad_types = 1:2, 
         octave = 0, 
         transpose = 0:4, 
         add_lyric = TRUE) %>% 

We have also created a shiny app to run and play random chords. If music21 is correctly installed, you can just run:

shiny::runGitHub("chordgen", "r-music", subdir="inst/chordgen/")

In a future post, we’ll explain how to create and label random chords in detail.


music21 is just a crawling baby for now. In my opinion, music21 can be a great tool for i) structured music data IO and ii) music statistical modeling. The biggest challenge for now is think how to make a tidy API to it.

What would you like to do with music21? Please comment in the comment section.


Allaire, JJ, Kevin Ushey, and Yuan Tang. n.d. Reticulate: Interface to ’Python’.

Cuthbert, Michael Scott, and Christopher Ariza. 2010. “Music21: A Toolkit for Computer-Aided Musicology and Symbolic Music Data.” International Society for Music Information Retrieval.


For attribution, please cite this work as

Wundervald & Trecenti (2018, Oct. 6). R-Music: music21. Retrieved from

BibTeX citation

  author = {Wundervald, Bruna and Trecenti, Julio},
  title = {R-Music: music21},
  url = {},
  year = {2018}