This notebook follows the Turkish state across fourteen centuries, one map at a time: the Turkic khaganates of the Central Asian steppe, the Seljuk conquest of the Middle East, the long rise of the Ottoman Empire to a Mediterranean superpower, its slow dismemberment, the partition of 1920, and the Republic of Turkey that rose from it. Each panel is zoomed to the action of its own age and marks the capitals (diamonds, bold labels), the important cities of the day (small points), and the neighbouring powers (grey, faintly labelled). When the realm fractured - after Timur in 1400, and in the 1920 partition - the pieces are drawn in separate colours. The maps grow denser through the last five centuries, where most of the story happens. At the end, a single plate overlays every era’s territory on one map, coloured by year, so the whole expansion and retreat reads at a glance.
Territorial outlines come from the
historical-basemaps project
(aourednik/historical-basemaps, CC-BY-SA), which
reconstructs world polity borders at fixed years; the snapshot year for
each map is chosen to sit inside the period, and the subtitle gives the
historical date even where the source map is a few decades off (the
conquest of Constantinople is dated 1453 but drawn from the c. 1500
borders, for example). Reconstructed historical borders are
interpretations of reach and control, not survey lines. Capitals and
cities are a hand-curated table (cities.json) of well-known
coordinates, tagged with the periods in which each mattered. Modern
coastlines (faint grey) come from Natural Earth as a geographic anchor
only. The state names shown in the legend are the source’s own labels
(e.g. the source calls the Sultanate of Rum the “Seljuk Caliphate”).
config <- fromJSON("data.json", simplifyVector = TRUE,
simplifyDataFrame = FALSE, simplifyMatrix = FALSE)
periods_by_key <- set_names(config$periods, map_chr(config$periods, "key"))
coastline <- st_read("coastline.geojson", quiet = TRUE)
cities_raw <- fromJSON("cities.json", simplifyVector = FALSE)
cities_role <- function(period_key, role) {
matched <- keep(cities_raw, ~ period_key %in% unlist(.x[[role]]))
if (length(matched) == 0) return(tibble::tibble(name = character(),
lon = numeric(), lat = numeric()))
map_dfr(matched, ~ tibble::tibble(name = .x$name, lon = .x$lon, lat = .x$lat))
}
Because each map is zoomed to a different theatre, a small locator inset sits in the top-left corner of every panel: a wide view of Eurasia and the Mediterranean with a red box marking where the current map sits, so a tightly cropped view is never disorienting.
make_minimap <- function(extent) {
ggplot() +
geom_sf(data = coastline, fill = "grey88", colour = "grey70", linewidth = 0.12) +
annotate("rect", xmin = extent[1], xmax = extent[3], ymin = extent[2], ymax = extent[4],
fill = NA, colour = "red", linewidth = 0.7) +
coord_sf(xlim = c(0, 125), ylim = c(10, 58), expand = FALSE) +
theme_void() +
theme(panel.background = element_rect(fill = "white", colour = "grey45", linewidth = 0.4))
}
One function builds every period map. It reads the period’s clipped
polities and splits them into the era’s own state(s) - matched by name,
accents folded so the ASCII configuration finds the diacritic source
names - and the neighbouring context. Context is drawn grey with the few
largest neighbours labelled in faint italics; the highlighted state(s)
are filled translucently by name through a qualitative
Brewer palette (Dark2), which is far clearer than a
sequential ramp when a realm fractures into several coloured pieces (the
palette and the translucency are the one place this notebook overrides
the default viridis look, at the user’s request). Capitals and important
cities are placed from the curated table, with ggrepel
nudging the labels apart, and the locator inset is composed into the
corner with patchwork. A per-period coord_sf
extent zooms each map to its own theatre.
plot_period <- function(period) {
extent <- unlist(period$extent)
polities <- st_read(period$file, quiet = TRUE) |>
filter(!is.na(name), name != "NA")
is_highlight <- ascii_fold(polities$name) %in% ascii_fold(unlist(period$highlight))
highlight <- polities[is_highlight, ]
context <- polities[!is_highlight, ]
context_in_view <- suppressWarnings(st_crop(context,
c(xmin = extent[1], ymin = extent[2], xmax = extent[3], ymax = extent[4])))
context_labels <- context_in_view |>
mutate(area = as.numeric(st_area(st_transform(st_make_valid(geometry), 3857)))) |>
slice_max(area, n = 5, with_ties = FALSE) |>
st_point_on_surface() |> suppressWarnings()
capitals <- cities_role(period$key, "capital_for")
cities <- cities_role(period$key, "city_for")
map <- ggplot() +
geom_sf(data = coastline, fill = "grey97", colour = "grey85", linewidth = 0.2) +
geom_sf(data = context, fill = "grey88", colour = "white", linewidth = 0.2) +
geom_sf(data = highlight, aes(fill = name), colour = "white", linewidth = 0.3,
alpha = 0.68) +
geom_sf_text(data = context_labels, aes(label = name), size = 2.7,
colour = "grey55", fontface = "italic")
if (nrow(cities) > 0) {
map <- map +
geom_point(data = cities, aes(lon, lat), size = 1.5, colour = "grey15") +
geom_text_repel(data = cities, aes(lon, lat, label = name), size = 3,
colour = "grey10", seed = 42, max.overlaps = 30,
box.padding = 0.25, segment.colour = "grey60",
bg.color = "white", bg.r = 0.16)
}
if (nrow(capitals) > 0) {
map <- map +
geom_point(data = capitals, aes(lon, lat), shape = 23, size = 3.2,
fill = capital_colour, colour = "white", stroke = 0.7) +
geom_text_repel(data = capitals, aes(lon, lat, label = name), size = 3.6,
fontface = "bold", colour = "grey5", seed = 42,
box.padding = 0.5, segment.colour = "grey50",
bg.color = "white", bg.r = 0.18)
}
main_map <- map +
scale_fill_brewer(palette = "Dark2", name = "State / polity") +
coord_sf(xlim = c(extent[1], extent[3]), ylim = c(extent[2], extent[4]),
expand = FALSE) +
labs(title = period$title, subtitle = period$era, x = NULL, y = NULL) +
theme(legend.position = "right",
panel.grid = element_line(colour = "grey92", linewidth = 0.2))
main_map +
inset_element(make_minimap(extent), left = 0.0, bottom = 0.72,
right = 0.26, top = 1.0, align_to = "panel")
}
The word “Turk” enters history on the Mongolian steppe. In 552 CE a clan of ironworking horsemen under Bumin Qaghan overthrew their overlords and founded the Gokturk (“Celestial Turk”) Khaganate, the first state to bear the name. At its height it stretched from Manchuria to the Black Sea, its heartland the sacred Otuken valley on the Orkhon river - where, two centuries later, the Turks carved the oldest known Turkic inscriptions in stone. This is the world the later Turks remembered as their origin: nomadic, mounted, and vast.
plot_period(periods_by_key$gokturk)
Over the following centuries Turkic peoples drifted west and converted to Islam. The Seljuks, a clan of the Oghuz Turks, swept out of Central Asia and in a single generation took Persia, Iraq and the Abbasid capital Baghdad, ruling as sultans in the caliph’s name from Isfahan and Nishapur. The hinge moment for everything that follows came in 1071 at Manzikert, in eastern Anatolia, where the Seljuks shattered the Byzantine army and threw the gates of Asia Minor open to Turkic settlement. Anatolia - the land that would become Turkey - begins to turn Turkish here.
plot_period(periods_by_key$seljuk)
The Anatolian branch of the Seljuks built the Sultanate of Rum (“Rome”, for the old Byzantine land), ruling a brilliant court at Konya. But in the thirteenth century the Mongols stormed through: after 1243 the Sultanate became a vassal of the Ilkhanate, and as Mongol power waned Anatolia splintered into a patchwork of small Turkish principalities, the beyliks. The map shows the shrunken Rum sultanate hemmed between the Ilkhanate, the surviving Byzantine Empire in the west, the Mamluke Sultanate to the south and the Greek Trebizond empire on the Black Sea. One of those obscure frontier beyliks, in the northwest, was led by a chieftain named Osman.
plot_period(periods_by_key$rum)
Osman’s beylik - the Ottomans - grew fastest, straddling the Byzantine frontier and pushing into Europe, taking Bursa, then Edirne (Adrianople) as capitals and leaping the straits into the Balkans. Then catastrophe: in 1402 the conqueror Timur crushed the Ottoman sultan at Ankara and broke the realm apart. The map catches this fractured moment - the Ottoman lands split into separate pieces in Europe and Asia, the rival Beylik of Aydin restored on the Aegean coast, a rump Byzantine Empire clinging to Constantinople, and Timur’s empire looming to the east. That the Ottomans survived this at all was the surprise of the age.
plot_period(periods_by_key$ottoman_birth)
The Ottomans reunited, and in 1453 the 21-year-old Mehmed II did what besiegers had failed to do for a thousand years: he took Constantinople, ending the Roman Empire and making the city his capital - Istanbul, capital of the Turks ever since. With the Bosphorus secured, the two halves of the empire, Balkan Rumelia and Anatolia, were welded into one. The map shows the Ottoman state now wrapped around the straits, the last Byzantine remnant gone, the old cities of Greece and the Balkans inside the empire.
plot_period(periods_by_key$constantinople)
In half a century the empire trebled. Selim I turned south and east, crushing the Mamluks to take Syria, Egypt and the holy cities of Mecca and Medina in 1516-17 - the Ottoman sultan was now guardian of Islam’s holiest sites. His son Suleiman the Magnificent drove northwest into Europe, taking Belgrade and most of Hungary, and east to Baghdad. The map fills with great cities under one ruler from Algiers to Basra - the moment the Ottoman Empire became the dominant power of the eastern Mediterranean and the Islamic world.
plot_period(periods_by_key$selim_suleiman)
At the turn of the seventeenth century the empire was at the height of its confidence: master of the Balkans, Anatolia, the Levant, Egypt, the North African coast as far as Algiers, the Red Sea and most of the Mediterranean’s eastern and southern shores, with the Crimean Khanate as a vassal guarding the Black Sea steppe. Istanbul was the largest city in Europe. This is the Ottoman world at its classical peak - a multi-ethnic, multi-faith empire administered from a single court, the cities of three continents answering to the Sublime Porte.
plot_period(periods_by_key$suleiman_peak)
The empire reached its largest territorial extent in the later seventeenth century, pushing up the Danube to besiege Vienna a second time in 1683. There the tide turned: a Polish-Habsburg relief army broke the siege, and the wars that followed cost the Ottomans Hungary for good. The map shows the empire at its fullest reach - and at the hinge of its fortunes. Everything after this is, in territorial terms, a long retreat.
plot_period(periods_by_key$greatest_extent)
Through the eighteenth century a resurgent Russia pressed down from the north, taking the Crimea and the northern Black Sea coast, while Habsburg Austria pushed from the west. By the close of the Napoleonic wars the empire had lost its grip on the far north of the Black Sea and was falling behind the industrialising European powers in wealth and arms. The cities of the core - Istanbul, the Balkans, the Levant, Egypt, the Arabian holy cities - were still Ottoman, but the frontier was contracting and the provinces were growing restless.
plot_period(periods_by_key$retreat)
In the nineteenth century nationalism tore the Balkans away. Greece won independence in the 1830s; the Russo-Turkish War of 1877-78 and the Congress of Berlin that followed stripped away Serbia, Romania, Montenegro and an autonomous Bulgaria. Egypt drifted into British control. The European powers now spoke openly of “the sick man of Europe” and how to divide his estate. The map shows the empire pushed back to Anatolia, a Balkan toehold around its capital, and the Arab provinces - a shadow of the c. 1600 colossus, though still spanning three continents on paper.
plot_period(periods_by_key$sick_man)
By 1914 the Balkan Wars had just stripped away almost all that remained in Europe, leaving only eastern Thrace around Istanbul. What was left was the Anatolian heartland and the Arab provinces - the Levant, Mesopotamia, and the Hejaz with the holy cities. The empire entered the First World War on the side of Germany and Austria-Hungary, a fateful choice: defeat would mean not just the loss of territory but the end of the empire itself.
plot_period(periods_by_key$wwi_eve)
Defeat brought dismemberment. Under the 1920 Treaty of Sevres the victors carved the empire into pieces: Mesopotamia and Palestine to Britain, Syria to France, a large independent Armenia in the east, a zone around Smyrna to Greece and another in the southwest to Italy, with the Sultan left only a rump around Istanbul under Allied occupation. This is the most fragmented map in the whole story - every colour a different claimant on once-Ottoman land. But in the Anatolian interior a nationalist movement under Mustafa Kemal, governing from Ankara, refused the treaty and began a war to overturn it.
plot_period(periods_by_key$partition)
The nationalists won. They drove the Greek army out of Anatolia, abolished the sultanate, and in 1923 negotiated the Treaty of Lausanne, which recognised the borders of a new sovereign nation-state. On 29 October 1923 Mustafa Kemal - soon Ataturk, “father of the Turks” - proclaimed the Republic of Turkey, with its capital not at imperial Istanbul but at Ankara in the Anatolian heartland. Fourteen centuries after the Gokturks, the Turkish state had become a compact republic centred on the land the Seljuks had first opened in 1071.
plot_period(periods_by_key$republic)
The maps above each freeze one moment. This last plate overlays them all on a single shared frame, so the whole expansion and retreat reads at a glance. Every era’s territory is drawn as one outline, coloured by its year - deep blue for the Sultanate of Rum around 1300, through green and yellow at the sixteenth-to-seventeenth-century peak, to red for the rump of 1920 and the compact republic of 1923. The capitals are marked in the same time colours, tracing how the seat of power migrated from Konya to Edirne to Istanbul and finally to Ankara. Read the colours from cool to warm and you watch the state swell from an Anatolian core to a three-continent empire and contract back to a nation-state on much the same land it started from.
territories <- st_read("cube_territories.geojson", quiet = TRUE) |>
mutate(area = as.numeric(st_area(st_transform(st_make_valid(geometry), 3857)))) |>
arrange(desc(area))
year_range <- range(territories$year)
capital_track <- map_dfr(territories$key, function(period_key) {
capital <- cities_role(period_key, "capital_for")
if (nrow(capital) == 0) return(NULL)
capital |> slice(1) |> mutate(year = territories$year[territories$key == period_key])
}) |>
group_by(name) |>
slice_min(year, with_ties = FALSE) |>
ungroup()
ggplot() +
geom_sf(data = coastline, fill = "grey97", colour = "grey88", linewidth = 0.2) +
geom_sf(data = territories, aes(colour = year), fill = NA, linewidth = 0.8) +
geom_point(data = capital_track, aes(lon, lat, fill = year), shape = 21,
size = 3, colour = "white", stroke = 0.6) +
geom_text_repel(data = capital_track, aes(lon, lat, label = name), size = 3.4,
fontface = "bold", colour = "grey10", seed = 42,
box.padding = 0.7, segment.colour = "grey60",
bg.color = "white", bg.r = 0.18) +
scale_colour_viridis_c(option = "turbo", name = "Year", limits = year_range) +
scale_fill_viridis_c(option = "turbo", guide = "none", limits = year_range) +
coord_sf(xlim = c(2, 50), ylim = c(18, 49), expand = FALSE) +
labs(title = "The rise and fall of the Turkish state, 1300-1938",
subtitle = "every era's territory as one outline, coloured by year; capitals tracked in the same colours",
x = NULL, y = NULL) +
theme(panel.grid = element_line(colour = "grey92", linewidth = 0.2))
summary_table <- map_dfr(config$periods, function(period) {
capitals <- cities_role(period$key, "capital_for")
tibble::tibble(
Period = period$title,
Date = period$era,
`State(s) drawn` = paste(unlist(period$highlight), collapse = ", "),
Capital = if (nrow(capitals) > 0) paste(capitals$name, collapse = ", ") else "-")
})
knitr::kable(summary_table, caption = "The thirteen periods at a glance")
| Period | Date | State(s) drawn | Capital |
|---|---|---|---|
| Gokturk Khaganate | 552-744 CE - the first Turkic state | Gokturks | Otuken |
| Great Seljuk Empire | 1037-1194 CE - Turks take the Middle East | Seljuk Empire | Nishapur, Isfahan |
| Sultanate of Rum, under the Mongol shadow | c. 1300 CE | Seljuk Caliphate | Konya |
| An Ottoman beylik among many | c. 1400 CE - after Timur shattered Anatolia | Ottoman Empire | Edirne |
| The conquest of Constantinople | 1453 CE (map drawn c. 1500) | Ottoman Empire | Istanbul |
| Selim I and Suleiman - the great expansion | 1512-1566 CE (map c. 1530) | Ottoman Empire | Istanbul |
| A Mediterranean superpower | c. 1600 CE | Ottoman Empire | Istanbul |
| Greatest extent, then Vienna | 1683 CE (map drawn c. 1700) | Ottoman Empire | Istanbul |
| The long retreat | c. 1815 CE | Ottoman Empire | Istanbul |
| The sick man of Europe | c. 1880 CE - after the Balkans broke away | Ottoman Empire | Istanbul |
| On the eve of the First World War | 1914 CE | Ottoman Empire | Istanbul |
| Partition - the empire carved up | 1920 CE - Treaty of Sevres | Ottoman Sultanate, Syria (France), Mesopotamia (GB), Mandatory Palestine (GB), Armenia, Greece, Italy | Ankara |
| The Republic of Turkey | 1923 CE - founded by Ataturk (map c. 1938) | Turkey | Ankara |
aourednik/historical-basemaps
(CC-BY-SA), snapshot years chosen inside each period; reconstructed
borders are interpretations, and the source’s own polity labels are used
(it calls the Sultanate of Rum the “Seljuk Caliphate”).cities.json from
well-known coordinates, tagged with the periods in which each was a
capital or a leading city.prep.R;
this notebook holds only loading and plotting logic. Retrieved June
2026.