I am using ggraph to plot two networks containing nodes and edges of varying sizes and widths, respectively.
I want to maintain the absolute sizes of nodes and edges using scale_size_identity()
and scale_edge_width_identity()
.
I'd like to display legends and am using scale_size_identity(legend = "guide")
for nodes, which works as expected, but for edges scale_edge_width_identity(legend = "guide")
I get the following error:
Error: Continuous value supplied to discrete scale
If I don't provide legend = "guide"
to scale_edge_width_identity()
, everything works. The variable I'm scaling is numeric. This problem also occurs if I'm using scale_edge_alpha_identity(legend = "guide")
Why is this and is there any way I can still show the legends? Appreciate any suggestions.
UPDATE:
It works with the suggestion by @teunbrand below. However, I noticed that scale_size_continuous()
for scaling node size does not work with this approach. Use scale_radius()
instead:
# building on example by @teunbrand
library(ggraph)
#> Loading required package: ggplot2
require(tidygraph)
#> Loading required package: tidygraph
#>
#> Attaching package: 'tidygraph'
#> The following object is masked from 'package:stats':
#>
#> filter
library(patchwork)
gr <- create_notable("bull")
layout <- create_layout(gr, layout = "igraph", algorithm = "kk")
edge_guide <- guide_legend()
# Edges are plotted using the same scale but nodes are not when scale_size_continuous() is used.
# Notice the differently sized nodes between the legend guides:
ggraph(layout) +
geom_node_point(aes(size = seq(1, 5, length.out = 5))) +
geom_edge_link(aes(edge_width = seq(1, 5, length.out = 5))) +
scale_size_continuous(range = c(1, 5), breaks = c(1, 3, 5)) +
scale_edge_width_continuous(range = c(1, 5), breaks = c(1, 2, 3)) |
ggraph(layout) +
geom_node_point(aes(size = seq(1, 10, length.out = 5))) +
geom_edge_link(aes(edge_width = seq(1, 10, length.out = 5))) +
scale_size_continuous(range = c(1, 10), breaks = c(1, 3, 5)) +
scale_edge_width_continuous(range = c(1, 10), breaks = c(1, 2, 3))
# However, using scale_radius() instead does the job:
ggraph(layout) +
geom_node_point(aes(size = seq(1, 5, length.out = 5))) +
geom_edge_link(aes(edge_width = seq(1, 5, length.out = 5))) +
scale_radius(range = c(1, 5), breaks = c(1, 3, 5)) +
scale_edge_width_continuous(range = c(1, 5), breaks = c(1, 2, 3)) |
ggraph(layout) +
geom_node_point(aes(size = seq(1, 10, length.out = 5))) +
geom_edge_link(aes(edge_width = seq(1, 10, length.out = 5))) +
scale_radius(range = c(1, 10), breaks = c(1, 3, 5)) +
scale_edge_width_continuous(range = c(1, 10), breaks = c(1, 2, 3))
Created on 2020-12-04 by the reprex package (v0.3.0)
I get the confusion and this might be a bug, but here are workarounds. The workaround is basically to use the _continuous()
version of the scales to mimick the _identity()
version as close as possible by setting the range to the exact range of the data.
library(ggraph)
#> Loading required package: ggplot2
require(tidygraph)
#> Loading required package: tidygraph
#>
#> Attaching package: 'tidygraph'
#> The following object is masked from 'package:stats':
#>
#> filter
gr <- create_notable('bull')
layout <- create_layout(gr, layout = 'igraph', algorithm = 'kk')
edge_guide <- guide_legend()
ggraph(layout) +
geom_node_point() +
geom_edge_link(aes(edge_width = 1:5)) +
scale_edge_width_continuous(range = c(1, 5))
ggraph(layout) +
geom_node_point() +
geom_edge_link(aes(edge_alpha = seq(0.1, 1, length.out = 5))) +
scale_edge_alpha_continuous(range = c(0.1, 1))
Created on 2020-12-03 by the reprex package (v0.3.0)