On Dave Mustaine’s birthday, this document presents a small tribute through network analysis. The idea is to study his position within a broad network of rock, metal, and related guitarists, constructed from musical collaborations and cover relationships.
The goal is not to determine who is the “best” guitarist. Centrality describes the structural position of each musician within the observed network and allows us to examine, from another perspective, how connected each guitarist is, how strongly they act as bridges, and how close they are to the rest of the network.
The network was constructed from publicly available sources documenting relationships among rock and metal guitarists. The initial roster was assembled primarily from the Wikipedia List of heavy metal guitarists, while recorded collaborations were verified mainly through MusicBrainz, Discogs, and AllMusic. Cover relationships were cross-checked primarily using SecondHandSongs. Additional release-specific sources were used when necessary, including official or specialized pages for projects such as G3, Generation Axe, Hear ’n Aid, Rock Aid Armenia, and selected individual recordings. An undirected edge was created whenever reliable evidence indicated that two guitarists had recorded together or that one had performed or recorded a cover associated with the other. Multiple pieces of evidence for the same pair were aggregated into a single binary connection. Consequently, the network should be regarded as an evidence-based, non-exhaustive representation of documented musical relationships.
Main sources: MusicBrainz, SecondHandSongs, Discogs, AllMusic, and the Wikipedia List of heavy metal guitarists.
suppressMessages(suppressWarnings(library(readxl)))
suppressMessages(suppressWarnings(library(dplyr)))
suppressMessages(suppressWarnings(library(igraph)))
suppressMessages(suppressWarnings(library(ggplot2)))
suppressMessages(suppressWarnings(library(ggraph)))
suppressMessages(suppressWarnings(library(graphlayouts)))
suppressMessages(suppressWarnings(library(ggrepel)))
suppressMessages(suppressWarnings(library(knitr)))
The database contains guitarists as vertices. Two guitarists are connected when there is at least one captured piece of evidence that they recorded together or that one performed a cover associated with the other. The network is binary, undirected, and symmetric.
Historical membership in the same band is not sufficient by itself to create an edge. In addition, the absence of an edge means that no evidence was captured for that pair, not necessarily that no musical relationship ever existed.
file_xlsx <- "rock_metal_guitarists_network_expanded.xlsx"
vertices <- read_excel(
file_xlsx,
sheet = "Vertices"
)
edges <- read_excel(
file_xlsx,
sheet = "Edges_Aggregated"
)
evidence <- read_excel(
file_xlsx,
sheet = "Relations_Evidence"
)
vertices_g <- vertices |>
select(guitarist, everything()) |>
rename(name = guitarist)
edges_g <- edges |>
select(u, v, everything())
The analyzed version contains 724 guitarists, 685 aggregated relationships, and 869 evidence records.
g <- graph_from_data_frame(
d = edges_g,
directed = FALSE,
vertices = vertices_g
)
network_summary <- tibble(
measure = c(
"Guitarists",
"Connections",
"Collaborations",
"Covers"
),
value = c(
vcount(g),
ecount(g),
sum(E(g)$relation == "collaboration"),
sum(E(g)$relation == "cover")
)
)
knitr::kable(
network_summary,
col.names = c("Measure", "Value"),
align = c("l", "r")
)
| Measure | Value |
|---|---|
| Guitarists | 724 |
| Connections | 685 |
| Collaborations | 438 |
| Covers | 247 |
The full network includes isolated musicians and small disconnected groups. To compare centrality measures based on distances and paths, we work with the giant component.
comp <- components(g)
giant_id <- which.max(
comp$csize
)
g_gc <- induced_subgraph(
g,
vids = V(g)[comp$membership == giant_id]
)
giant_summary <- tibble(
measure = c(
"Guitarists",
"Connections"
),
value = c(
vcount(g_gc),
ecount(g_gc)
)
)
knitr::kable(
giant_summary,
col.names = c("Giant component", "Value"),
align = c("l", "r")
)
| Giant component | Value |
|---|---|
| Guitarists | 227 |
| Connections | 493 |
The giant component contains 227 guitarists connected through 493 relationships. This is the subset used to construct the global ranking.
We consider five complementary centrality measures:
degree_raw <- degree(
g_gc,
mode = "all"
)
degree_norm <- degree_raw / (vcount(g_gc) - 1)
betweenness_cent <- betweenness(
g_gc,
directed = FALSE,
normalized = TRUE
)
closeness_cent <- closeness(
g_gc,
mode = "all",
normalized = TRUE
)
eigenvector_cent <- eigen_centrality(
g_gc,
directed = FALSE,
scale = TRUE
)$vector
pagerank_cent <- page_rank(
g_gc,
directed = FALSE,
damping = 0.85
)$vector
centrality <- tibble(
guitarist = V(g_gc)$name,
degree = degree_raw,
degree_centrality = degree_norm,
betweenness = betweenness_cent,
closeness = closeness_cent,
eigenvector = eigenvector_cent,
pagerank = pagerank_cent
)
Each measure captures a different way of occupying a relevant position in the network. For this reason, the final ranking is not based on a single centrality measure.
The original measures are on different scales, and some are partially redundant. To construct a more balanced index, we first transform each centrality measure into its percentile within the giant component.
We define three dimensions:
\[ L_i = \frac{ P_{i,D} + P_{i,E} + P_{i,P} }{3}, \]
where \(L_i\) summarizes connectivity and structural importance, combining degree, eigenvector centrality, and PageRank;
\[ B_i = P_{i,B}, \]
where \(B_i\) represents brokerage; and
\[ C_i = P_{i,C}, \]
where \(C_i\) represents accessibility.
The global index is
\[ I_i = 100 \left( \frac{ L_i + B_i + C_i }{3} \right). \]
Thus, the three dimensions receive equal weight and the index is expressed on a 0 to 100 scale.
centrality <- centrality |>
mutate(
pct_degree = percent_rank(degree_centrality),
pct_betweenness = percent_rank(betweenness),
pct_closeness = percent_rank(closeness),
pct_eigenvector = percent_rank(eigenvector),
pct_pagerank = percent_rank(pagerank),
connectivity = (
pct_degree +
pct_eigenvector +
pct_pagerank
) / 3,
brokerage = pct_betweenness,
accessibility = pct_closeness,
global_index = 100 * (
connectivity +
brokerage +
accessibility
) / 3
) |>
arrange(
desc(global_index),
guitarist
) |>
mutate(
global_rank = row_number()
)
This index favors guitarists who simultaneously combine relevant connections, the ability to link different parts of the network, and a globally accessible position.
top10_global <- centrality |>
slice_head(n = 10) |>
transmute(
Rank = global_rank,
Guitarist = guitarist,
`Global index` = global_index,
Connectivity = 100 * connectivity,
Brokerage = 100 * brokerage,
Accessibility = 100 * accessibility
)
knitr::kable(
top10_global,
digits = 1,
align = c("r", "l", "r", "r", "r", "r")
)
| Rank | Guitarist | Global index | Connectivity | Brokerage | Accessibility |
|---|---|---|---|---|---|
| 1 | Dave Murray | 99.8 | 99.4 | 100.0 | 100.0 |
| 2 | James Hetfield | 98.7 | 97.9 | 98.7 | 99.6 |
| 3 | Kirk Hammett | 97.5 | 97.5 | 96.0 | 99.1 |
| 4 | Vivian Campbell | 97.1 | 98.5 | 95.1 | 97.8 |
| 5 | Adrian Smith | 97.1 | 98.4 | 94.2 | 98.7 |
| 6 | Scott Gorham | 97.0 | 94.0 | 99.1 | 97.8 |
| 7 | Dave Mustaine | 96.5 | 93.4 | 99.6 | 96.5 |
| 8 | Yngwie Malmsteen | 95.1 | 96.3 | 92.9 | 96.0 |
| 9 | Mick Mars | 95.0 | 96.5 | 91.6 | 96.9 |
| 10 | Scott Ian | 94.4 | 92.2 | 97.8 | 93.4 |
The highest positions do not necessarily correspond to the guitarists with the largest number of direct connections. The ranking also rewards the ability to connect different regions of the network and to maintain a position that is close to the rest of the guitarists.
dave <- centrality |>
filter(
guitarist == "Dave Mustaine"
)
dave_summary <- dave |>
transmute(
Rank = global_rank,
Guitarist = guitarist,
`Global index` = global_index,
Connectivity = 100 * connectivity,
Brokerage = 100 * brokerage,
Accessibility = 100 * accessibility,
Degree = degree
)
knitr::kable(
dave_summary,
digits = 1,
align = c("r", "l", "r", "r", "r", "r", "r")
)
| Rank | Guitarist | Global index | Connectivity | Brokerage | Accessibility | Degree |
|---|---|---|---|---|---|---|
| 7 | Dave Mustaine | 96.5 | 93.4 | 99.6 | 96.5 | 20 |
Dave Mustaine ranks 7 out of 227 in the global ranking, with a global centrality index of 96.5 out of 100.
His position does not depend only on the number of connections. He also stands out through his role as a bridge and through his location within the global structure of the network.
top15_plot <- centrality |>
slice_head(n = 15) |>
mutate(
guitarist = factor(
guitarist,
levels = rev(guitarist)
),
group = case_when(
guitarist == "Dave Mustaine" ~ "Dave Mustaine",
global_rank <= 10 ~ "Top 10",
TRUE ~ "Others"
)
)
p_rank <- ggplot(
top15_plot,
aes(
x = global_index,
y = guitarist,
fill = group
)
) +
geom_col(
width = 0.72
) +
geom_text(
aes(
label = sprintf("%.1f", global_index)
),
hjust = -0.15,
size = 3.6
) +
scale_fill_manual(
values = c(
"Dave Mustaine" = "#B2182B",
"Top 10" = "#E3B341",
"Others" = "#C9CED6"
)
) +
scale_x_continuous(
limits = c(
0,
max(top15_plot$global_index) * 1.08
),
expand = expansion(
mult = c(0, 0)
)
) +
labs(
title = "Most central guitarists in the network",
subtitle = "Global centrality index",
x = "Global index",
y = NULL,
fill = NULL
) +
theme_minimal(
base_size = 12
) +
theme(
plot.title = element_text(
size = 18,
face = "bold"
),
plot.subtitle = element_text(
size = 12,
colour = "#4B5563"
),
panel.grid.major.y = element_blank(),
panel.grid.minor = element_blank(),
legend.position = "bottom"
)
p_rank
Mustaine’s position among the most central guitarists shows that his role in the network combines connectivity, brokerage, and accessibility, rather than depending on a single measure.
idx <- match(
V(g_gc)$name,
centrality$guitarist
)
V(g_gc)$degree_cent <- centrality$degree_centrality[idx]
V(g_gc)$betweenness_cent <- centrality$betweenness[idx]
V(g_gc)$closeness_cent <- centrality$closeness[idx]
V(g_gc)$eigenvector_cent <- centrality$eigenvector[idx]
V(g_gc)$pagerank_cent <- centrality$pagerank[idx]
V(g_gc)$connectivity <- centrality$connectivity[idx]
V(g_gc)$brokerage <- centrality$brokerage[idx]
V(g_gc)$accessibility <- centrality$accessibility[idx]
V(g_gc)$global_index <- centrality$global_index[idx]
V(g_gc)$global_rank <- centrality$global_rank[idx]
In the visualization, node size represents the global index. Guitarists in the top 10 are shown in gold, while Dave Mustaine is highlighted in red.
set.seed(1702)
p_network <- ggraph(
g_gc,
layout = "stress"
) +
geom_edge_link(
aes(
colour = relation
),
alpha = 0.18,
linewidth = 0.45,
show.legend = TRUE
) +
geom_node_point(
aes(
size = global_index
),
shape = 21,
fill = "#C9CED6",
colour = "white",
stroke = 0.25,
alpha = 0.90
) +
geom_node_point(
data = function(x) {
x |>
filter(
global_rank <= 10,
name != "Dave Mustaine"
)
},
aes(
size = global_index
),
shape = 21,
fill = "#E3B341",
colour = "#715500",
stroke = 1.1
) +
geom_node_point(
data = function(x) {
x |>
filter(
name == "Dave Mustaine"
)
},
aes(
size = global_index
),
shape = 21,
fill = "#B2182B",
colour = "#570812",
stroke = 1.6
) +
geom_node_text(
data = function(x) {
x |>
filter(
global_rank <= 10,
name != "Dave Mustaine"
)
},
aes(
label = name
),
repel = TRUE,
size = 3.6,
fontface = "bold",
colour = "#20242A",
box.padding = 0.5,
point.padding = 0.4,
max.overlaps = Inf
) +
geom_node_label(
data = function(x) {
x |>
filter(
name == "Dave Mustaine"
)
},
aes(
label = name
),
repel = TRUE,
size = 4.3,
fontface = "bold",
fill = "#B2182B",
colour = "white",
label.size = 0,
label.padding = unit(
0.35,
"lines"
),
box.padding = 0.8,
point.padding = 0.7
) +
scale_edge_colour_manual(
values = c(
collaboration = "#697B8C",
cover = "#C28A44"
),
labels = c(
collaboration = "Collaboration",
cover = "Cover"
),
name = "Relationship"
) +
scale_size_continuous(
range = c(
2.0,
9.0
),
limits = c(
0,
100
),
guide = "none"
) +
labs(
title = "Network of rock and metal guitarists",
subtitle = paste0(
"Giant component: ",
vcount(g_gc),
" guitarists and ",
ecount(g_gc),
" connections\n",
"Gold: top 10 by global index | Red: Dave Mustaine"
),
caption = paste0(
"Global index = average of connectivity, ",
"brokerage, and accessibility."
)
) +
guides(
edge_colour = guide_legend(
override.aes = list(
alpha = 0.8,
linewidth = 1.5
)
)
) +
theme_graph(
base_family = "sans"
) +
theme(
plot.title = element_text(
size = 22,
face = "bold",
colour = "#15191E"
),
plot.subtitle = element_text(
size = 12,
colour = "#4B5563",
lineheight = 1.15
),
plot.caption = element_text(
size = 9,
colour = "#6B7280"
),
legend.position = "bottom",
legend.title = element_text(
face = "bold"
),
plot.margin = margin(
20,
25,
20,
25
)
)
p_network
The network shows something that a simple list of collaborations cannot reveal directly: some guitarists occupy positions that connect different scenes, generations, and musical communities. Dave Mustaine’s high global centrality is consistent with a career positioned across several relevant regions of this structure.
This analysis offers a quantitative way to celebrate Dave Mustaine’s career: not simply by counting albums, bands, or songs, but by examining his position within a broader network of musical relationships.
The global index should be interpreted as a measure of structural centrality in this database, not as a definitive measure of artistic quality or historical influence. Even with that precaution, his position provides a clear visualization of the reach of his connections within the rock and metal universe.
Happy birthday, Dave Mustaine.