Now that the underlying data and network structures are in place,
this section focuses on their visualization. We will generate the key
plots presented in the paper, illustrating both the static, global
structure of technology and the dynamic, evolving space of AI.
1.3.1. Global technological space (GTS)
We begin by plotting the fundamental structure of the Global
Technological Space. This initial visualization is
geography-agnostic, meaning it shows the inherent
relatedness between technological fields without any country-specific
data. The node size corresponds to its centrality (degree), and nodes
are clustered and colored by their broader technological sector. This
plot serves as the canvas upon which we will later map national
trajectories.
g_tech_AI %>% ggraph(layout = coords_tech_AI) +
geom_edge_link(aes(width = weight), alpha = 0.4, colour = "grey") +
geom_node_point(aes(fill = sector, size = 1000^dgr, shape= sector))+ #
scale_shape_manual(values=c(21, 22, 23, 24, 25)) + scale_size("Degree", range = c(2, 12)) +
geom_node_text(aes(label = paste0(field_name, "\n(", name, ")")), size = 4, repel = TRUE) + #field_name or name
theme_graph(base_family = "sans")+ ggtitle("Global technological space: IPC Technological fields") +
theme(legend.title = element_text(size = 14), legend.text = element_text(size = 10)) +
guides(colour = guide_legend(override.aes = list(size=10)))+
geom_mark_hull(aes(x = x, y=y, colour = sector, fill= sector,
linetype = sector), alpha = 0.15, expand = unit(2.5, "mm"), size = 1)

