User’s Guide, Chapter 23: Roman Numeral Analysis

F major is a chord that has the notes F, A, and usually C. Those notes, placed in the same octave, instrument, dynamics, etc., should have basically the same acoustical properties each time it’s played, but human perception of this chord can seem to vary dramatically depending on the context the chord is placed in. One of the most powerful contexts that can give the same isolated sound remarkably different meanings comes from its surrounding key.

Roman numeral analysis is a way to identify certain similarities in tonal music (whether classical, folk, or popular) that have traditionally been assigned to different chords that appear on the same scale degrees in different keys.


For a basic introduction to Roman numeral analysis, see the strong Wikipedia article or, for a quick review, the great PDF cheatsheet at “Learn Music Theory”

Let’s create an F-major chord but convert it to roman numerals in a few different contexts by creating different key objects. First the setup:

from music21 import *
f = chord.Chord('F4 C5 A5')
kf = key.Key('F')
sf = stream.Measure([kf, f])
kc = key.Key('C')
sc = stream.Part([kc, f])
kb = key.Key('B')
sb = stream.Part([kb, f])

Now that we have four different keys, let’s create Roman numerals from the F major chord and each of the keys. We will use a function from the music21.roman module called romanNumeralFromChord() (which we saw briefly in Chapter 10). We pass to this function a Chord object and a Key object.

rf = roman.romanNumeralFromChord(f, kf)
 <music21.roman.RomanNumeral I in F major>
rc = roman.romanNumeralFromChord(f, kc)
 <music21.roman.RomanNumeral IV in C major>

Music21 tries its best to find a Roman numeral for almost any combination of chord and key, even if, like in B major:

rb = roman.romanNumeralFromChord(f, kb)
 <music21.roman.RomanNumeral bV in B major>

Each RomanNumeral object has some common properties, such as .figure, .figureAndKey, .romanNumeralAlone, .key, and .scaleDegree:

(rf.figure, rc.figure, rb.figure)
 ('I', 'IV', 'bV')
 'I in F major'
(rf.romanNumeralAlone, rc.romanNumeralAlone, rb.romanNumeralAlone)
 ('I', 'IV', 'V')
(rf.key, rc.key, rb.key)
 (<music21.key.Key of F major>,
  <music21.key.Key of C major>,
  <music21.key.Key of B major>)
(rf.scaleDegree, rc.scaleDegree, rb.scaleDegree)
 (1, 4, 5)

Note that in the last case, the scale degree is the uninflected degree – the flat sign isn’t included in the .scaleDegree tag. For that, use .scaleDegreeWithAlteration

 (1, None)
 (5, <music21.pitch.Accidental flat>)

Or look at the .frontAlterationString, frontAlterationAccidental, and frontAlterationTransposeInterval

 <music21.pitch.Accidental flat>
 <music21.interval.Interval d1>

Of course, some RomanNumerals make more sense than others, so there’s a .functionalityScore which returns a number from 0 to 100 as a rough approximation of how “functional” this chord is:

(rf.functionalityScore, rc.functionalityScore, rb.functionalityScore)
 (100, 59, 0)

As I hinted at above, RomanNumeral objects are Music21Objects so they can be put into Streams and showed:

s = stream.Measure()
s.insert(0, rf)

Note that the spacing of the roman numeral is preserved from the chord that it was converted from. If we create a RomanNumeral object directly, then it is created in closed position above a tonic note in octave 4:

rf2 = roman.RomanNumeral('I', kf)
 <music21.roman.RomanNumeral I in F major>

It is possible to pass in just a roman numeral (“I”, “ii”, “iii”, “IV”, etc.) and a string (“C” = C major, “c” = c minor) to create a RomanNumeral object:

subDom7 = roman.RomanNumeral("IV7", "B-")
e65 = roman.RomanNumeral("ii65", "E")

For these romanNumerals, there is information after the .romanNumeralAlone this can be found as a string in .figuresWritten:

(subDom7.figuresWritten, e65.figuresWritten)
 ('7', '65')

These numbers can also be found as part of a more powerful figuredBass.Notation object (to be discussed later) in the .figuresNotationObj attribute:

(subDom7.figuresNotationObj, e65.figuresNotationObj)
 (<music21.figuredBass.notation.Notation 7>,
  <music21.figuredBass.notation.Notation 6,5>)
 (6, 5, 3)

Many of these properties can be changed:

rf.key = key.Key('D')

Changing the key removes any information about pitch spacing. You can’t have everything. :-)

We’ll put the key of F back and the original pitches before we forget:

rf = roman.romanNumeralFromChord(f, kf)

RomanNumerals as Chords

A RomanNumeral object is a subclass of a Chord object, therefore we can do everything with them that we could do with a chord. For instance:

rfc = rf.closedPosition()
rb.lyric = rb.figure
(rf.quality, rc.quality, rb.quality)
 ('major', 'major', 'major')
 [0, 3, 5, 8]

That’s all we have for RomanNumerals for now – we will return to RomanNumeral like objects later when we look at other Harmony objects such as ChordSymbols and FiguredBass and we look at the romanText module. But we’ll take a break from musical objects and get acquainted a bit better with how your system works when running music21 with a look at Chapter 24, Environment.