The Graph is the Story
Why Knowledge Graphs Reveal What Text Cannot
Part 1 of a Fabula blog series
A screenplay is a sequence of words. A spreadsheet of character appearances is a table of counts. A knowledge graph is something else entirely: a structure where the connections between things carry meaning that neither the words nor the counts can express.
This is the founding argument of Fabula, and it is not a metaphor. When we process a season of television through our pipeline — extracting characters, events, locations, relationships, and narrative arcs into a Neo4j graph — we do not merely store what the script said. We make visible what the story meant.
What Flat Data Sees (and What It Cannot)
Imagine you have a database table listing every character appearance in Doctor Who Season 4 (1966-67, the Second Doctor era). You can count that The Doctor appears in 756 events, Ben Jackson in 446, Polly Wright in 432, Jamie McCrimmon in 382. Useful numbers. You could sort them, compute averages, draw a bar chart.
But counts cannot answer the question that matters most: what would happen to the story if you removed one of these characters?
That question is structural. It lives in the topology of relationships, not in any column of any table. And it is precisely the kind of question a knowledge graph was built to answer.
The Power Law of Dramatic Weight
When we examine how Season 4’s 275 characters distribute across events, a pattern emerges that no one wrote into the script but the graph makes undeniable:
1–10 events: 184 characters, 66.9% share
11–20 events: 35 characters, 12.7% share
21–50 events: 42 characters, 15.3% share
51–100 events: 10 characters, 3.6% share
200+ events: 4 characters, 1.5% share
This is a power-law distribution. Two-thirds of all characters exist in fewer than ten events. Four characters — The Doctor, Ben, Polly, Jamie — command the top tier. The graph did not invent this hierarchy; the writers did, across 43 episodes, one scene at a time. But no writer ever sat down and said “I shall allocate dramatic weight according to a power law.” The graph reveals the emergent mathematics of storytelling.
You can extract this distribution with a single query:
MATCH (a:Agent)-[p:PARTICIPATED_AS]->(e:Event)
WHERE a.status = 'canonical'
WITH a, count(DISTINCT e) AS event_count
RETURN CASE
WHEN event_count <= 10 THEN '1-10'
WHEN event_count <= 20 THEN '11-20'
WHEN event_count <= 50 THEN '21-50'
WHEN event_count <= 100 THEN '51-100'
ELSE '200+'
END AS bracket,
count(a) AS characters
ORDER BY min(event_count)Bridge Characters: The Load-Bearing Walls of Narrative
Now for the insight that only a graph can provide. When we compute how many otherwise-isolated character clusters each character connects, we find:
The Doctor: 428 connected isolates
Ben Jackson: 312
Polly Wright: 290
Jamie McCrimmon: 246
Commandant: 74
Cybermen: 72
This is not the same information as “The Doctor appears a lot.” Event count tells you a character is present. Bridge analysis tells you a character is structurally necessary. Remove The Doctor from the graph and you do not merely lose 756 event participations — you shatter the narrative into 428 disconnected islands. Characters who never shared a scene, who existed in entirely separate storylines, were held in the same narrative universe by the Doctor’s presence in both.
Ben Jackson’s bridge score of 312 is extraordinary for a companion. He is not just travelling with the Doctor — he is independently connecting clusters of characters, functioning as a secondary structural spine for the season.
The Asymmetry of Companionship
Co-occurrence data — which characters share events — encodes relationship dynamics with startling precision:
MATCH (a1:Agent)-[:PARTICIPATED_AS]->(e:Event)<-[:PARTICIPATED_AS]-(a2:Agent)
WHERE a1.status = 'canonical' AND a2.status = 'canonical'
AND id(a1) < id(a2)
WITH a1, a2, count(DISTINCT e) AS shared
ORDER BY shared DESC LIMIT 8
RETURN a1.canonical_name, a2.canonical_name, sharedThe results tell a story about companion dynamics:
Doctor-Ben: 359 shared events
Doctor-Polly: 352 shared events
Polly-Ben: 306 shared events
Doctor-Jamie: 286 shared events
Jamie-Victoria: 56 shared events
Ben and Polly are a unit. Their 306 shared events (out of Ben’s 446 and Polly’s 432) mean they appear together in roughly 70% of their scenes. They are dramatically inseparable — the graph confirms what any viewer of the era would tell you, but now it is computable fact.
Jamie and Victoria, by contrast, share only 56 events despite both being companions. Their relationship is mediated through the Doctor rather than existing independently. The graph topology distinguishes these two very different kinds of partnership without anyone having to label them.
The Combinatorial Horizon
Here is where it gets genuinely interesting. Season 4 contains 369 agents connected by 5,147 PARTICIPATED_AS edges to 1,147 events, plus 509 causal links between events, 180 conflict arcs, and 410 organizational affiliations. This is not a large graph by industrial standards. But it encodes access to millions of possible multi-hop paths.
Every query is a question the graph can answer that the script never explicitly asked:
// Which characters are connected through causal event chains
// but never shared an event directly?
MATCH (a1:Agent)-[:PARTICIPATED_AS]->(e1:Event)-[:CAUSAL*1..3]->(e2:Event)<-[:PARTICIPATED_AS]-(a2:Agent)
WHERE a1.status = 'canonical' AND a2.status = 'canonical'
AND NOT EXISTS {
MATCH (a1)-[:PARTICIPATED_AS]->(shared:Event)<-[:PARTICIPATED_AS]-(a2)
}
RETURN a1.canonical_name, a2.canonical_name,
[n IN nodes(path) WHERE n:Event | n.title] AS causal_chainCharacters connected by causation but separated by presence. Actions that ripple forward to affect people the actor never met. This is narrative structure — and it was always there in the script, implicit in the sequence of scenes, but invisible until the graph made it traversable.
What the Graph Knows
A screenplay tells you what happened. A spreadsheet tells you how often. A knowledge graph tells you what holds the story together, and what would happen if you pulled a thread.
The graph does not store what the story said. It makes visible what the story meant.
That is why we built Fabula. And in the posts that follow, we will show you how deep this rabbit hole goes — from belief states and dramatic irony to the mathematical structure of narrative itself.
Next: [Post #2 — “Topology as Meaning: What Graph Structure Encodes About Narrative”]
Built with Fabula. Data from Doctor Who Season 4 (1966-67), processed into Neo4j knowledge graphs.

