The research project aims to answer the following questions:
Which texts co-occur in books?
Collect all texts they share (through an analysis of the paths; betweenness centrality)
Which texts are unique to specific books?
Are there differences per century?
Handschriften die samen voorkomen: kortste pad van 3 Tel het aantal paden Maak gephi-bestand Voor totaal en per eeuw
Visualisatie in heatmap
Identificeer alle handschriften die maar een keer voorkomen
import os
import re
import json
import requests
import bnm
from tdmh import *
from operator import itemgetter
from pyvis.network import Network
import pandas as pd
from tdmh import *
To address this question, we firstly select the data we work with. The data have all been exported from the BNM-i, a database contructed by the Huyghens ING. The texts have all been saved as separate JSON files. 41902 files have been dowbloaded in total. The code below selects the texts which have been assigned a category containing the words 'getijden' or 'gebeden'. This is the case for 5437 texts.
files = os.listdir('BNM_texts')
print(f'{len(files)} texts in total.')
selected_texts = []
for file in files:
if re.search( r'.json$' , file ):
path = os.path.join('BNM_texts' , file)
json_str = open( path , encoding = 'utf-8')
json_data = json.load(json_str)
categories = bnm.get_categories(json_data)
for c in categories:
if re.search( r'\bgetijden' , c ) or re.search( r'\bgebeden' , c ):
selected_texts.append( path )
selected_texts = list(set(selected_texts))
print( f'{len(selected_texts)} texts selected.')
41902 texts in total. 5437 texts selected.
A further selection takes place. We focus exclusively on the texts that have been assigned a standardised title.
The code below navigates across all the texts, and establishes the carriers (or the books) these texts are in.
out = open('books_of_hours.tsv' , 'w' , encoding = 'utf-8')
out.write('text_id\ttext_title\tbook_id\tbook_title\tyear\n')
count = 0
norm_titles = []
for text in selected_texts:
json_str = open( text, encoding = 'utf-8')
json_data = json.load(json_str)
#print(text)
norm_title = bnm.get_norm_title(json_data)
if len(norm_title) > 0:
#print(norm_title)
count += 1
title = norm_title[0][1]
title = re.sub('Ongespecificeerde Mnl. teksten op naam van\s+' , '' , str(title))
title = re.sub('Mnl. vertaling(en)? van\s+' , '' , str(title))
title = re.sub('MNoordnederlandse vertaling van\s+' , '' , str(title))
norm_titles.append(title)
# Find information about the book this text is in.
# the book is added to the modes dictionary
book = bnm.get_text_carrier(json_data)
## get the date of the book
path = os.path.join( 'BNM_carriers' , book[0][0] ) + '.json'
json_book = open( path , encoding = 'utf-8')
json_book = json.load(json_book)
book_date = json_book['datering']
# normalise book_date
date_norm = 0
if re.search( r'/' , str(book_date)):
parts = re.split( r'/' , book_date )
date_norm = ( int(parts[0]) + int(parts[1]) )/2
elif re.search( r'[?]{2}' , str(book_date)):
date_norm = re.sub( r'[?]{2}' , '50' , book_date )
elif book_date is not None:
date_norm = book_date
if re.search( r'\d' , str(date_norm) ):
date_norm = int(date_norm)
else:
date_norm = None
out.write(f'{norm_title[0][0]}\t{title}\t{book[0][0]}\t{book[0][1]}\t{date_norm}\n')
out.close()
print( f'{count} texts have been assigned normalised titles.' )
print( f'There are {len(selected_texts)-count} without a normalised title.' )
503 texts have been assigned normalised titles. There are 4934 without a normalised title.
To be able to perform network analysis, we create an edges file and a nodes file. The nodes in this multimodal network are the texts and the books these texts are in. Note that the edges are directed: they represent the notion that a text occurs in a book.
nodes_file = open('nodes.tsv' , 'w' , encoding = 'utf-8')
edges_file = open('edges.csv' , 'w' , encoding = 'utf-8')
nodes_file.write('Id\tLabel\tType\n')
edges_file.write('Source,Target\n')
titles_dict = dict()
types_dict = dict()
nodes = []
df = pd.read_csv( 'books_of_hours.tsv' , sep = '\t' )
for i,row in df.iterrows():
nodes.append(row['text_id'])
titles_dict[ row['text_id'] ] = row['text_title'].strip()
types_dict[ row['text_id'] ] = 'Text'
nodes.append(row['book_id'])
titles_dict[ row['book_id'] ] = row['book_title'].strip()
types_dict[ row['book_id'] ] = 'Book'
edges_file.write( f"{row['text_id']},{row['book_id']}\n" )
nodes = list(set(nodes))
for n in nodes:
nodes_file.write( f"{n}\t{titles_dict[n]}\t{types_dict[n]}\n" )
edges_file.close()
nodes_file.close()
The collections of nodes are represented as Pandas data frames.
nodes_df = pd.read_csv(f'nodes.tsv' , sep = '\t' )
edges_df = pd.read_csv(f'edges.csv' )
Now that we have all the nodes and the edges, we are ready to perform the network analysis. We firstly create a network of all the nodes. Texts are shown in orange, and the books are shown in blue. The visualisation reveals that there are a number of texts that appear in many different books. This is the case for 'Teksten op naam van Bernard Clairvaux' and 'Teksten op naam van Augustinus'.
net = Network(notebook=True , height="750px", width="100%" , bgcolor="#dce5f2" )
net.force_atlas_2based(
gravity=-60,
central_gravity=0.01,
spring_length=100,
spring_strength=0.08,
damping=0.4,
overlap= 0 )
for i,row in nodes_df.iterrows():
node = row['Id']
label= row['Label']
if row['Type'] == 'Text':
c ='#EE7733'
else:
c = '#007788'
net.add_node( node , title=label, color= c , value = 15 )
for i,row in edges_df.iterrows():
net.add_edge( row['Source'] , row['Target'] )
net.show( f'network1.html')
We can analyse the networks in Python using the networkx
package.
import networkx as nx
from networkx.algorithms import community
G = nx.Graph()
for i,row in nodes_df.iterrows():
G.add_node( row['Id'] , type = row['Type'])
for i,row in edges_df.iterrows():
G.add_edge( row['Source'] , row['Target'] )
print(nx.info(G))
Graph with 431 nodes and 446 edges
We want to establish the texts that co-occur in a book.
all_nodes = G.nodes()
cooccurring_texts = dict()
unique = []
for node1 in all_nodes:
count = 0
if types_dict[node1] == 'Text':
for node2 in all_nodes:
if types_dict[node2] == 'Text' and node1 != node2:
nr_paths = nx.all_simple_paths( G,node1,node2 , 3 )
for path in nr_paths:
count += 1
cooccurring_texts[(path[0],path[2]) ] = cooccurring_texts.get( (path[0],path[2]) , 0 )+1
if count == 0:
unique.append(node1)
print('The following titles occur only once in the network:\n')
for t in unique:
print(f'{titles_dict[t]} ({t})' )
The following titles occur only once in the network: Een onderscheit van cleynmoedicheit ende van wanhopen (LEXI000000004073) O Scepper alre creatueren (LEXI000000006745) Juste judex Jhesu Criste (LEXI000000021634) Sinte Augustinus suchtinge (LEXI000000004435) O nuda humanitas (LEXI000000007604) Meditacien vanden soeten leven ende bitter passie, verrisenisse ende glorificatie ons heeren Jhesu Cristi (LEXI000000004047) Ave mundi spes Maria, berijmd (LEXI000000021653) O Martelie groot O wonden diep (LEXI000000006701) Meditationum liber unus (LEXI000000004478) Horologium aeternae sapientiae (LEXI000000004030) Johannes de Hovedena (LEXI000000005762) Gebed op naam van Augustinus op zijn sterfbed (LEXI000000004464) Gerlach Peters: Soliloquium ignitum cum Deo (LEXI000000004274) Jacobus de Voragine: Legenda aurea, ongespecificeerd (LEXI000000003958) Otto van Passau: Die vierundzwanzig Alten (LEXI000000004049) de psalmen en cantica in de standaardredactie van de Moderne Devotie (LEXI000000003324) Gebed tot alle heiligen (LEXI000000005180) stokregel O Schoone Maria staet my in staden (LEXI000000021669) Leven van Jezus van Jan Brugman (LEXI000000004957) Des heiligen geest mantel (LEXI000000021167) Sulvenite sancti Dei, occurite angeli Domini (LEXI000000021163) de Revelationes caelestes van Birgitta van Zweden (LEXI000000004036) Vita Christi (LEXI000000003787) Profectus religiosorum (LEXI000000004018) getijden van S. Maria (LEXI000000006940) Oratio sancti Hieronymi pro custodia diei sequentis (LEXI000000006064) Stimulus amoris, ongespecificeerd (LEXI000000004507) De grote Der sielen troest (LEXI000000003936) Eerste evangeliënharmonie samengesteld uit Johan Scutken: Noordnederlandse vertaling van Nieuwe Testament (LEXI000000003329) Jean de Fécamp: Summe sacerdos et vere pontifex (LEXI000000005097) Christina nobilissimis parentibus orta in Tyro Italiae (LEXI000000021630) Gulden zielen troest (LEXI000000021537) Die rolie vander woedegher minnen (LEXI000000003878) Ad te levavi animam meam (LEXI000000022561) Hi is wijs die gode mynt (LEXI000000004323) Sacrosanctae (LEXI000000005059) Noordnederlandse vertaling van Nieuwe Testament en oud-testamentische perikopen (LEXI000000003327) Gerard Zerbolt van Zutphen: De spiritualibus ascensionibus (LEXI000000004374) Mnl. bewerking van Adolf van Essen: Rosengertelin (LEXI000000022562) Bernardus van Clairvaux: Sermones super Cantica canticorum, ongespecificeerd (LEXI000000004001) Warimont, Petrus (LEXI000000022415) Zuchten en wenen van Maria (LEXI000000023072) Ave verum corpus (LEXI000000008050) Precor te amantissime Domine Jesu Christi propter eximiam caritatem (LEXI000000006237) gebed tot Jezus van Erasmus van Rotterdam (LEXI000000023055) Ave preclara maris stella (LEXI000000021802) stokregel Lof alder zuverste gods tresorie (LEXI000000021682) Der leken spiegel (LEXI000000003698) het gebed Ave salus mundi (LEXI000000006352) Sancte Herasme preciose martyr (LEXI000000006798) O Alderhoochste god almachtich (LEXI000000006436) Salve misericordia Maria, aurora fulgens, stella matutina (LEXI000000004335) Glorieuse virge reigne (LEXI000000021686) Gregorius de Grote: Homiliae in evangelia (LEXI000000004103)
This network can be plotted. The visualisation displays all the texts that cooccur in one or more books. It looks as if there are a number of 'cliques' consisting of texts that appear together.
net = Network(notebook=True , height="750px", width="100%" , bgcolor="#dce5f2" )
net.force_atlas_2based(
gravity=-60,
central_gravity=0.01,
spring_length=100,
spring_strength=0.08,
damping=0.4,
overlap= 0 )
for node in cooccurring_texts:
net.add_node( node[0] )
net.add_node( node[1] )
for node in cooccurring_texts:
net.add_edge( node[0] , node[1] , value = cooccurring_texts[node] )
net.show( f'network2.html')
The information about the intensity of the cooccurrences (i.e. how often often do two diffent texts cooccur?) can be visualised by varying the thickness of the edges. Such a visualisation can also created in Gephi. The network should be imported as a non-directed graph.
The cell below generates the CSV files that can be used for this purpose.
n = open('cooccurrences_nodes.csv' , 'w')
e = open('cooccurrences_edges.csv' , 'w')
n.write('Id')
e.write('Source,Target,Weight')
all_nodes = []
for node in cooccurring_texts:
all_nodes.append(node[0])
all_nodes.append(node[1])
all_nodes = list(set(all_nodes))
for node in all_nodes:
n.write(f'{n}\n')
for c in cooccurring_texts:
e.write(f'{c[0]},{c[1]},{cooccurring_texts[c]}\n')
from tdmh import sortedByValue
cooccurring_text_deduplicated = dict()
for c in cooccurring_texts:
if (c[1],c[0]) not in cooccurring_text_deduplicated:
cooccurring_text_deduplicated[c] = cooccurring_texts[c]
for c in sortedByValue(cooccurring_text_deduplicated , ascending = False ):
if cooccurring_text_deduplicated[c] > 1:
print( f'{titles_dict[c[0]]}({c[0]}) and {titles_dict[c[1]]}({c[1]}) occur together {cooccurring_text_deduplicated[c]} times \n' )
Mechtild van Hackeborn: Liber specialis gratiae(LEXI000000004281) and Bernardus van Clairvaux(LEXI000000004522) occur together 13 times Bernardus van Clairvaux(LEXI000000004522) and Augustinus(LEXI000000004448) occur together 12 times Mechtild van Hackeborn: Liber specialis gratiae(LEXI000000004281) and Augustinus(LEXI000000004448) occur together 9 times Bernardus van Clairvaux(LEXI000000004522) and Anselmus van Canterbury(LEXI000000004750) occur together 4 times Mechtild van Hackeborn: Liber specialis gratiae(LEXI000000004281) and Anselmus van Canterbury(LEXI000000004750) occur together 4 times Gregorius de Grote(LEXI000000004659) and Bernardus van Clairvaux(LEXI000000004522) occur together 4 times Gregorius de Grote(LEXI000000004659) and Mechtild van Hackeborn: Liber specialis gratiae(LEXI000000004281) occur together 4 times Augustinus(LEXI000000004448) and Hieronymus(LEXI000000004902) occur together 3 times Augustinus(LEXI000000004448) and Gebed tegen de pest op naam van paus Clemens(LEXI000000022623) occur together 3 times Anselmus van Canterbury(LEXI000000004750) and Augustinus(LEXI000000004448) occur together 3 times Mechtild van Hackeborn: Liber specialis gratiae(LEXI000000004281) and Gebed tegen de pest op naam van paus Clemens(LEXI000000022623) occur together 3 times Hugo van Sint-Victor(LEXI000000005214) and Augustinus(LEXI000000004448) occur together 3 times Hugo van Sint-Victor(LEXI000000005214) and Bernardus van Clairvaux(LEXI000000004522) occur together 3 times Gebed tegen de pest op naam van paus Clemens(LEXI000000022623) and Hieronymus(LEXI000000004902) occur together 2 times Augustinus(LEXI000000004448) and Henricus Suso: Horologium aeternae sapientiae(LEXI000000004031) occur together 2 times Anselmus van Canterbury(LEXI000000004750) and Hieronymus(LEXI000000004902) occur together 2 times Anselmus van Canterbury(LEXI000000004750) and Gebed tegen de pest op naam van paus Clemens(LEXI000000022623) occur together 2 times Thomas van Aquino(LEXI000000004652) and Augustinus(LEXI000000004448) occur together 2 times Thomas van Aquino(LEXI000000004652) and Bernardus van Clairvaux(LEXI000000004522) occur together 2 times Gebeden tot de lijdenswerktuigen van Christus op naam van Gregorius(LEXI000000004530) and Bernardus van Clairvaux(LEXI000000004522) occur together 2 times Beda Venerabilis(LEXI000000005152) and Augustinus(LEXI000000004448) occur together 2 times Beda Venerabilis(LEXI000000005152) and Bernardus van Clairvaux(LEXI000000004522) occur together 2 times Mechtild van Hackeborn: Liber specialis gratiae(LEXI000000004281) and Hieronymus(LEXI000000004902) occur together 2 times Mechtild van Hackeborn: Liber specialis gratiae(LEXI000000004281) and Bonaventura(LEXI000000004555) occur together 2 times Mechtild van Hackeborn: Liber specialis gratiae(LEXI000000004281) and korte getijden van het H. Kruis(LEXI000000009166) occur together 2 times Mechtild van Hackeborn: Liber specialis gratiae(LEXI000000004281) and Franciscus van Assisi(LEXI000000005265) occur together 2 times Mechtild van Hackeborn: Liber specialis gratiae(LEXI000000004281) and Thomas van Aquino(LEXI000000004652) occur together 2 times Hugo van Sint-Victor(LEXI000000005214) and Mechtild van Hackeborn: Liber specialis gratiae(LEXI000000004281) occur together 2 times Gregorius de Grote(LEXI000000004659) and Bonaventura(LEXI000000004555) occur together 2 times Die dorne croene Ons Heeren(LEXI000000005105) and Mechtild van Hackeborn: Liber specialis gratiae(LEXI000000004281) occur together 2 times Johannes Gerson(LEXI000000005386) and Bernardus van Clairvaux(LEXI000000004522) occur together 2 times
The cell below identifies the texts that occur most frequently with other texts.
degrees = dict(G.degree(G.nodes()))
for d in sortedByValue( degrees , ascending = False ):
if degrees[d] > 1:
print( f'{titles_dict[d]} ({d}) => {degrees[d] }' )
Bernardus van Clairvaux (LEXI000000004522) => 77 Augustinus (LEXI000000004448) => 65 Mechtild van Hackeborn: Liber specialis gratiae (LEXI000000004281) => 55 LEIDEN, UB : LTK 317 (TDRA000000001346) => 20 Gregorius de Grote (LEXI000000004659) => 19 Anselmus van Canterbury (LEXI000000004750) => 18 LEIDEN, UB : LTK 321 (TDRA000000001350) => 9 ANTWERPEN, SB : B 141155 (TDRA000000005597) => 8 LEIDEN, UB : LTK 323 (TDRA000000001352) => 7 MÜNCHEN, BSB : Cgm 864 (TDRA000000005388) => 7 Hugo van Sint-Victor (LEXI000000005214) => 7 Arnulf van Leuven: Salve meum salutare (LEXI000000004812) => 6 Bonaventura (LEXI000000004555) => 6 BRUSSEL, KB : 15589-623 (TDRA000000005898) => 6 Franciscus van Assisi (LEXI000000005265) => 5 Thomas van Aquino (LEXI000000004652) => 5 Gebeden tot de lijdenswerktuigen van Christus op naam van Gregorius (LEXI000000004530) => 5 UTRECHT, MCC : s.o. (TDRA000000006017) => 4 Olim LEUVEN, UB : G 70 (verloren) (TDRA000000006259) => 4 LEIDEN, UB : LTK 320 (TDRA000000001349) => 4 KEULEN, HA : W Sed. 39 (TDRA000000001982) => 4 BRUGGE, SB : 568 (TDRA000000005671) => 4 RIJSEL, BM : Olim 62 (TDRA000000007280) => 4 PURMEREND, WA : MONNICKENDAM 155 (TDRA000000005966) => 4 Johannes Gerson (LEXI000000005386) => 4 Olim WIEDER (Noordwijk) : z.s. (TDRA000000007281) => 3 Henricus Suso: Horologium aeternae sapientiae (LEXI000000004031) => 3 LÜBECK, SB : Theol. Germ. 64 (TDRA000000007259) => 3 Hieronymus (LEXI000000004902) => 3 LEIDEN, UB : LTK 324 (TDRA000000001353) => 3 Gebed tegen de pest op naam van paus Clemens (LEXI000000022623) => 3 LEIDEN, UB : LTK 349 (TDRA000000001375) => 3 DARMSTADT, HLHB : 193 (TDRA000000004726) => 3 De grote Der sielen troest (LEXI000000003936) => 3 Stimulus amoris, ongespecificeerd (LEXI000000004507) => 3 'S-GRAVENHAGE, KB : 73 G 29 (TDRA000000003457) => 3 BRUSSEL, KB : 11231-36 (TDRA000000003829) => 3 Ambrosius (LEXI000000005211) => 3 LEIDEN, UB : LTK 356 (TDRA000000001381) => 3 UTRECHT, MCC : BMH 108 (TDRA000000000506) => 3 Olim LE ROY DU VIVIER (Munsterbilsen) : z.s. (TDRA000000007460) => 3 Meester Eckhart (LEXI000000004385) => 3 UTRECHT, MCC : BMH 110 (TDRA000000000509) => 3 BRUSSEL, KB : 19588 (TDRA000000003952) => 3 BRUSSEL, KB : 21953 (TDRA000000003986) => 3 Beda Venerabilis (LEXI000000005152) => 3 Alanus de Rupe: Psalterium Virginis Mariae (LEXI000000004583) => 3 Brief aan Keizer Karel met gebed (LEXI000000009193) => 3 ROTTERDAM, GB : 96 E 7 (TDRA000000000563) => 3 BRYN MAWR, BMC : z.s. (TDRA000000006028) => 3 Olim LEUVEN, UB : D 380 (verloren) (TDRA000000006040) => 3 O nuda humanitas (LEXI000000007604) => 3 Ave tempel der Triniteit (LEXI000000006961) => 3 LONDEN, BL : Sloane 1174 (TDRA000000004462) => 3 Hubertinus de Casale (LEXI000000004876) => 3 UDEN, MRK : s.o. (TDRA000000007407) => 2 LUIK, UB : Wittert 32 (TDRA000000005740) => 2 SINT-PETERSBURG, BAN : O 255 (TDRA000000002188) => 2 BOEDAPEST, OSK : Holl. 6 (TDRA000000002036) => 2 Vader danc ende lof soe moet ghi hebben (LEXI000000007942) => 2 BRUSSEL, KB : 11171 (TDRA000000003822) => 2 BRUSSEL, KB : 12079 (TDRA000000003850) => 2 Onser liever vrouwen mantel (LEXI000000005114) => 2 Olim SOTHEBY'S (Londen) : Cat. 1984-07-03, nr.89 (TDRA000000011882) => 2 Salve misericordia Maria, aurora fulgens, stella matutina (LEXI000000004335) => 2 Groeten tot Maria (LEXI000000007269) => 2 'S-GRAVENHAGE, KB : 133 F 7 (TDRA000000003363) => 2 De zeven banden van Jezus (LEXI000000022201) => 2 ROTTERDAM, GB : 96 E 12 (TDRA000000000566) => 2 KOPENHAGEN, KB : Thott 132 Oct. (TDRA000000004617) => 2 DARMSTADT, HLHB : 1918 (TDRA000000004711) => 2 Precor te amantissime Domine Jesu Christi propter eximiam caritatem (LEXI000000006237) => 2 TILBURG, UB : KHS 19 (TDRA000000008128) => 2 VAN DER LANDE (Diepenveen) : z.s. (TDRA000000007976) => 2 Thomas a Kempis: Orationes et meditationes de vita Christi (LEXI000000005652) => 2 Bernardus van Clairvaux: Sermones super Cantica canticorum, ongespecificeerd (LEXI000000004001) => 2 EMDEN, GK : Qu. 76 (TDRA000000013233) => 2 RIJSEL, BM : Olim 68 (TDRA000000007920) => 2 JERNBECK (Stockholm) : z.s. (TDRA000000006030) => 2 GENT, UB : 2364 (TDRA000000000291) => 2 BRUSSEL, KB : 10763-64 (TDRA000000003805) => 2 Drieëndertig vermaningen aan Jezus (LEXI000000023071) => 2 ROME, BAV : Vat. Lat. 9216 (TDRA000000007405) => 2 Olim NIJHOFF ('s-Gravenhage) : 4 (BNM) (TDRA000000007519) => 2 LEIDEN, UB : LTK 294 (TDRA000000001326) => 2 LEIDEN, UB : LTK 325 (TDRA000000001354) => 2 JASPERS (Aerdenhout) : z.s. (TDRA000000011080) => 2 Oratio de septem verbis Christi in cruce, in proza (LEXI000000005127) => 2 DRESDEN, SL : M 291 (TDRA000000002046) => 2 BRUSSEL, KB : 22012 (TDRA000000003991) => 2 UTRECHT, MCC : ABM 38 (TDRA000000004974) => 2 UTRECHT, MCC : BMH 62 (TDRA000000000482) => 2 BRUSSEL, KB : 12080 (TDRA000000003851) => 2 korte getijden van het H. Kruis (LEXI000000009166) => 2 Seghelijn van Jherusalem (LEXI000000004184) => 2 Leven van Jezus van Jan Brugman (LEXI000000004957) => 2 KARLSRUHE, BLB : 1307 (TDRA000000006034) => 2 BRUGGE, GS : 72/175 (TDRA000000006558) => 2 CAMBRIDGE, FM : 270 (TDRA000000004299) => 2 Gregorius XI: Gebed tot de vijf wonden van Christus (LEXI000000004882) => 2 PHILADELPHIA, FL : Lewis European 217 (TDRA000000008147) => 2 SINT-PETERSBURG, BSS : Goll. O.I, 2 (TDRA000000002521) => 2 lange getijden van het H. Kruis (LEXI000000009162) => 2 DARMSTADT, HLHB : 1936 (TDRA000000004731) => 2 AMSTERDAM, BPH : ICN 158 (TDRA000000006002) => 2 OXFORD, BL : Canonici Liturg. 217 (TDRA000000004478) => 2 BRUSSEL, KB : 18270 (TDRA000000003915) => 2 'S-GRAVENHAGE, KB : 133 H 11 (TDRA000000003369) => 2 ZÜRICH, ZB : C 137 (TDRA000000006022) => 2 BRUSSEL, KB : II 6907 (TDRA000000004209) => 2 Meditationum liber unus (LEXI000000004478) => 2 Olim NIJHOFF ('s-Gravenhage) : 3 (BNM) (TDRA000000007456) => 2 Olim DE BOM (Antwerpen) : 2 (TDRA000000005973) => 2 DARMSTADT, HLHB : 1938 (TDRA000000004728) => 2 Büchlein der ewigen Weisheit (LEXI000000004029) => 2 DARMSTADT, HLHB : 189 (TDRA000000004732) => 2 Ave mundi spes Maria, berijmd (LEXI000000021653) => 2 HAMBURG, SUB : Theol. 2058 (TDRA000000005583) => 2 'S-HEERENBERG, HB : 10 (TDRA000000002749) => 2 WENEN, ONB : Series Nova 12869 (TDRA000000002436) => 2 OXFORD, BL : Dutch f 1 (TDRA000000007459) => 2 Die dorne croene Ons Heeren (LEXI000000005105) => 2 SINT-TRUIDEN, IFG : B 66 (TDRA000000007290) => 2 ROTTERDAM, GB : 96 F 6 (TDRA000000000565) => 2
The following texts are unique in the network.
for d in sortedByValue( degrees , ascending = False ):
if degrees[d] == 1 and types_dict[d] == 'Text':
print( f'{titles_dict[d]} ({d})' )
Gregorius de Grote: Homiliae in evangelia (LEXI000000004103) Leven van S. Amand (LEXI000000006326) Regina celi letare (LEXI000000009183) O here Jhesu Criste die alle tijt voir onse sculde gheoffert werdes (LEXI000000005200) Ludolf van Saksen: Vita Christi (LEXI000000004485) Ambrosius: In praeparatione ad missam, berijmd (LEXI000000021642) Glorieuse virge reigne (LEXI000000021686) Vijftien Pater Noster van de passie (LEXI000000005329) Onze Vader (LEXI000000004148) Maria vrouwe edel maghet (LEXI000000021685) O Alderhoochste god almachtich (LEXI000000006436) Sancte Herasme preciose martyr (LEXI000000006798) het gebed Ave salus mundi (LEXI000000006352) Christus et sanctus Johannes, berijmd (LEXI000000021652) Openbaringen van Birgitta van Zweden, ongespecificeerd (LEXI000000004041) Der leken spiegel (LEXI000000003698) stokregel Lof alder zuverste gods tresorie (LEXI000000021682) Ave preclara maris stella (LEXI000000021802) gebed tot Jezus van Erasmus van Rotterdam (LEXI000000023055) Leven van Henricus Suso (LEXI000000004484) Lof God van desen als u belieft salt beter wesen (LEXI000000022408) Ave verum corpus (LEXI000000008050) Zuchten en wenen van Maria (LEXI000000023072) O vrouwe der glorien, coninginne der bliscappen (LEXI000000004786) Warimont, Petrus (LEXI000000022415) Sente Goedele reine maget (LEXI000000021687) Mnl. bewerking van Adolf van Essen: Rosengertelin (LEXI000000022562) Gerard Zerbolt van Zutphen: De spiritualibus ascensionibus (LEXI000000004374) Noordnederlandse vertaling van Nieuwe Testament en oud-testamentische perikopen (LEXI000000003327) Het Cuelsche pater noster (LEXI000000004293) Tweede Eckbert van Schönau: Sermo de vita et passione Jesu Christi (LEXI000000004514) Sacrosanctae (LEXI000000005059) Hi is wijs die gode mynt (LEXI000000004323) gebedenkrans (LEXI000000006942) Ad te levavi animam meam (LEXI000000022561) de getijden van S. Maria (LEXI000000009161) Gebed tot Christus en Zijn wonden op naam van Gregorius de Grote (LEXI000000004881) Gebeden ter ere van de ledematen van S. Maria (LEXI000000005175) Gebed voor de communie ontleend aan het Manuale (LEXI000000004474) Die rolie vander woedegher minnen (LEXI000000003878) O leven der armen, o lichte inder duysternis (LEXI000000005271) Communiegebed , Ad te fontem misericordiae (LEXI000000007685) gebed tot de drievuldigheid uit Meditationum liber unus (LEXI000000004476) Gulden zielen troest (LEXI000000021537) Christina nobilissimis parentibus orta in Tyro Italiae (LEXI000000021630) Jean de Fécamp: Summe sacerdos et vere pontifex (LEXI000000005097) O intemerata, berijmd (LEXI000000004732) Eerste evangeliënharmonie samengesteld uit Johan Scutken: Noordnederlandse vertaling van Nieuwe Testament (LEXI000000003329) getijden van de Heilige Geest (LEXI000000009163) Gebed voor de eucharistie uit Henricus Suso: Büchlein der ewigen Weisheit (LEXI000000004654) Ons liefs heren passie (LEXI000000021266) Eest drooghe eest nat // deus benedicat (LEXI000000022406) Oratio sancti Hieronymi pro custodia diei sequentis (LEXI000000006064) Die clausule van der Bible (LEXI000000003633) Illumina oculos meos (LEXI000000004333) Pro custodienta humilitate et cognitione humanae fragilitatis (LEXI000000004472) getijden van S. Maria (LEXI000000006940) Profectus religiosorum (LEXI000000004018) Vita Christi (LEXI000000003787) de Revelationes caelestes van Birgitta van Zweden (LEXI000000004036) In praesentia corporis et sanguinis tui (LEXI000000005210) Sulvenite sancti Dei, occurite angeli Domini (LEXI000000021163) O here Jhesu Criste, lof si dijnre onsprekeliker minnentliker goedertierenheit (LEXI000000005198) Des heiligen geest mantel (LEXI000000021167) gebed Omnipotens sempiterne Deus, ecce accedo (LEXI000000004645) Gebed tot de schouderwonde van Jezus (LEXI000000007149) stokregel O Schoone Maria staet my in staden (LEXI000000021669) Lof eere glorie van tije tot tyen (LEXI000000021392) Gebed tot alle heiligen (LEXI000000005180) Gebed op naam van Bernardinus van Siena (LEXI000000004862) de psalmen en cantica in de standaardredactie van de Moderne Devotie (LEXI000000003324) Gulden gebed voor de overledenen (LEXI000000007938) Gebed over het lijden van Jezus, geopenbaard aan paus Silvester (LEXI000000005165) Otto van Passau: Die vierundzwanzig Alten (LEXI000000004049) vreugden van S. Maria (LEXI000000006453) Gebed op naam van Augustinus bij de zeven boetpsalmen (LEXI000000004469) Jacobus de Voragine: Legenda aurea, ongespecificeerd (LEXI000000003958) Vincentius Ferrerius: Gebed tot de naam van Jezus (LEXI000000004669) Gerlach Peters: Soliloquium ignitum cum Deo (LEXI000000004274) Gebed op naam van Augustinus op zijn sterfbed (LEXI000000004464) Ave salus mundi (LEXI000000022255) Gebed tot de vijf wonden van Christus op naam van Franciscus van Assisi (LEXI000000005078) Johannes de Hovedena (LEXI000000005762) Horologium aeternae sapientiae (LEXI000000004030) droefheden van Maria (LEXI000000006435) O Afgront alre goetheit (LEXI000000007937) het gebed Adore te (LEXI000000004649) O intemerata, in proza (LEXI000000004730) O Martelie groot O wonden diep (LEXI000000006701) Jean de Fécamp: Invoco te (LEXI000000004751) Meditacien vanden soeten leven ende bitter passie, verrisenisse ende glorificatie ons heeren Jhesu Cristi (LEXI000000004047) Sinte Augustinus suchtinge (LEXI000000004435) Juste judex Jhesu Criste (LEXI000000021634) O Scepper alre creatueren (LEXI000000006745) Een onderscheit van cleynmoedicheit ende van wanhopen (LEXI000000004073) Miserere (LEXI000000004493) Ic bevele mijn doot inden bitteren doot ons lieven heren Jezus Christus (LEXI000000007297)
Which books do these texts appear in?
for c in sortedByValue(cooccurring_text_deduplicated , ascending = False ):
if cooccurring_text_deduplicated[c] > 1:
nr_paths = nx.all_simple_paths( G,c[0],c[1] , 3 )
for path in nr_paths:
print(f'{path[0]} and {path[2]} both occur in ')
print( f'{titles_dict[path[1]]} ({path[1]})\n')
LEXI000000004281 and LEXI000000004522 both occur in WENEN, ONB : Series Nova 12869 (TDRA000000002436) LEXI000000004281 and LEXI000000004522 both occur in DARMSTADT, HLHB : 1936 (TDRA000000004731) LEXI000000004281 and LEXI000000004522 both occur in DARMSTADT, HLHB : 1938 (TDRA000000004728) LEXI000000004281 and LEXI000000004522 both occur in AMSTERDAM, BPH : ICN 158 (TDRA000000006002) LEXI000000004281 and LEXI000000004522 both occur in BRUSSEL, KB : 22012 (TDRA000000003991) LEXI000000004281 and LEXI000000004522 both occur in KARLSRUHE, BLB : 1307 (TDRA000000006034) LEXI000000004281 and LEXI000000004522 both occur in Olim LE ROY DU VIVIER (Munsterbilsen) : z.s. (TDRA000000007460) LEXI000000004281 and LEXI000000004522 both occur in UTRECHT, MCC : s.o. (TDRA000000006017) LEXI000000004281 and LEXI000000004522 both occur in Olim LEUVEN, UB : G 70 (verloren) (TDRA000000006259) LEXI000000004281 and LEXI000000004522 both occur in LEIDEN, UB : LTK 321 (TDRA000000001350) LEXI000000004281 and LEXI000000004522 both occur in DARMSTADT, HLHB : 193 (TDRA000000004726) LEXI000000004281 and LEXI000000004522 both occur in BRYN MAWR, BMC : z.s. (TDRA000000006028) LEXI000000004281 and LEXI000000004522 both occur in UTRECHT, MCC : BMH 62 (TDRA000000000482) LEXI000000004522 and LEXI000000004448 both occur in EMDEN, GK : Qu. 76 (TDRA000000013233) LEXI000000004522 and LEXI000000004448 both occur in UTRECHT, MCC : s.o. (TDRA000000006017) LEXI000000004522 and LEXI000000004448 both occur in BRUSSEL, KB : 21953 (TDRA000000003986) LEXI000000004522 and LEXI000000004448 both occur in LEIDEN, UB : LTK 321 (TDRA000000001350) LEXI000000004522 and LEXI000000004448 both occur in UTRECHT, MCC : ABM 38 (TDRA000000004974) LEXI000000004522 and LEXI000000004448 both occur in RIJSEL, BM : Olim 62 (TDRA000000007280) LEXI000000004522 and LEXI000000004448 both occur in ROTTERDAM, GB : 96 E 12 (TDRA000000000566) LEXI000000004522 and LEXI000000004448 both occur in 'S-HEERENBERG, HB : 10 (TDRA000000002749) LEXI000000004522 and LEXI000000004448 both occur in Olim WIEDER (Noordwijk) : z.s. (TDRA000000007281) LEXI000000004522 and LEXI000000004448 both occur in ROME, BAV : Vat. Lat. 9216 (TDRA000000007405) LEXI000000004522 and LEXI000000004448 both occur in UTRECHT, MCC : BMH 108 (TDRA000000000506) LEXI000000004522 and LEXI000000004448 both occur in GENT, UB : 2364 (TDRA000000000291) LEXI000000004281 and LEXI000000004448 both occur in BRUSSEL, KB : 11231-36 (TDRA000000003829) LEXI000000004281 and LEXI000000004448 both occur in SINT-PETERSBURG, BSS : Goll. O.I, 2 (TDRA000000002521) LEXI000000004281 and LEXI000000004448 both occur in OXFORD, BL : Dutch f 1 (TDRA000000007459) LEXI000000004281 and LEXI000000004448 both occur in 'S-GRAVENHAGE, KB : 73 G 29 (TDRA000000003457) LEXI000000004281 and LEXI000000004448 both occur in ANTWERPEN, SB : B 141155 (TDRA000000005597) LEXI000000004281 and LEXI000000004448 both occur in UTRECHT, MCC : s.o. (TDRA000000006017) LEXI000000004281 and LEXI000000004448 both occur in MÜNCHEN, BSB : Cgm 864 (TDRA000000005388) LEXI000000004281 and LEXI000000004448 both occur in DARMSTADT, HLHB : 189 (TDRA000000004732) LEXI000000004281 and LEXI000000004448 both occur in LEIDEN, UB : LTK 321 (TDRA000000001350) LEXI000000004522 and LEXI000000004750 both occur in Olim LE ROY DU VIVIER (Munsterbilsen) : z.s. (TDRA000000007460) LEXI000000004522 and LEXI000000004750 both occur in BRUGGE, SB : 568 (TDRA000000005671) LEXI000000004522 and LEXI000000004750 both occur in KOPENHAGEN, KB : Thott 132 Oct. (TDRA000000004617) LEXI000000004522 and LEXI000000004750 both occur in SINT-TRUIDEN, IFG : B 66 (TDRA000000007290) LEXI000000004281 and LEXI000000004750 both occur in LEIDEN, UB : LTK 349 (TDRA000000001375) LEXI000000004281 and LEXI000000004750 both occur in ANTWERPEN, SB : B 141155 (TDRA000000005597) LEXI000000004281 and LEXI000000004750 both occur in Olim LE ROY DU VIVIER (Munsterbilsen) : z.s. (TDRA000000007460) LEXI000000004281 and LEXI000000004750 both occur in MÜNCHEN, BSB : Cgm 864 (TDRA000000005388) LEXI000000004659 and LEXI000000004522 both occur in BRYN MAWR, BMC : z.s. (TDRA000000006028) LEXI000000004659 and LEXI000000004522 both occur in KEULEN, HA : W Sed. 39 (TDRA000000001982) LEXI000000004659 and LEXI000000004522 both occur in LEIDEN, UB : LTK 294 (TDRA000000001326) LEXI000000004659 and LEXI000000004522 both occur in ZÜRICH, ZB : C 137 (TDRA000000006022) LEXI000000004659 and LEXI000000004281 both occur in BRYN MAWR, BMC : z.s. (TDRA000000006028) LEXI000000004659 and LEXI000000004281 both occur in Olim NIJHOFF ('s-Gravenhage) : 3 (BNM) (TDRA000000007456) LEXI000000004659 and LEXI000000004281 both occur in UTRECHT, MCC : BMH 110 (TDRA000000000509) LEXI000000004659 and LEXI000000004281 both occur in Olim LEUVEN, UB : D 380 (verloren) (TDRA000000006040) LEXI000000004448 and LEXI000000004902 both occur in MÜNCHEN, BSB : Cgm 864 (TDRA000000005388) LEXI000000004448 and LEXI000000004902 both occur in ANTWERPEN, SB : B 141155 (TDRA000000005597) LEXI000000004448 and LEXI000000004902 both occur in RIJSEL, BM : Olim 62 (TDRA000000007280) LEXI000000004448 and LEXI000000022623 both occur in MÜNCHEN, BSB : Cgm 864 (TDRA000000005388) LEXI000000004448 and LEXI000000022623 both occur in ANTWERPEN, SB : B 141155 (TDRA000000005597) LEXI000000004448 and LEXI000000022623 both occur in BRUSSEL, KB : 11231-36 (TDRA000000003829) LEXI000000004750 and LEXI000000004448 both occur in PURMEREND, WA : MONNICKENDAM 155 (TDRA000000005966) LEXI000000004750 and LEXI000000004448 both occur in ANTWERPEN, SB : B 141155 (TDRA000000005597) LEXI000000004750 and LEXI000000004448 both occur in MÜNCHEN, BSB : Cgm 864 (TDRA000000005388) LEXI000000004281 and LEXI000000022623 both occur in BRUSSEL, KB : 11231-36 (TDRA000000003829) LEXI000000004281 and LEXI000000022623 both occur in ANTWERPEN, SB : B 141155 (TDRA000000005597) LEXI000000004281 and LEXI000000022623 both occur in MÜNCHEN, BSB : Cgm 864 (TDRA000000005388) LEXI000000005214 and LEXI000000004448 both occur in Olim WIEDER (Noordwijk) : z.s. (TDRA000000007281) LEXI000000005214 and LEXI000000004448 both occur in ROTTERDAM, GB : 96 E 7 (TDRA000000000563) LEXI000000005214 and LEXI000000004448 both occur in MÜNCHEN, BSB : Cgm 864 (TDRA000000005388) LEXI000000005214 and LEXI000000004522 both occur in 'S-GRAVENHAGE, KB : 133 H 11 (TDRA000000003369) LEXI000000005214 and LEXI000000004522 both occur in JASPERS (Aerdenhout) : z.s. (TDRA000000011080) LEXI000000005214 and LEXI000000004522 both occur in Olim WIEDER (Noordwijk) : z.s. (TDRA000000007281) LEXI000000022623 and LEXI000000004902 both occur in MÜNCHEN, BSB : Cgm 864 (TDRA000000005388) LEXI000000022623 and LEXI000000004902 both occur in ANTWERPEN, SB : B 141155 (TDRA000000005597) LEXI000000004448 and LEXI000000004031 both occur in PURMEREND, WA : MONNICKENDAM 155 (TDRA000000005966) LEXI000000004448 and LEXI000000004031 both occur in OXFORD, BL : Canonici Liturg. 217 (TDRA000000004478) LEXI000000004750 and LEXI000000004902 both occur in ANTWERPEN, SB : B 141155 (TDRA000000005597) LEXI000000004750 and LEXI000000004902 both occur in MÜNCHEN, BSB : Cgm 864 (TDRA000000005388) LEXI000000004750 and LEXI000000022623 both occur in ANTWERPEN, SB : B 141155 (TDRA000000005597) LEXI000000004750 and LEXI000000022623 both occur in MÜNCHEN, BSB : Cgm 864 (TDRA000000005388) LEXI000000004652 and LEXI000000004448 both occur in LÜBECK, SB : Theol. Germ. 64 (TDRA000000007259) LEXI000000004652 and LEXI000000004448 both occur in UTRECHT, MCC : s.o. (TDRA000000006017) LEXI000000004652 and LEXI000000004522 both occur in UTRECHT, MCC : s.o. (TDRA000000006017) LEXI000000004652 and LEXI000000004522 both occur in KEULEN, HA : W Sed. 39 (TDRA000000001982) LEXI000000004530 and LEXI000000004522 both occur in DRESDEN, SL : M 291 (TDRA000000002046) LEXI000000004530 and LEXI000000004522 both occur in 'S-GRAVENHAGE, KB : 133 F 7 (TDRA000000003363) LEXI000000005152 and LEXI000000004448 both occur in RIJSEL, BM : Olim 62 (TDRA000000007280) LEXI000000005152 and LEXI000000004448 both occur in JERNBECK (Stockholm) : z.s. (TDRA000000006030) LEXI000000005152 and LEXI000000004522 both occur in RIJSEL, BM : Olim 62 (TDRA000000007280) LEXI000000005152 and LEXI000000004522 both occur in RIJSEL, BM : Olim 68 (TDRA000000007920) LEXI000000004281 and LEXI000000004902 both occur in ANTWERPEN, SB : B 141155 (TDRA000000005597) LEXI000000004281 and LEXI000000004902 both occur in MÜNCHEN, BSB : Cgm 864 (TDRA000000005388) LEXI000000004281 and LEXI000000004555 both occur in Olim LEUVEN, UB : D 380 (verloren) (TDRA000000006040) LEXI000000004281 and LEXI000000004555 both occur in SINT-PETERSBURG, BAN : O 255 (TDRA000000002188) LEXI000000004281 and LEXI000000009166 both occur in BRUSSEL, KB : 12079 (TDRA000000003850) LEXI000000004281 and LEXI000000009166 both occur in BRUSSEL, KB : 12080 (TDRA000000003851) LEXI000000004281 and LEXI000000005265 both occur in 'S-GRAVENHAGE, KB : 73 G 29 (TDRA000000003457) LEXI000000004281 and LEXI000000005265 both occur in DARMSTADT, HLHB : 193 (TDRA000000004726) LEXI000000004281 and LEXI000000004652 both occur in LEIDEN, UB : LTK 317 (TDRA000000001346) LEXI000000004281 and LEXI000000004652 both occur in UTRECHT, MCC : s.o. (TDRA000000006017) LEXI000000005214 and LEXI000000004281 both occur in LEIDEN, UB : LTK 356 (TDRA000000001381) LEXI000000005214 and LEXI000000004281 both occur in MÜNCHEN, BSB : Cgm 864 (TDRA000000005388) LEXI000000004659 and LEXI000000004555 both occur in KEULEN, HA : W Sed. 39 (TDRA000000001982) LEXI000000004659 and LEXI000000004555 both occur in Olim LEUVEN, UB : D 380 (verloren) (TDRA000000006040) LEXI000000005105 and LEXI000000004281 both occur in ANTWERPEN, SB : B 141155 (TDRA000000005597) LEXI000000005105 and LEXI000000004281 both occur in LEIDEN, UB : LTK 317 (TDRA000000001346) LEXI000000005386 and LEXI000000004522 both occur in BRUGGE, SB : 568 (TDRA000000005671) LEXI000000005386 and LEXI000000004522 both occur in TILBURG, UB : KHS 19 (TDRA000000008128)
print( f"Network density: {nx.density(G) }" )
Network density: 0.004813036205687153
all_nodes = G.nodes()
all_books = []
all_texts = []
for node in all_nodes:
if types_dict[node] == 'Book':
all_books.append(node)
else:
all_texts.append(node)
books_dict = dict()
## Create a list of all the texts in each book
for book in all_books:
texts_list = []
for t in all_texts:
nr_paths = nx.all_simple_paths( G,book,t , 2 )
for path in nr_paths:
texts_list.append( path[1] )
books_dict[book] = texts_list
## next, create an overview of the number of texts the books have in common
books_edges = dict()
for book1 in books_dict:
for book2 in books_dict:
if book1 != book2:
intersection = list(set(books_dict[book1]) & set(books_dict[book2]))
if len(intersection) > 2:
books_edges[(book1,book2)] = len(intersection)
sbn = open( 'similar_books_nodes.csv' , 'w' )
sbe = open( 'similar_books_edges.csv' , 'w' )
sbn.write('Id\n')
sbe.write('Source,Target\n')
nodes = []
for be in books_edges:
sbe.write(f'{be[0]},{be[1]}\n')
if be[0] not in nodes:
nodes.append(be[0])
if be[1] not in nodes:
nodes.append(be[0])
for n in nodes:
sbn.write(f'{n}\n')
sbn.close()
sbe.close()
net = Network(notebook=True , height="750px", width="100%" , bgcolor="#dce5f2" )
net.force_atlas_2based(
gravity=-60,
central_gravity=0.01,
spring_length=100,
spring_strength=0.08,
damping=0.4,
overlap= 0 )
for node in books_edges:
net.add_node( node[0] )
net.add_node( node[1] )
for node in books_edges:
net.add_edge( node[0] , node[1] , value = books_edges[node] )
net.show( f'network3.html')
betweenness_dict = nx.betweenness_centrality(G)
eigenvector_dict = nx.eigenvector_centrality(G)
nx.set_node_attributes(G, betweenness_dict, 'betweenness')
nx.set_node_attributes(G, eigenvector_dict, 'eigenvector')
sorted_betweenness = sorted(betweenness_dict.items(), key=itemgetter(1), reverse=True)
print("5 nodes with the higest betweenness centrality:")
for b in sorted_betweenness[:5]:
print( f'{titles_dict[b[0]]} ({b[0]}), {b[1]} ' )
print('\n')
sorted_eigen = sorted(eigenvector_dict.items(), key=itemgetter(1), reverse=True)
print("5 nodes with the higest eigenvector centrality:")
for e in sorted_eigen[:5]:
print( f'{titles_dict[e[0]]} ({e[0]}), {e[1]} ' )
5 nodes with the higest betweenness centrality: Bernardus van Clairvaux (LEXI000000004522), 0.19111843838827663 Mechtild van Hackeborn: Liber specialis gratiae (LEXI000000004281), 0.1678708863923592 Augustinus (LEXI000000004448), 0.16439967935972105 LEIDEN, UB : LTK 317 (TDRA000000001346), 0.06614951169112727 Gregorius de Grote (LEXI000000004659), 0.036703077584986095 5 nodes with the higest eigenvector centrality: Bernardus van Clairvaux (LEXI000000004522), 0.5336458872587647 Augustinus (LEXI000000004448), 0.3437638679496076 Mechtild van Hackeborn: Liber specialis gratiae (LEXI000000004281), 0.28781326407734725 LEIDEN, UB : LTK 321 (TDRA000000001350), 0.1287468489102948 UTRECHT, MCC : s.o. (TDRA000000006017), 0.12340895443317042