ggraph icon indicating copy to clipboard operation
ggraph copied to clipboard

geom_node_col: Bar plot at each node

Open mikldk opened this issue 6 years ago • 3 comments

The geom_node_tile() draws nodes as tiles with center provided by the layout's x and y components and with width and height from the geom_node_tile()'s mapping. That's very useful.

I have a slightly different use-case: I wish to be able to draw something like a geom_col() at each node. I.e. two (or more) bars and not just a tile. The problem with geom_node_tile() is that as with geom_tile(), the x and y give the center, so comparing two bars/tiles is difficult as positioning from the center is fundamentally wrong.

I am wondering what you think would be the best way solving this? I have a few suggestions myself:

  1. Try to solve it in generality by making it possible for nodes to each have a geom_col().
  2. Implement geom_node_rect() using geom_rect() with it's xmin, xmax, ymin and ymax parameters. I am not sure if sensible default values can be provided.
  3. Make extra arguments to geom_node_tile(): hjust and vjust: The default hjust = 0.5 and vjust = 0.5 gives functionality as now. In my case I would do something like hjust = 0 and hjust = 0.5. Here, the problem is that the bars will use the same y coordinate.

Do you have any input on this?

I would prefer solving it in generality by a geom_node_col() as suggested in 1), but I'm not sure if that's possible.

mikldk avatar Jun 14 '19 06:06 mikldk

In https://twitter.com/mikldk/status/1139420728254554114, @thomasp85 mentioned that solving this in general (item 1) would be good, but also that he hadn't had time to look at it, yet. Meanwhile @thomasp85 suggested to maybe use https://CRAN.R-project.org/package=scatterpie / https://github.com/GuangchuangYu/scatterpie.

mikldk avatar Jun 14 '19 07:06 mikldk

Technically you can do this yourself using ggplot2::annotation_custom().

library(dplyr)
library(purrr)
library(ggplot2)
library(tidygraph)
library(ggraph)

set.seed(42)

g = tbl_graph(
  nodes = tibble(x = sample(seq(1, 100, by = 5), 6), y = sample(seq(1, 100, by = 5), 6)),
  edges = tibble(from = sample(1:3, 3),to = sample(4:6, 3))
)


p = as_tibble(g, "nodes") %>%
  mutate(
    plot = map(1:6,
      ~ ggplot(tibble(x = rnorm(100, sd = .x)), aes(x = x)) + 
	    geom_histogram() + theme_bw(base_size = 8)),
	annotation = pmap(list(x, y, plot),
    ~ annotation_custom(ggplotGrob(..3),
      xmin = ..1 - 5, xmax = ..1 + 5,
      ymin = ..2 - 5, ymax = ..2 + 5))
  ) 

ggraph(g, layout = "manual", x = x, y = y) + 
  theme_graph() +
  geom_edge_link() +
  geom_node_tile(width = 10, height = 10) +
  pull(p, annotation)

image

Also see https://github.com/thomasp85/ggforce/issues/147

mkoohafkan avatar Mar 10 '20 20:03 mkoohafkan

using ggsubplot2:

# remotes::install("mkoohafkan/ggsubplot2")
library(dplyr)
library(purrr)
library(ggplot2)
library(tidygraph)
library(ggraph)
library(ggsubplot2)

set.seed(42)

g = tbl_graph(
  nodes = tibble(x = sample(seq(1, 100, by = 5), 6), y = sample(seq(1, 100, by = 5), 6)),
  edges = tibble(from = sample(1:3, 3),to = sample(4:6, 3))
) %N>%
  mutate(plot = map(1:n(),
    ~ ggplot(tibble(x = rnorm(1000, sd = .x)),
          aes(x = x)) +
          geom_histogram() +
          theme_bw(base_size = 4)
  ))


ggraph(g, layout = "manual", x = x, y = y) +
  theme_graph() +  
  geom_edge_link() +
  geom_node_tile(width = 10, height = 10) +
  geom_subfig(aes(x = x, y = y, plot = plot), width = 10, height = 10)

image

mkoohafkan avatar Mar 14 '20 16:03 mkoohafkan