Next, we overlay the country-specific specialization data onto the
static GTS canvas. This allows us to visualize the technological
trajectory of each country over the three time intervals. The shape of
each node indicates the type of specialization (general, break-through,
or break-in), while hulls are drawn to highlight the clusters of
specialization for each period. This composite visualization reveals how
each nation’s technological focus has evolved within the global
structure. Additionally, an horizontal bar plot is also generated to
summarize the main indicators based on the country-specific
specializations. Picking China as an example, this overlaid
visualization and its linked bar-plot look like this:
#GTS with specialisations per country
country_select <- c("CN", "US", "JP", "KR")
### 1.2.3.3. Third Country
i=1
IPC_RCAs_wide_simplified <- IPC_RCAs_Top4 %>% pivot_wider(id_cols = c(ctry_code, techn_field_nr, Label),
names_from = Period_sim,
values_from = c(RCA_AI_Period, Total_RCA_2, RCA_Gen, RCA_AI, Round_general, Round_AI, Total_RCA),
names_glue = "{.value}_Period_{Period_sim}" )
g_tech_AI %N>% left_join(IPC_RCAs_wide_simplified %>%
filter(ctry_code == country_select[i]) %>%
select(-ctry_code), by = c("name" = "techn_field_nr")) %>%
mutate(Shape_Group_P1_Factor = factor(
ifelse(is.na(Total_RCA_2_Period_1), "NA_Value", as.character(Total_RCA_2_Period_1)),
levels = c("0", "1", "2", "3", "NA_Value"))) %>% ggraph(layout = coords_tech_AI) +
geom_edge_link(aes(width = weight), alpha = 0.2, colour = "#CCCCCC", show.legend = FALSE) +
geom_node_point(aes(shape = Shape_Group_P1_Factor,
size = 5, stroke = ifelse(Total_RCA_2_Period_1 == 3, 2.5, 1.3),
alpha = 1), color = "#FF3300", show.legend = c(shape=TRUE, size=FALSE, stroke=FALSE, alpha=FALSE, color=FALSE)) +
geom_node_point(aes(shape = factor(Total_RCA_2_Period_2),
size = 5.5, stroke = ifelse(Total_RCA_2_Period_2 == 3, 2.5, 1.3),
alpha = 1), color = "#3399FF", show.legend = FALSE) +
geom_node_point(aes(shape = factor(Total_RCA_2_Period_3),
size = 6.5,stroke = ifelse(Total_RCA_2_Period_3 == 3, 2.5, 1.3),
alpha = 1), color = "#009900", show.legend = FALSE) +
scale_shape_manual(name = "Type of specialisation",
values = c("0" = 4, "1" = 1, "2" = 5, "3" = 2, "NA_Value" = 16), breaks = c("0", "1", "2", "3"),
labels = c("0" = "No specialisation", "1" = "General specialisation",
"2" = "Break-through specialisation", "3" = "Break-in specialisation"),
na.translate = FALSE, drop = FALSE) + scale_size("Degree", range = c(7, 18))+
scale_alpha(guide = "none") +
#geom_node_label(aes(label = name), size = 2, repel = F) +
geom_mark_hull(aes(filter = Total_RCA_2_Period_1 > .99, x = x, y = y, fill = "Period 1", group = "Period 1"),
concavity = .1, alpha = .11, linetype = "dotted",expand = unit(2, "mm"), size = .5, color = "#FF3300") +
geom_mark_hull(aes(filter = Total_RCA_2_Period_2 > .99, x = x, y = y, fill = "Period 2", group = "Period 2"),
concavity = .1, alpha = .11, linetype = "longdash",expand = unit(2, "mm"), size = .5, color = "#3399FF") +
geom_mark_hull(aes(filter = Total_RCA_2_Period_3 > .99, x = x, y = y, fill = "Period 3", group = "Period 3"),
concavity = .1, alpha = .02, expand = unit(2, "mm"), size = 1, color = "#009900") +
scale_fill_manual(name = "Interval colour (same for \nboth nodes and cluster)", # New legend for fill
values = c("Period 1" = "#FF3300", "Period 2" = "#3399FF", "Period 3" = "#009900"),
labels = c("Interval 1 (1974-1988)", "Interval 2 (1989-2003)", "Interval 3 (2004-2018)")) +
theme_graph(base_family = "sans") + theme(legend.position = "bottom", #right
legend.box = "vertical", legend.title = element_text(size = 12, face = "bold"),
legend.text = element_text(size = 10), legend.key.size = unit(0.7, "cm") ) +
ggtitle("d) Global technological space: China (1974-2018)") +
geom_node_text(aes(label = name), size = 5, repel = TRUE) + #field_name or name
guides(shape = guide_legend(title.position = "top",
override.aes = list(size = 5, stroke = 1.5, color = "black") ),
colour = guide_legend(title.position = "top",
override.aes = list(linetype = c("solid", "longdash", "dotted"),
alpha = 1, size = 1, shape = NA) ))

bar_plot_China <- bar_plot_China <- IPC_RCAs_Top4[IPC_RCAs_Top4$ctry_code == country_select[i],] %>%
arrange(Label, Period) %>% group_by(Label) %>%
mutate( general = Total_RCA_2 == 1,
break_in = Total_RCA_2 == 2,
break_through = Total_RCA_2 == 3,
sustained_general = general & lag(general, 1, default = FALSE),
sustained_break_in = break_in & lag(break_in, 1, default = FALSE),
sustained_break_through = break_through & lag(break_through, 1, default = FALSE)) %>%
ungroup()
bar_plot_China <- bar_plot_China %>%
group_by(Period) %>% summarise(`General case` = sum(general, na.rm = TRUE),
`Break-through case` = sum(break_in, na.rm = TRUE),
`Break-in case` = sum(break_through, na.rm = TRUE),
`Sustained General case` = sum(sustained_general, na.rm = TRUE),
`Sustained break-through case` = sum(sustained_break_in, na.rm = TRUE),
`Sustained break-in case` = sum(sustained_break_through, na.rm = TRUE),
.groups = "drop") %>% arrange(Period)
plot_long_China <- bar_plot_China |> rename(Period = Period) |>
pivot_longer(cols= -Period,names_to= "Indicator",values_to = "Count")
#order labels
plot_long_China$Indicator <- factor(plot_long_China$Indicator, levels = rev(c("General case", "Break-through case", "Break-in case",
"Sustained General case", "Sustained break-through case", "Sustained break-in case")))
plot_long_China$Period <- factor(plot_long_China$Period, levels = c("2004-2018", "1989-2003", "1974-1988"))
legend_order <- c(
"General case", "Break-through case", "Break-in case",
"Sustained General case", "Sustained break-through case", "Sustained break-in case"
)
ggplot(plot_long_China, aes(x = factor(Period),y = Count, fill = Indicator)) +
geom_col(position = position_dodge(width = .8), width = .7) +
scale_fill_manual(values = c("General case" = "#FF3300",
"Sustained General case" = "#993333",
"Break-in case" = "#009900", #3399FF
"Sustained break-in case" = "#006633", #3333CC
"Break-through case" = "#3399FF", #009900
"Sustained break-through case" = "#3333CC"),
breaks = legend_order) + #006633
guides(fill = guide_legend(nrow = 2, byrow = TRUE)) +
labs(x = "Interval",y = "Number of cases", fill = NULL, title = NULL)+
ggtitle("Summary of specialisations China") +
theme_classic(base_size = 11) + theme(legend.position = "bottom")+ coord_flip()

