John R. Ladd | 17 February 2020
To the Reader: I've provided a PDF version of this essay for easy printing. But if you're reading this as a PDF, you're missing some of the interactive visualizations and some images may not be full size. For the full version, go to https://jrladd.com/dedication_networks.
In A description of the famous Kingdome of Macaria (1641), Samuel Hartlib begins his book with a dedication to the "High and Honorable Court of Parliament," but in the text of the dedication he saw fit to name a few people who have little do with the Parliament of the early 1640s:

Right-click and select "view image" to see larger version.
This dedication follows the conventional form by including an elaborate header that addresses the dedicatee, in this case the "High and Honorable Court of Parliament." But Hartlib names two other individuals, More and Bacon, in the body of the dedication, and he even labels them as his "pattern" or role models in this publishing venture.
Neither More (who died in 1535) nor Bacon (who died in 1626) would show up in a network graph focused on reconstituting the lived early modern social world of 1641, but Hartlib mentions each of them at the book’s opening. Since he's putting forth a new utopian text, it makes sense that Hartlib would want to cite these two men as his "pattern," making this a reference to both the authors and their books simultaneously. Hartlib uses his dedication to address his dedicatee but also to stake out some authorial territory by invoking his key influences. In this brief essay, I take advantage of the additional names that authors added to their dedications to create an expanded network of print relationships that includes contemporary social bonds alongside historical—and even fictional—associations. But Hartlib's reference to his influences is far from the only kind of naming that takes place in early modern dedications.

Right-click and select "view image" to see larger version.
Samuel Drake's dedication of his sermon Totum hominis to Margaret Armitage also includes a number of additional names that belong to neither the author nor the dedicatee. Armitage's husband, John, is included in the header, but more importantly Drake includes his dedicatee's two daughters, Margaret and Catherine, holding them up as examples of piety. Margaret and her daughters are all associated with the content of Drake's sermon, as exemplars of the virtues (justice, mercy, and humility) on which he preaches. Drake takes this a step farther when he insists that Margaret and Catherine "deserve the stile of Jemima and Kesia, (two of Holy Jobs Daughters)." In addition to the contemporary figures that are invoked here, Drake associates Armitage's daughters with biblical figures, further incorporating them into the subject of his sermon and demonstrating his knowledge of scripture. For Drake, as for many writers of dedications, the contemporary and the biblical exist side-by-side.
The habit of naming non-contemporary figures alongside living ones is repeated in the texts of many early modern dedications: some of the individuals mentioned are living, some have died recently, others are writers, influences, and religious figures from another time entirely. The imaginative network of a text involves all of these figures together, and by considering them in a single network—a peopled imagination—we can better understand the many motivations that underlie text creation, including patronage, social and cultural aspiration, anxieties of influence, and social relationships.
I use these two examples to emphasize the untimeliness of the print networks I've reconstructed: just as the landscape of reading is made up of recently published texts and texts that first appeared long before, the landscape of print is made up of actors who are not physically present in the social world but are nonetheless crucial to understanding how the relation between persons and texts was constructed. The relationship between an author or text and a name mentioned in a dedication is an imaginative relation. When an author does not personally know the individual they are invoking in a dedication, or even when they do, the appearance of that name stakes out an intellectual and imaginative space for the idea of that person that could, but need not necessarily, fall back on any first-hand relationship with the individual. These imaginative relations abound during the creation of a text—we all carry the ideas of many people we may not currently know: public figures, deceased relatives, people we would like to meet. A dedication is one place where these imaginative relations can take form through naming, direct reference, and allusion. My project attempts to recover these relations—at least the ones available through direct reference—and map them at scale.
Computational approaches to digitized texts have mainly treated documents as "bags of words," and major distant reading methods of the last two decades—including topic modeling, authorship attribution, and more recently word vector analysis—model a digital text as a container for words, stripping it of most information that refers back to the physical object. One of the first things I learned when I was starting out in digital humanities was how to strip the detailed XML markup from the texts in the Early English Books Online–Text Creation Partnership, markup which accounts for sections of the book, physical pages, and other important features. While the tools and techniques of corpus linguistics and distant reading have made it possible to use machine-readable text to probe the history of language, there is even more work we can do with digitized texts, thanks to the markup standards of the Text Encoding Initiative, to understand the history of books and printing, particulary in the early modern period. One of the simplest and most useful things that markup does is to label a text's many parts. This means that not only is the main body of an early modern book available to us in new ways, but a book's many paratexts---its prefaces, epistles, indices, and dedications—are newly tractable. This work outlines a method for better understanding a particular kind of paratext—the dedication—while eschewing the "bag of words" model in two ways: by taking advantage of TCP markup to locate specific sections of a book and by employing network analysis in concert with text analysis to understand linkages among texts.
In my book project Network Poetics, I use network analysis to explore the ways in which social relations and collaborative writing practices shape literary forms and genres. I often turn to paratext as a site of early modern relational thinking, combining my interest in abstract social networks with an attention to material texts. EarlyPrint, the digital project on which I'm currently a collaborator, extends the EEBO-TCP markup of a book's features and parts with linguistic markup that makes natural language processing tasks much easier and invites widely varied forms of analysis using the improved texts as a base. The EarlyPrint texts have been a boon for my research in that they provide better raw materials for thinking about the social world of printed books.

