rgraphvisualizationigraph

Coloring points on a graph proportionately


I have this graph in R:

library(igraph)

width <- 30
height <- 20
num_nodes <- width * height

x <- rep(1:width, each = height)
y <- rep(1:height, times = width)

g <- make_empty_graph(n = num_nodes, directed = FALSE)

get_node_index <- function(i, j) (i - 1) * height + j

edges <- c()
for(i in 1:width) {
    for(j in 1:height) {
        current_node <- get_node_index(i, j)
        
        if(i < width) edges <- c(edges, current_node, get_node_index(i + 1, j))
        
        if(j < height) edges <- c(edges, current_node, get_node_index(i, j + 1))
    }
}

g <- add_edges(g, edges)

V(g)$x <- x
V(g)$y <- y

par(mfrow=c(1,1))

V(g)$name <- 1:num_nodes
plot(g, vertex.size = 7, vertex.label = V(g)$name, vertex.label.cex = 0.6, main = "Map with         Node Indices")

enter image description here

I want to pick some node on this graph, and color all nodes on this graph proportional to how far they are located from this node. That is, all nodes of the same distance have the same color - and nodes closer to the node are darker colored vs nodes that are farther away are lighter colored.

Based on my previous question (Calculating the shortest distance between multiple points on a graph?), I tried to do this (e.g. select node 50):

distances_from_50 <- distances(g, v = 50, to = V(g))
max_dist <- max(distances_from_50)

color_palette <- colorRampPalette(c("#08306B", "#F7FBFF"))(max_dist + 1)

V(g)$color <- color_palette[distances_from_50 + 1]

V(g)$color[50] <- "red"

par(mfrow=c(1,1), mar=c(5,4,4,2))
plot(g, 
     vertex.size = 7,
     vertex.label = V(g)$value,
     vertex.label.cex = 0.6,
     main = "Distance-based Color Gradient from Node 50",
     layout = cbind(V(g)$x, V(g)$y))

enter image description here

Is there something else that can be done so that nodes with darker colors still have visible labels?


Solution

  • I think this depends on your subjective perception about color differentiation. You can define a color palette specifically for vertex labels, e.g.,

    labelcolor_palette <- colorRampPalette(c("white", "lightyellow", "red", "purple", "black"))(max_dist + 1)
    V(g)$labelcolor <- labelcolor_palette[distances_from_50 + 1]
    plot(g,
        vertex.size = 7,
        vertex.label = V(g)$value,
        vertex.label.cex = 1,
        vertex.label.color = V(g)$labelcolor,
        main = "Distance-based Color Gradient from Node 50",
        layout = cbind(V(g)$x, V(g)$y)
    )
    

    enter image description here