💡 Atualmente, estou desenvolvendo um projeto voltado para o mapeamento de congestionamentos urbanos, analisando seus padrões de origem e propagação. Para isso, levo em consideração tanto os elementos da rede viária quanto aspectos do ambiente construído, buscando compreender os fatores que influenciam a formação e dispersão do tráfego intenso.
🔍 Com isso pretendo elaborar uma análise multidimensional através da união de estrutura (grafos), complexidade (fractais) e contexto (ambiente construído) para modelagem da estrutura urbana de mobilidade.
Com esses três aspectos posso implementar camadas de contexto urbano e integrar dados do ambiente construído, como:
✨ Como muitos congestionamentos têm origem nas interseções, pretendo avaliá-los por meio de métricas da teoria dos grafos, identificando padrões estruturais que podem impactar diretamente a fluidez do trânsito e a mobilidade urbana
🔹 Por que usar grafos para entender congestionamentos?
📌 Interseções como vértices: As interseções rodoviárias funcionam como
nós da rede, sendo pontos cruciais na propagação do
congestionamento.
📌 Ruas como arestas: As conexões entre interseções formam as arestas,
determinando como o fluxo de tráfego se desloca.
📌 Centralidade de intermediação (betweenness): Identifica nós
estratégicos que atuam como gargalos—pontos onde o congestionamento
tende a se formar.
📌 Centralidade de proximidade (closeness): Mostra quais interseções
estão mais acessíveis, podendo afetar a dispersão do tráfego.
📌 Centralidade de grau (degree): Avalia o número de conexões de uma
interseção, indicando se ela tem muitas entradas e saídas e como isso
pode impactar a fluidez.
📌 Propagação do congestionamento: Usando propriedades do grafo, é
possível analisar como os padrões de trânsito evoluem e prever zonas
críticas antes que se tornem problemáticas.
🔹 Vantagens da abordagem com grafos
✅ Permite uma visualização estruturada da rede viária e dos padrões de
tráfego.
✅ Quantifica impactos de cruzamentos críticos no fluxo geral.
✅ Ajuda no planejamento urbano, permitindo ajustes estratégicos para
reduzir congestionamentos.
✅ Pode ser combinado com dados de ambiente construído, como largura das
ruas e presença de semáforos, para análises mais precisas.
🔹 Por que usar fractais para entender congestionamentos urbanos?
📌 Auto-semelhança urbana:
Cidades crescem de forma desigual, mas com padrões que se repetem em
várias escalas — bairros, ruas e cruzamentos muitas vezes refletem
estruturas maiores. Fractais ajudam a captar essa auto-organização
espacial.
📌 Complexidade da malha viária:
Redes de tráfego apresentam ramificações, aglomerações e zonas
periféricas que não são bem descritas por geometria tradicional. Já a
geometria fractal abraça essa complexidade.
📌 Medição da rugosidade e dispersão:
A dimensão fractal permite quantificar a irregularidade e fragmentação
da malha viária, o que afeta diretamente como o tráfego se espalha e
onde ele tende a se acumular.
📌 Previsibilidade da propagação:
Sistemas com estrutura fractal costumam ter zonas críticas recorrentes.
Ao entender a estrutura fractal, é possível prever como um
congestionamento pode se espalhar de forma não-linear.
📌 Escalas múltiplas de análise:
Fractais funcionam bem desde o nível macro (zonas inteiras de uma
cidade) até o micro (interseções locais), permitindo integrar diferentes
camadas de análise — inclusive o ambiente construído.
✅ Vantagens da abordagem fractal
- Mensuração objetiva da complexidade urbana
- Integração com modelos dinâmicos de propagação (como SIR, percolação
ou CA)
- Complementaridade com as métricas de centralidade do grafo
- Aplicável a dados espaciais vetoriais ou raster
- Base para simulações de cenários urbanos com alta fidelidad
Criar um grafo que incorpore dados da rede viária permitindo que análises de grafos e fractais possam ser realizadas sobre a rede viária em nós de interesse.
Na figura abaixo podemos ver que o objeto no mapa e o grafo compartilham um mesmo valor de atributo que se chama osm_id, esse atributo é a ID do link fornecida pelo Open Street Maps (OSM).
Resultado esperado: Grafo com arestas de mesmo ID das Ruas do arquivo shape
library(sf)
library(igraph)
library(visNetwork)
library(dplyr)
library(mapview)
ruas <- st_read("C:/Users/fagne/OneDrive/SIG/sul-latest-free.shp/OSM_POA/OSM_PoA/OSM_PoA.shp")
## Reading layer `OSM_PoA' from data source
## `C:\Users\fagne\OneDrive\SIG\sul-latest-free.shp\OSM_POA\OSM_PoA\OSM_PoA.shp'
## using driver `ESRI Shapefile'
## Simple feature collection with 42439 features and 10 fields
## Geometry type: MULTILINESTRING
## Dimension: XY
## Bounding box: xmin: -51.29933 ymin: -30.26926 xmax: -51.01163 ymax: -29.94017
## Geodetic CRS: WGS 84
ruas <- ruas[ruas$highway %in% c("primary", "primary_link", "secondary", "secondary_link"), ]
ruas <- st_transform(ruas, 4326)
Aqui criamos um bounding box para definir uma área específica para análise dentro da rede de arteriais que carregamos.
bbox <- st_bbox(c(xmin = -51.13754, ymin = -30.03429, xmax = -51.12969, ymax = -30.02931),
crs = st_crs(4326))
# plinio
bbox <- st_bbox(c(xmin = -51.186075, ymin = -30.022909, xmax = -51.183189, ymax = -30.020670), crs = st_crs(4326))# WGS 84
# Converter para um objeto sf (polígono)
bbox_sf <- st_as_sfc(bbox)
# Visualizar com mapview
mapview(bbox_sf, col.regions = "red", alpha = 0.3)
Aqui já é possível visualizar a rede compreendida no bounding box.
ruas <- st_crop(ruas, bbox)
## Warning: attribute variables are assumed to be spatially constant throughout
## all geometries
mapview(ruas)
ruas_segmentadas <- ruas %>%
st_cast("LINESTRING") %>%
group_by(osm_id) %>%
summarise(geometry = st_union(geometry), .groups = "drop") %>%
mutate(osm_id = as.character(osm_id), edge_id = row_number()) # Criar um ID único para cada segmento
coords <- st_coordinates(ruas_segmentadas)
nodes <- data.frame(
X = coords[, "X"],
Y = coords[, "Y"]
) %>%
distinct() %>%
mutate(id = row_number()) # Atribuir um ID único para cada nó
coords <- st_coordinates(ruas_segmentadas) # Extrair coordenadas corretamente
edges_temp <- data.frame(
osm_id = rep(ruas_segmentadas$osm_id, sapply(st_geometry(ruas_segmentadas), function(g) nrow(st_coordinates(g)))),
X = coords[, "X"],
Y = coords[, "Y"]
)
edges <- edges_temp %>%
group_by(osm_id) %>%
summarise(from.X = first(X), from.Y = first(Y),
to.X = last(X), to.Y = last(Y)) %>%
left_join(nodes, by = c("from.X" = "X", "from.Y" = "Y")) %>%
rename(from = id) %>%
left_join(nodes, by = c("to.X" = "X", "to.Y" = "Y")) %>%
rename(to = id) %>%
left_join(ruas_segmentadas %>% select(osm_id, edge_id, geometry), by = "osm_id") %>%
mutate(original_id = osm_id) # Agora `osm_id` será corretamente preservado
edges <- edges %>%
dplyr::select(from, to, original_id, edge_id)
nodes <- nodes %>%
filter(id %in% c(edges$from, edges$to))
print(nrow(ruas_segmentadas)) # Deve ser igual ao número de edges
## [1] 18
print(nrow(edges)) # Deve ser igual ao número de ruas
## [1] 18
edges_sf <- edges_temp %>%
st_as_sf(coords = c("X", "Y"), crs = 4326) # Converter para spatial dataframe
mapview(edges_sf, zcol="osm_id") + mapview(ruas, zcol="osm_id")
grafo <- graph_from_data_frame(edges, directed = TRUE)
plot(grafo, vertex.label = NA, main = "Grafo da Rede Viaria")
Os vértices representam os nós da rede—no seu caso, podem ser
interseções de ruas ou pontos específicos no mapa.
- Vértices altos: Indica uma rede viária complexa, com muitas
interseções.
- Vértices baixos: Pode representar caminhos mais diretos, com menos
pontos de decisão.
print(vcount(grafo))
## [1] 17
As arestas representam conexões entre os vértices—ou seja, as ruas ou
caminhos entre interseções.
- Arestas altas: Indica uma rede viária bem interligada, com múltiplas
rotas possíveis.
- Arestas baixas: Pode significar poucas alternativas, o que pode afetar
o fluxo de tráfego.
print(ecount(grafo))
## [1] 18
Mede quão conectada está a rede.
- Densidade alta: Muitas conexões entre nós, indicando um centro urbano
compacto.
- Densidade baixa: Rede mais espalhada, típica de áreas suburbanas.
print(edge_density(grafo))
## [1] 0.06617647
O grau de um nó é o número de conexões que ele possui.
- Nó de alto grau: Muito conectado, pode ser um ponto central na rede
viária.
- Nó de baixo grau: Poucas conexões, pode ser um cul-de-sac ou um
cruzamento menos utilizado.
Essa métrica indica quantos vizinhos imediatos um nó possui.
- Nó com alto grau: Muito conectado, pode ser um ponto de grande fluxo
na rede viária.
- Nó com baixo grau: Poucas conexões, pode representar um beco sem saída
ou um cruzamento menos movimentado.
print(degree(grafo))
## 1 3 8 13 15 17 23 25 28 30 35 29 12 7 22 34 43
## 1 4 3 4 1 4 2 1 1 4 2 2 3 1 1 1 1
Mede quantas vezes um nó é usado como “ponte” entre outros.
- Nó com alta betweenness: Crucial para conectar diferentes partes da
rede.
- Nó com baixa betweenness: Menos importante para a conectividade
global.
print(betweenness(grafo))
## 1 3 8 13 15 17 23 25 28 30 35 29 12 7 22 34 43
## 0 44 9 46 0 47 9 0 0 50 18 10 12 0 0 0 0
A centralidade de proximidade (closeness) mede o quão rapidamente um
nó pode alcançar todos os outros na rede. Ela ajuda a identificar pontos
estratégicos para navegação e mobilidade. 🚀
- Um nó com alta proximidade pode chegar rapidamente a todos os outros
pontos da rede.
- Um nó com baixa proximidade está mais isolado, levando mais tempo para
alcançar os demais.
Isso é útil, por exemplo, para planejamento urbano, indicando
interseções centrais que facilitam o tráfego.
Fórmula matemática
A proximidade de um nó ( u ) é calculada como:
\[C(u) = \frac{1}{\sum d(u,
v)}\]
onde ( d(u, v) ) representa a distância mais curta entre o nó ( u ) e
todos os outros ( v ).
Quanto menor a soma das distâncias, maior a proximidade!
print(closeness(grafo))
## 1 3 8 13 15 17 23
## 0.03448276 0.05000000 0.04000000 0.05555556 0.02857143 0.05263158 0.03571429
## 25 28 30 35 29 12 7
## 0.02631579 0.01960784 0.04761905 0.03333333 0.02500000 1.00000000 NaN
## 22 34 43
## NaN NaN NaN
Representa a maior distância entre dois nós da rede.
- Diâmetro grande: Cidade extensa, onde os extremos estão longe.
- Diâmetro pequeno: Cidade compacta, tudo está perto.
print(diameter(grafo))
## [1] 8
# comunidades <- cluster_louvain(grafo)
# V(grafo)$comunidade <- membership(comunidades)
nodes_vis <- data.frame(
id = nodes$id,
label = nodes$id,
title = paste("ID:", nodes$id) # Exibir ID ao passar o mouse
)
edges_vis <- edges %>%
mutate(
title = paste("Rua OSM ID:", original_id), # Exibir ao passar o mouse
# osm = original_id, # Exibir ao passar o mouse
label = original_id # Exibir diretamente no grafo
) %>%
dplyr::select(from, to, title, label) # Removido erro de texto extra
#edges_vis$title <- as.character(edges_vis$original_id) # Converter para texto legível
nodes_vis <- nodes_vis %>%
filter(id %in% c(edges_vis$from, edges_vis$to))
visNetwork(nodes_vis, edges_vis) %>%
visOptions(highlightNearest = TRUE, nodesIdSelection = TRUE) %>%
visLegend(position = "right")
edges_vis <- edges_vis %>%
mutate(
comprimento_km = 1,#as.numeric(st_length(geometry)) / 1000, # exemplo com comprimento da rua
peso_congestionamento = 2,#1 / (faixas + 1) + as.numeric(tem_semaforo) + densidade_edif,
info_tooltip = paste("Comprimento",comprimento_km, "<br>Peso:", peso_congestionamento,"<br>Faixas:", NA, "<br>Semáforo:", NA, "<br>Densidade:", NA)
)
edges_vis$title <- edges_vis$info_tooltip
edges_vis$label <- paste0("ID: ", edges_vis$label)
visNetwork(nodes_vis, edges_vis)
nodes_vis <- data.frame(
id = nodes$id,
label = nodes$id,
title = paste("ID:", nodes$id), # Exibir ID ao passar o mouse
group = nodes$id # Atribuir o grupo baseado na comunidade
#group = V(grafo)$comunidade # Atribuir o grupo baseado na comunidade
)
nodes_vis$color <- rainbow(length(unique(nodes_vis$group)))[nodes_vis$group]
edges_vis <- edges %>%
mutate(title = paste("Rua OSM ID:", original_id), label = original_id) %>%
dplyr::select(from, to, original_id)
visNetwork(nodes_vis, edges_vis) %>%
visOptions(highlightNearest = TRUE, nodesIdSelection = TRUE) %>%
visGroups(groupname = unique(nodes_vis$group)) %>%
visLegend(position = "right")
Ah, os fractais… uma beleza caótica que ainda está no forno! 🔥
A análise fractal pode revelar padrões ocultos na estrutura da sua rede viária e ajudar a entender sua complexidade. Aqui estão alguns passos para transformar sua rede em um fractal e realizar a análise:
1️⃣ Converter a Rede em um Fractal Método de Box-Counting: Uma abordagem comum para medir a dimensão fractal de redes espaciais. Você pode dividir sua rede em uma grade de diferentes tamanhos e contar quantas células contêm partes da rede.
Método de Similaridade: Algumas redes viárias apresentam padrões de auto-semelhança, onde segmentos menores se parecem com a estrutura maior. Você pode testar isso aplicando subdivisões iterativas.
2️⃣ Calcular a Dimensão Fractal Use a função fractaldim() do pacote fractal no R para calcular a dimensão fractal da rede.
Outra opção é usar boxcount() do pacote pracma, que implementa o método de contagem de caixas.
3️⃣ Analisar Propriedades Fractais Distribuição de Grau: Redes fractais muitas vezes seguem distribuições de potência. Você pode verificar isso com fit_power_law() do pacote igraph.
Centralidade e Caminhos: A análise de betweenness e closeness pode revelar padrões fractais na conectividade da rede.
4️⃣ Visualização Fractal Você pode usar ggplot2 para criar gráficos que mostram a estrutura fractal da rede.
1️⃣ Cálculo da Dimensão Fractal com Box-Counting Este método divide a rede em uma grade e conta quantas células contêm partes da rede.
🧠 O que é a Dimensão Fractal? - É uma medida da complexidade espacial de um objeto irregular — como uma rede de ruas ou o contorno de uma cidade. - A dimensão fractal indica o grau em que o padrão “enche” o espaço: quanto mais fragmentado ou ramificado, maior a dimensão (embora nunca exceda o valor inteiro do espaço: em 2D, nunca passa de 2).
📦 Box-Counting: Como funciona a técnica? A ideia do método é: - Cobrir o conjunto de pontos com uma malha de quadrados de tamanho size - Contar quantos quadrados contêm pelo menos um ponto - Repetir com diferentes tamanhos de quadrado - Plotar o resultado em escala log-log para estimar a dimensão fractal com uma regressão
📊 Interpretação - Uma rede viária mais orgânica, como em centros históricos, tende a ter dimensão fractal mais alta - Redes muito regulares ou planejadas (como malhas retangulares) têm dimensões mais próximas de 1
library(pracma)
# Função para calcular a dimensão fractal usando Box-Counting
box_counting <- function(points, sizes) {
counts <- sapply(sizes, function(size) {
grid_x <- seq(min(points$X), max(points$X), by = size)
grid_y <- seq(min(points$Y), max(points$Y), by = size)
count <- sum(sapply(grid_x, function(x) {
sum(sapply(grid_y, function(y) {
any(points$X >= x & points$X < x + size & points$Y >= y & points$Y < y + size)
}))
}))
return(count)
})
return(data.frame(size = sizes, count = counts))
}
# Aplicação sobre os nós da rede
#- Varia o tamanho das caixas de 0.001 a 0.01 (em unidades do espaço — pode ser km, graus, etc.)
sizes <- seq(0.001, 0.01, by = 0.001)
sizes <- seq(10, 1000, by = 10) # tamanhos das caixas em metros
result <- box_counting(nodes, sizes)
# Ajuste log-log para estimar a dimensão fractal
#plot(log(result$size), log(result$count), type = "b", main = "Dimensão Fractal da Rede Viária")
plot(log(result$size / 1000), log(result$count), type = "b",
xlab = "Log(Tamanho da caixa em km)", ylab = "Log(Contagem)",
main = "Dimensão Fractal da Rede Viária")
2️⃣ Distribuição de Grau e Ajuste de Lei de Potência Redes fractais frequentemente seguem distribuições de potência.
library(igraph)
# Ajuste de Lei de Potência
fit <- fit_power_law(degree(grafo))
print(fit)
## $continuous
## [1] FALSE
##
## $alpha
## [1] 1.932962
##
## $xmin
## [1] 1
##
## $logLik
## [1] -28.13125
##
## $KS.stat
## [1] 0.1343017
3️⃣ Visualização Fractal Podemos visualizar padrões fractais na rede.
library(ggplot2)
ggplot(nodes, aes(x = X, y = Y)) +
geom_point(color = "blue", alpha = 0.5) +
theme_minimal() +
ggtitle("Visualização Fractal da Rede Viária")
library(igraph)
# Criar o grafo a partir das arestas
grafo <- graph_from_data_frame(edges, directed = FALSE)
# Calcular betweenness centrality
betweenness_values <- betweenness(grafo, normalized = TRUE)
betweenness_values
## 1 3 8 13 15 17 23 25
## 0.0000000 0.3250000 0.1250000 0.4833333 0.0000000 0.4041667 0.1250000 0.0000000
## 28 30 35 29 12 7 22 34
## 0.0000000 0.4875000 0.2333333 0.1250000 0.1250000 0.0000000 0.0000000 0.0000000
## 43
## 0.0000000
# Calcular closeness centrality
closeness_values <- closeness(grafo, normalized = TRUE)
closeness_values
## 1 3 8 13 15 17 23 25
## 0.3018868 0.4210526 0.3555556 0.4705882 0.2666667 0.4324324 0.3200000 0.2461538
## 28 30 35 29 12 7 22 34
## 0.2162162 0.4571429 0.3478261 0.2711864 0.3555556 0.3018868 0.3076923 0.3200000
## 43
## 0.2666667
# Adicionar os valores aos nós
nodes$betweenness <- betweenness_values[nodes$id]
nodes$closeness <- closeness_values[nodes$id]
# Visualizar os resultados
print(summary(nodes$betweenness))
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## 0.0000 0.0000 0.0625 0.0625 0.1250 0.1250 9
print(summary(nodes$closeness))
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## 0.2462 0.2701 0.3048 0.3031 0.3289 0.3556 9
# Visualizar graficamente
library(ggplot2)
ggplot(nodes, aes(x = betweenness)) +
geom_histogram(bins = 30, fill = "blue", alpha = 0.7) +
theme_minimal() +
ggtitle("Distribuição da Centralidade Betweenness")
## Warning: Removed 9 rows containing non-finite outside the scale range
## (`stat_bin()`).
ggplot(nodes, aes(x = closeness)) +
geom_histogram(bins = 30, fill = "red", alpha = 0.7) +
theme_minimal() +
ggtitle("Distribuição da Centralidade Closeness")
## Warning: Removed 9 rows containing non-finite outside the scale range
## (`stat_bin()`).
1️⃣ Dimensão de Hausdorff Este método mede a complexidade da rede considerando sua auto-semelhança.
Uma dimensão alta como essa pode indicar que o conjunto ocupa muito espaço (ou grau de liberdade) dentro do espaço de origem.
Em análise fractal: seria um objeto extremamente intricado em múltiplas escalas.
A dimensão de Hausdorff, nesse contexto, quantifica como o número de vizinhos acessíveis cresce com a escala.
Em redes rodoviárias, ela pode indicar densidade de conexões e redundância geográfica (por exemplo, número de caminhos alternativos entre regiões).
Uma dimensão alta, como 31.7, sugere que o grafo é extremamente ramificado, com muitas possibilidades de movimento, rotas e interconexões — talvez até que os dados estejam em um espaço de atributos muito rico (tempo, fluxo, tipo de via, etc.).
library(geometry)
##
## Attaching package: 'geometry'
## The following objects are masked from 'package:pracma':
##
## cart2pol, cart2sph, dot, pol2cart, polyarea, sph2cart
# Função para calcular a dimensão de Hausdorff
hausdorff_dim <- function(points) {
dist_matrix <- dist(points)
return(max(dist_matrix) / min(dist_matrix))
}
# Aplicação sobre os nós da rede
hausdorff_value <- hausdorff_dim(nodes[, c("X", "Y")])
print(paste("Dimensão de Hausdorff:", hausdorff_value))
## [1] "Dimensão de Hausdorff: 31.7283359883424"
2️⃣ Análise de Percolação Estuda a conectividade da rede e como ela se fragmenta.
library(igraph)
# Remover aleatoriamente 10% das arestas e verificar conectividade
grafo_removido <- delete_edges(grafo, sample(E(grafo), length(E(grafo)) * 0.1))
components <- components(grafo_removido)
print(paste("Número de componentes após remoção:", components$no))
## [1] "Número de componentes após remoção: 2"
3️⃣ Distribuição de Lei de Potência Verifica se a rede segue uma distribuição fractal.
library(igraph)
# Ajuste de Lei de Potência
fit <- fit_power_law(degree(grafo))
print(fit)
## $continuous
## [1] FALSE
##
## $alpha
## [1] 1.932962
##
## $xmin
## [1] 1
##
## $logLik
## [1] -28.13125
##
## $KS.stat
## [1] 0.1343017
4️⃣ Dimensão Fractal da Fronteira Mede a irregularidade das bordas da rede.
#devtools::install_github ("mariodosreis/fractal")
#https://github.com/mariodosreis/fractal
library(fractal)
library(Rdimtools)
## ** ------------------------------------------------------- **
## ** Rdimtools || Dimension Reduction and Estimation Toolbox
## **
## ** Version : 1.1.2 (2025)
## ** Maintainer : Kisung You (kisungyou@outlook.com)
## ** Website : https://kisungyou.com/Rdimtools/
## **
## ** Please see 'citation('Rdimtools)' to cite the package.
## ** ------------------------------------------------------- **
# Aplicação do método de Box-Counting na fronteira
border_points <- nodes[nodes$id %in% c(edges$from, edges$to), ]
# Definir um número adequado de níveis para a análise fractal
nlevel_value <- 50 # Ajuste conforme necessário
# Executar a análise de Box-Counting
result <- est.boxcount(as.matrix(border_points[, c("X", "Y")]), nlevel = nlevel_value)
# Visualizar os resultados
plot(log(1 / result$r), log(result$Nr), type = "b",
main = "Dimensão Fractal da Fronteira",
xlab = "Log(1/Escala)", ylab = "Log(Número de caixas)")
5️⃣ Análise de Auto-Similaridade
Verifica padrões de auto-semelhança na rede.
library(igraph)
library(Rdimtools)
library(ggplot2)
# Criar o grafo
grafo <- graph_from_data_frame(edges, directed = FALSE)
# **1. Corrigir erro na extração de comunidades**
comunidades <- cluster_louvain(grafo)
membership_df <- data.frame(id = as.numeric(names(membership(comunidades))),
comunidade = as.numeric(membership(comunidades)))
Geramos o grafo de comunidades
visNetwork(nodes_vis, edges_vis) %>%
visOptions(highlightNearest = TRUE, nodesIdSelection = TRUE) %>%
visGroups(groupname = unique(nodes_vis$comunidade)) %>%
visLegend(position = "right")
# **5. Corrigir a análise fractal**
nlevel_value <- 50
result <- est.boxcount(as.matrix(nodes[, c("X", "Y")]), nlevel = nlevel_value)
# **6. Ajustar gráfico para evitar NA values**
ggplot(na.omit(nodes), aes(x = betweenness)) +
geom_histogram(bins = 30, fill = "blue", alpha = 0.7) +
theme_minimal() +
ggtitle("Distribuição da Centralidade Betweenness")