A sample of EarlyPrint XML from the dedication to Macaria.
Many network projects that attempt to understand the world of early modern print use forms of metadata---information extrinsic to the text itself, like titles, subject headings, and publication information---rather than the contents of the text or any part of the text. The Shakeosphere project is made from metadata: the information in the English Short Title Catalog. Another network project (one which I worked on), Six Degrees of Francis Bacon, is derived from the metacommentary on social relationships available in the secondary sources of the Oxford Dictionary of National Biography. Michael Gavin's Historical Text Networks are made from a combination of Early English Books Online metadata, imprint information specifically, and additional information from paratexts. Paratexts occupy a liminal position between data and metadata. As part of the primary source, they can be considered data itself, but for the ways they comment on and relate to the main text, they are also a form of metadata. My project takes a specific paratextual form, the dedication, as its main source of (meta)data, leveraging its complex relationship to the text as a source of network information.
Finally, as a scholar concerned with digital and material forms, I thought a lot about the best way to share my work with others. Since so much of my research for this essay took place in a Jupyter notebook as I worked through various analyses of the data, I decided that the most transparent way of sharing the work was to put my prose alongside the code that influenced so much of my thinking, in an extension of the aims of literate programming, which Jupyter is designed to facilitate. The code that generates the visualizations and analysis throughout this essay is far from everything I've written for this project: there are helper functions in a separate file, not to mention the code that was used to derive the network data from the EarlyPrint texts. But by showing some of the code throughout the essay I hope to emphasize that my writing process and my programming are, for this project and others, mutually constitutive.
# Begin by importing necessary libraries
import networkx as nx
from networkx.readwrite import json_graph
from networkx.algorithms import bipartite, community
import json
import matplotlib
import matplotlib.pyplot as plt
import pandas as pd
from pyvis.network import Network
import helper_functions as hf
plt.style.use('ggplot') # Automatically give all charts nice styling
# Read in the full initial graph from my named-entity recognition process
with open('all_eebo.json', 'r') as jsonfile:
jsonstring = jsonfile.read()
data = json.loads(jsonstring)
# Load this graph into a NetworkX object for easy analysis
B = json_graph.node_link_graph(data)
print(nx.info(B))
In my search for imaginative relations, I employed a method for finding names in dedications indiscriminately, concerning myself only with the fact that a name appeared in a dedication and not with why or how. What can we learn by studying the patterns of these names when we gather them at an increased scale, and how might such patterns direct our energies in the study of particular persons or texts?
First, as I mentioned before, I was able easily to extract every section of a text marked up as a “dedication.” The “dedication” attribute---which was added by the TCP at the earliest stages of markup---is not infallible: there may be certain dedicatory text-segments that were not marked as dedications, as well as other types of paratext (encomia, prefaces, etc.) that were given the wrong tags. Once I had the dedications, I needed a reliable way of identifying names in the text. The traditional approach would be to use a process called named-entity recognition, or NER, but though I tried and tried, it's difficult to use contemporary NER tools, trained on modern language corpora, on early modern texts. Irregular orthography, non-standardized capitalization, initialism, pseudonymy, and anonymity all present distinct early modern challenges to computer-assisted name recognition. I could train a classifier myself if I had a substantial corpus of early modern texts in which names were already tagged, but such a corpus does not currently exist.
This is where the EarlyPrint texts truly shine. Thanks to a piece of software called MorphAdorner, which was developed by my Northwestern colleagues Martin Mueller and Phil Burns, EarlyPrint is marked up with parts of speech and regularized spelling for each word in every text. MorphAdorner is able to overcome the challenges that bedevil other natural language processing tools because it was designed by domain experts with historical texts specifically in mind. This still isn't the same as having named-entity recognition fully available for early modern texts---though this is something we're currently experimenting with at Northwestern—but using some specialized rules I programmed myself in Python, I was able to use MorphAdorner's markup for proper nouns to capture many of the names in the dedications across the entire EarlyPrint corpus.
By listing the names that appeared in each dedication, I was able to construct a network of people and the texts in which they appear. Networks are made up of nodes (usually represented as circles) which stand for the entities that are connected, and edges (usually represented as lines), which stand for the connections themselves. Though in social networks nodes typically represent people and edges represent social relationships, networks are a data structure that can hold any kind of relational information. It is possible to have a network of cell phone towers, a network of bivalve reproduction, a network of foods and their tastes. The important thing in a network is to carefully define the nature of the edge relation, but that connection (even when the entities are people) need not be a human relationship. A network of people could be connected by who shares the same height or eye color. In my project, a connection is nothing more or less than a name's presence in a dedication—sometimes this maps onto a social relationship, and sometimes it does not. One of the purposes of this project is to interrogate the overlap and gaps between a social relationship and a dedicatory mention.
The code above takes data from every dedication in EEBO-TCP and turns it into a single network where names are linked to the texts in whose dedications they appear. It links a name to a text regardless of whether that name appears in the dedication's heading (meaning the person is probably the dedicatee); its "signed" section (meaning the person is probably the author); or its main body (meaning the person is probably someone else). As stated above, I engaged in this project because I believe that the names in the dedication's body matter, that they tell us something about the network of print that dedicatee and author names alone cannot. A first step is to determine whether including those names in the network actually changes its structure in a substantive way.
A series of network visualizations can answer this question fairly quickly, along with a list of the people in the network with the highest "degree," those people who are connected to the most texts. Since the whole network, with its 40,000+ nodes, is difficult to read at all at once, I chose to look at the network from 1660 as an example. Here's the network of all names that I found, regardless of their position in the dedication:
THESE VISUALIZATIONS ARE INTERACTIVE! The orange circles represent people, while the green squares represent texts. Scroll to zoom the visualization, and click-and-drag to pan. Mouseover a node to see its label. Some names include lists of similar spellings, which is my attempt at internal name reconciliation.
# As a test, create a subgraph for 1660
SB = hf.filter_by_year(1660, B)
print("Full Network for 1660")
print(nx.info(SB))
# Sort nodes by their degree to get the 10 people with the heighest degree
# Then print those names
nodes_by_degree = sorted(SB.nodes(data=True), key=lambda n:SB.degree(n[0]), reverse=True)
people_by_degree = [n for n in nodes_by_degree if n[1]['bipartite'] == 1]
print("\nTop Ten People by Degree:\n")
for p in people_by_degree[:10]:
print(p[1]['name_variants'])
viz = hf.convert_nx(SB)
viz.show("year_graph.html")
In the above network, you can see that names from the present of 1660 (King Charles, William Prynne, General Monck, Thomas Allen) are combined with religious and political from the distant past (Jesus Christ, St. Paul, Queen Elizabeth). This is a hallmark of all configurations of the network that I created, and it emphasizes the ways in which dedicatory practice, when expanded beyond a view of patronage alone, isn't bound to figures living at the exact moment of publication. n.b. If you don't see a network visualization at all, you're probably reading this in the PDF version. Check out https://jrladd.com/dedication_networks.
But what happens when I create a network using only names that appear in the body of the dedication?
# Create a subset of the graph by looking for edges that I've already labeled "body"
body_subgraph = B.edge_subgraph([(e[0],e[1]) for e in B.edges(data=True) if e[2]['types'] == ['body']])
print("1660 Network, using only names from the <body> of the dedication")
# Create a subgraph of this one for 1660
body_yeargraph = hf.filter_by_year(1660, body_subgraph)
print(nx.info(body_yeargraph))
# Sort the nodes as before
nodes_by_degree = sorted(body_yeargraph.nodes(data=True), key=lambda n:body_yeargraph.degree(n[0]), reverse=True)
people_by_degree = [n for n in nodes_by_degree if n[1]['bipartite'] == 1]
print("\nTop Ten People by Degree:\n")
for p in people_by_degree[:10]:
print(p[1]['name_variants'])
viz = hf.convert_nx(body_yeargraph)
viz.show("body_year_graph.html")
Some of the same high-frequency names come up in this network (Christ, King Charles), but the names are in different order and some of the contemporary figures have been replaced by more biblical figures. (More work needs to be done to establish this, but my instinct is that the appearance of biblical kings Solomon and David is related to a renewed interest in anointed kingship at the Restoration.)
Looking at the network visualization itself, you may notice that the network is a bit more tight-knit, with fewer disconnected components: those floating sections of the graph where a few names are connected to only one text. This suggests that the network without authors and patrons involves more of the same names over and over, rather than introducing new ones.
How does the network look if we filter in the other direction, by eliminating those names which only appear in the body?
# Create a subgraph as before, but with the exact opposite set of edges
patron_subgraph = B.edge_subgraph([(e[0],e[1]) for e in B.edges(data=True) if e[2]['types'] != ['body']])
print("1660 Network, using only names from the <body> of the dedication")
# Make a subgraph of this one for 1660
patron_yeargraph = hf.filter_by_year(1660, patron_subgraph)
print(nx.info(patron_yeargraph))
# Sort and print top ten nodes
nodes_by_degree = sorted(patron_yeargraph.nodes(data=True), key=lambda n:patron_yeargraph.degree(n[0]), reverse=True)
people_by_degree = [n for n in nodes_by_degree if n[1]['bipartite'] == 1]
print("\nTop Ten People by Degree:\n")
for p in people_by_degree[:10]:
print(p[1]['name_variants'])
viz = hf.convert_nx(patron_yeargraph)
viz.show("patron_year_graph.html")
With the exception of Christ, whose unsurprisingly high frequency makes sure he tops any of these lists, the figures from the biblical and political past are entirely replaced by contemporaries in this network. Authors and dedicatees are the ones who have the most connections here. (As an aside, you can see in the appearance of "Ireland King" as well as two different modes of address for Charles II that more data cleaning needs to be done and will be done in future versions of this project. The data here is provisional, but I think highly suggestive. Cleaner data, for example, is unlikely to effect the relative prominence of Elizabeth, Christ, or St. Paul.)
If you zoom out, you'll see that the graph is almost entirely disconnected components. Without the more general names from the body of the dedication, texts are a lot less likely to be connected to one another by author or dedicatee. This speaks to the necessity of considering all names together, in a single network. By addressing different kinds of connection at once, we get the best sense of the many competing persons and ideas that exerted force on a book, placing it in one community or another.
So what can we learn from this unified network? Names from the distant past appear with more regularity across the corpus than contemporary figures almost as a rule. I see this as an important corrective to the practice of using dedications to tell us only about author-patron relations. It is now a commonplace in studies of reception to recognize that readers do not choose only from a crop of books newly published in a given era, but from a variety of books published before then. Reading practices are often backward-looking, and any one person's reading can include books published across a long span of time. Likewise with dedicatory practice, while early modern books are almost always dedicated to a living person, the names that appear in dedications can include a range of influences, citations, and relations from across a very wide span. A dedication—whether written before or after the main text—works along with other paratexts to signal the reader to the book's wide imaginative network. The invocation of names in the dedication allows readers to situate a book and its author within a network of influences, citations, and allusions. Repetition of a particular referent across several book dedications builds up a set of connections between books, and may suggest the importance of particular figures in networks of reading and book production over time.
The first thing we may ask of the data, then, is how to determine which referents are most important in the network over time. The traditional way to measure a node's importance within a network is through a set of measures called "centrality." The simplest kind of centrality is degree—the number of connections a single node possesses. If a person has relationships with ten other people, their degree is ten. Centrality measures can be used as a tool for thinking about a name's importance in the dedicatory network.
# The maximum range I could analyze was 1531-1700
# Create a dictionary of subgraphs for that range
graphs_by_year = {x:hf.filter_by_year(x,B) for x in range(1531,1701)}
# To analyze the people with the most connections, I need a sorted list of the highest degree-people.
nodes_by_degree = sorted(B.nodes(data=True), key=lambda n:n[1]['degree'], reverse=True)
people_by_degree = [n for n in nodes_by_degree if n[1]['bipartite'] == 1]
top_people = people_by_degree[:10]
# To get the graph for the "projected degree" over time, I needed to
# project every subgraph and record the degree
degree_projected = {}
for year,G in graphs_by_year.items():
sub_people_nodes = {n for n, d in G.nodes(data=True) if d['bipartite']==1}
projected_G = bipartite.projected_graph(G, sub_people_nodes)
degree_projected[year] = dict(projected_G.degree())
# Make a dataframe for easy graphing
df = hf.create_dataframe(degree_projected,top_people)
tf = df.T
# Create subplots for each person
ax = tf.plot(subplots=True, figsize=(20,30))
Consider the degree of Queen Elizabeth (in green on the graph above). Variations on her name appear throughout the corpus, beginning as Princess Elizabeth before her reign and hitting a high point in the decade before her death. Her degree from 1595 to 1603 is 163, outstripping perennially common names such as St. Augustine and St. Paul. Significantly, Elizabeth's influence does not decrease as much after her death as one would think: she remains in or near the top 10 nodes by degree all the way through 1640s and 50s. Similarly, in the 1590s and early 1600s, for example, the increased centrality of Luther, Calvin, and Hus signals a growing market for Protestant texts in the late part of Elizabeth's reign as well as an increase in the desire among authors to curry social favor by espousing interest in major Protestant thinkers. The social concerns of dedicatory practice and the economic ones are inextricably linked—by viewing texts and names together we get a better sense of the way these two drivers for dedicatory naming overlap.
Beyond the transhistorical importance of specific names and texts, the same data can be used to address the question of changes in dedicatory practice over time. The best test case for this is the period spanning from the 1630s through the 1660s. How did political upheaval change dedicatory practice and, by extension, the literary networks of the seventeenth century? Slicing the network by decade instead of by year makes this kind of analysis possible.
By degree:
# Create a subgraph for decades around the Civil War/Interregnum period (and immediately before and after)
decade_graphs = {'1630s':hf.filter_by_range(1630,1639,B),
'1640s':hf.filter_by_range(1639,1649,B),
'1650s':hf.filter_by_range(1650,1659,B),
'1660s':hf.filter_by_range(1660,1669,B)
}
# Find centralities by decade
decade_centralities = {year:dict(G.degree()) for year,G in decade_graphs.items()}
# Create a dataframe for the top ten people (but eliminate Christ and St. Paul for readability)
dbdf = hf.create_dataframe(decade_centralities,top_people[2:])
tdbdf = dbdf.T
# Plot as a bar graph instead of a line graph
ax = tdbdf.plot(kind='bar', figsize=(20,10), title="Number of Mentions for Top 10 People By Decade (1630s-1660s)")
ax.set_xlabel('Decade')
ax.set_ylabel('Number of Mentions')
plt.legend(loc='center left', bbox_to_anchor=(1.0, 0.5))
By betweenness centrality:
# Need the itemgetter module for easier sorting
from operator import itemgetter
import pickle as pkl
# Import all the betweenness measures from a file I created earlier
with open('all_betweenness.pkl', 'rb') as newf:
all_betweenness = pkl.load(newf)
people_nodes = {n for n, d in B.nodes(data=True) if d['bipartite']==1}
# Get betweenness for just the people nodes and sort them
all_betweenness_people = {k:v for k,v in all_betweenness.items() if k in people_nodes}
all_betweenness_sorted = sorted(all_betweenness_people.items(), key=itemgetter(1), reverse=True)
# Keep track of the ids and get the top ten nodes by betweenness
abs_ids = [a[0] for a in all_betweenness_sorted[:10]]
top_ten_betweenness = []
for a in abs_ids:
for n in B.nodes(data=True):
if n[0] == a:
top_ten_betweenness.append(n)
with open('decade_betweenness.pkl', 'rb') as newf:
decade_betweenness = pkl.load(newf)
# Create a datagrame and graph these results (eliminate Christ for readability)
ddf = hf.create_dataframe(decade_betweenness,top_ten_betweenness[1:])
tddf = ddf.T
ax = tddf.plot(kind='bar', figsize=(20,10), title="Number of Mentions for Top 10 People By Decade (1630s-1660s)")
ax.set_xlabel('Decade')
ax.set_ylabel('Betweenness Centrality')
plt.legend(loc='center left', bbox_to_anchor=(1.0, 0.5))
Looking at the network in the 1630s, many of the top names are similar to those of previous decades: there is a mixture of current political figures, saints, and ancient thinkers. In the 1640s, some of those nodes remain prominent, but particularly in terms of betweenness centrality the order and distribution of those names change. Centralities of "King Henry" and "Queen Elizabeth" go up, for one thing, and contemporary non-royal figures begin to crop up in the top ten and twenty names. One possible explanation for this is that the Republican government has disrupted the normal flow of social capital. With the King and much of the nobility imprisoned or in exile, the network is deprived of its usual go-to names for reference. In response, authors on both sides of the political spectrum seem to harken back to a previous, more stable political era.
Things change more markedly after 1649. The execution of Charles I seems to bring more finality in relation to his naming in dedications than the natural deaths of other monarchs. After his death Charles disappears from the list of most central names in the network, though Elizabeth and James still feature prominently. Pauline references, though in somewhat of a downslide during the war years, increase in frequency alongside topical biblical references like John the Baptist, whose beheading (along with Paul's own martyrdom) might have been on the minds of authors and publishers reflecting on the death of the king. Crucially, the two Republican leaders Thomas Fairfax and Oliver Cromwell join the monarchs as top names in betweenness centrality: as one might expect, Fairfax in the 40s and Cromwell in the 50s. In the 1660s the network returns to some pre-Interregnum patterns, but clear differences emerge. Centralities for King James hit a high point, suggesting nostalgia for the originator of the Stuart line in England. The name "King Charles" of course also is prominent, though this time referring to Charles II and signifying the restoration of both the monarchy and more traditional dedicatory and patronage practices. Though the return of monarchs and recently deceased political figures suggests a return to pre-1640 network behavior, there is also evidence of shifts in social behavior as it manifests in dedicatory practice. For example, the formation of the Royal Society and its subsequent flurry of publishing activity elevates names like Kenelm Digby into the group of high betweenness centrality nodes. New intellectual communities that form in the Restoration world begin to make their mark on the print landscape alongside names that we would "expect" to see given the shape of pre-war networks.
Networks have long been a way of making visible that which was previously invisible. Early modern printers, stationers, and authors conceived of the social world of print as a conversation; that is why there are so many names in these dedications in the first place. By making this practice visible, I hope to have brought forward a way of thinking transhistorically about the existing connections in the early modern print record. One of the larger points of this project is to make those people more visible to researchers through the stubborn method of finding all names in every dedication. My hope is that this visual representation is a rhetorical and argumentative step in that direction, making the people, texts, and relations of imaginative print networks visible. By not separating living figures from dead ones in these graphs, it is easier to see the ways in which people of the past continue to exert great influence over social networks of the living. As William St. Clair reoriented our understanding of reception by showing that reading was centered not simply on current publication but around a library of books from the recent and the distant past; so these networks suggest that the imaginative worlds of early modern print, manifest in dedications, are constituted of figures from a long history and not just the patrons and politicians of the day.
This essay gestures toward a larger project, and there is plenty more to do. At the level of data collection and cleaning, I've already completed some promising proofs of concept for trained named-entity recognition on early modern texts. Once data from these efforts is available, more careful cleaning can begin, so that Latin terms aren't included as names and terms like "King Charles" and "Majesty Charles" are grouped as a single person.
I have so far focused mainly on the most frequent and connected names in the network because those are the ones for which I have the most reliable data. But I originally set out on this project with the aim of using these methods to find names and resonances outside of the ones with which scholars are already most familiar, like the example of the Armitage family in Drake's dedication that I used to begin this paper. The "long tail" of names in these data, the many names that appear in just a few texts rather than the few names that appear in many texts, is still where I believe the most interesting part of this work lies. With better data, the clear future direction of this work is to extend the above exploration of large scale trends by looking for smaller-scale findings that might highlight new aspects of dedicatory practice.