The plotting code is structured to iterate through each of the four
focus countries by changing the i variable. The resulting
figures, each depicting a single country’s trajectory over three periods
alongside a summary bar chart, are then saved.
1.3.2. AI-specific technological space (ATS)
Unlike the static GTS, the AI-specific Technological Space
(ATS) is dynamic. Its structure is recalculated for each time
interval, reflecting the rapid evolution of AI technology. Here, the
relatedness between fields is based only on their co-occurrence within
AI patents for that specific period. This approach allows us to observe
which technological fields form the core of AI innovation at different
points in time.
Starting with the first interval (1974-1988), the top 10 most central
technological fields in the AI space are:
g_tech_AI %N>% arrange(desc(dgr)) %>% as_tibble() %>% slice(1:10)
We use the previously calculated AI specialization data
(AI_RCA) to highlight the core technologies in each period.
A binary flag indicates whether AI has an RTA ≥ 1 in a given field (and
Period_sim refers to each interval, going from 1 to 3), like this:
kable(as.data.frame(AI_RCA[1:6,]))
| 1 |
0.0593493 |
1 |
0 |
| 2 |
0.0853538 |
1 |
0 |
| 3 |
0.3360644 |
1 |
0 |
| 4 |
1.0978493 |
1 |
1 |
| 5 |
1.6452825 |
1 |
1 |
| 6 |
16.6484958 |
1 |
1 |
The following code generates the ATS for the first interval
(1974-1988). The nodes with labels are those where AI is specialized
(RTA ≥ 1).
AI_RCA1 <- AI_RCA[AI_RCA$Period_sim == 1,]
p=1
g_tech_AI %N>%
left_join(AI_RCA1 %>% filter(Period_sim == p), by = c("name" = "techn_field_nr")) %>%
ggraph(layout = coords_tech_AI) +
geom_edge_link(aes(width = weight), alpha = 0.2, colour = "#CCCCCC") +
geom_node_point(aes(fill = sector, size = 1000^dgr, shape= sector)) +
scale_shape_manual(values=c(21, 22, 23, 24, 25)) + labs(color = "RCA")+ scale_size("Degree", range = c(2, 12)) +
geom_node_text(aes(filter=Binary > .99, label = field_name), size = 6, repel = TRUE) +
theme_graph(base_family = "sans") + guides(colour = guide_legend(override.aes = list(size=5)))+
ggtitle("AI-specific technological space (1974-1988)") #

We do the same for the 2 other intervals, and combine the three
figures again using the multiplot custom function. The resulting figure
is saved at
Files_created_with_the_code/figures/Figure_2_ATS_and_AI_core_technologies_3_intervals.jpg.