3

I am trying to visualize some networks using the ggraph package. My network has two different types of edges, A and B, which have different scales. I'd like to color the edges by type (which I've done) and also modulate their opacity by the value. However, since all the edges are displayed together and since A and B have different scales, using aes(alpha=value) uses the entire scale over both A and B, so all the edges with the smaller scale (here A) are practically invisible. How can I separate the alpha scales for A and B so that the alpha corresponds to their internal scales? (ie, alpha=1 when an A edge is at max A and a B edge is at max B)

I've included a small example below:

library(ggplot2)
library(igraph)
library(ggraph)
nodes <- data.frame(id=seq(1,5),label=c('a','b','c','d','e'))
edges <- data.frame(from=c(3,3,4,1,5,3,4,5),
                    to=  c(2,4,5,5,3,4,5,1),
                    type=c('A','A','A','A','A','B','B','B'),
                    value=c(1,.2,.5,.3,1,5,12,8))
net <- graph_from_data_frame(d=edges,vertices=nodes,directed=T)
ggraph(net,layout='stress') + 
  geom_edge_fan(aes(color=type,alpha=value)) + 
  geom_node_label(aes(label=label),size=5)

This is what the graph currently looks like:

badgraph.png

And I want something that looks like this:

fixedgraph.png

Ideally I'd be able to do this in R and not do a convoluted editing process in GIMP.

I was hoping this would be possible with set_scale_edge_alpha, but I can't find the solution anywhere. I saw from here that this can be done with ggnewscale, but this seems to require drawing two separate objects, and it also doesn't seem like there is a function for specifically changing edge aesthetics. Is there a simple way to do this without drawing two overlapping graphs?

Thanks!

zx8754
  • 52,746
  • 12
  • 114
  • 209

1 Answers1

2

It would probably be better just to rescale the values yourself before plotting. You can scale the values to a 0-1 scale within each group

edges <- edges %>% 
  group_by(type) %>% 
  mutate(value = scales::rescale(value))
MrFlick
  • 195,160
  • 17
  • 277
  • 295
  • Thanks, this makes sense, I'll probably go with this. Though I would like to keep the original values somehow so that I can reference them in the legend, etc, but I guess that may be too much anyway. And if instead I wanted to have both of them on different color scales completely (like A on a red-to-yellow and B on a green-to-blue colormap), is this possible? I realize this is slightly different from the question I explicitly asked, but I'm looking for a more general solution for splitting aesthetic scales – user19492750 Jul 06 '22 at 20:24
  • In general, ggplot doesn’t allow more than one scale per aesthetics. You’d have to hack it to make something like that work. It would be better as it’s own separate question. (Though likely duplicates for that already exist) – MrFlick Jul 06 '22 at 20:26