rggplot2ggraph

ggplot2 geom_point and geom_text prevent exceeding plot area in R


I have a graph to plot points, texts and edges to export in png. Here is current codes.

node <- data.frame(id=c(1,2,3), x=c(1,2,1), y=c(1,1,2), label=c("a","b","c"))
edge <- data.frame(from=c(1,1,2), to=c(2,3,3))
g <- graph_from_data_frame(d=edge, vertices=node, directed=F)


cor <- matrix(c(V(g)$x, y=V(g)$y), ncol=2)

p <- g %>% ggraph(layout=cor) +
## Base settings
  geom_edge_link(width=3, color="gray70") +
  geom_node_point(size=22, aes(x=x, y=y)) +
  geom_node_text(size=16, color="white", fontface=2, vjust=0.4, aes(x=x, y=y, label=label)) +
## Set axis
  expand_limits(x=1, y=1) +
  coord_fixed() +
## Set legend
  scale_color_manual(name=tname, labels=plabel, values=pname) +
## Theme
theme(
  ## Font size
  plot.title=element_blank(),
  axis.title.y=element_blank(),
  axis.title.x.top=element_blank(),
  axis.text=element_blank(),
  legend.title=element_blank(),
  legend.text=element_blank(),
  legend.position="none",
  ## Appearance
  panel.background=element_rect(fill="transparent"),
  panel.grid.major=element_blank(),
  legend.key=element_blank()
  )

ggsave(p, file="test.png", width=5, height=5, dpi=100)

It generates the following image. Nodes and texts are cut off, thus I changed width and height in ggsave larger value so it fit into the plot area. But node size became smaller.

enter image description here

enter image description here

As I need to put lots of graphs in a document within limited space, I do not want to make node and text size small. Also, it may not suite changing values in expand_limits(x=1, y=1) dinamically as I need to export graphs into images as bigger as possible within fixed and limited size (in this example, 'width=5, height=5'). Is there any ways or parameters to plot nodes and texts within plot area? I've tried margin() in theme() but it can set marging outside plot area.


Solution

  • One option would be to

    1. remove the default expansion of the x and y scale,
    2. set the length of the (even if invisible) axis ticks to zero,
    3. use clip="off" to prevent the points and text to be clipped off when hitting the panel border
    4. and finally to set the plot.margin according to the size of your points, e.g. a margin of 9mm works fine for the point size of 22. (Actually I expected that 22 / 2 = 11 should work fine.).
    library(ggraph)
    library(tidygraph)
    library(igraph)
    
    p <- g %>% 
      ggraph(layout = cor) +
      ## Base settings
      geom_edge_link(width = 3, color = "gray70") +
      geom_node_point(size = 22, aes(x = x, y = y)) +
      geom_node_text(
        size = 16, color = "white", fontface = 2, vjust = 0.4,
        aes(x = x, y = y, label = label)
      ) +
      scale_x_continuous(expand = c(0, 0)) +
      scale_y_continuous(expand = c(0, 0)) +
      ## Set axis
      expand_limits(x = 1, y = 1) +
      coord_fixed(clip = "off") +
      ## Set legend
      # scale_color_manual(name = tname, labels = plabel, values = pname) +
      ## Theme
      theme(
        ## Font size
        plot.title = element_blank(),
        axis.title.y = element_blank(),
        axis.title.x.top = element_blank(),
        axis.text = element_blank(),
        axis.ticks = element_blank(),
        axis.line = element_blank(),
        axis.ticks.length = unit(0, "pt"),
        legend.title = element_blank(),
        legend.text = element_blank(),
        legend.position = "none",
        ## Appearance
        panel.background = element_rect(fill = "transparent"),
        panel.grid.major = element_blank(),
        legend.key = element_blank(),
        plot.margin = unit(rep(9, 4), units = "mm")
      )
    
    ggsave(p, file = "test.png", width = 5, height = 5, dpi = 100)
    

    enter image description here

    And for a larger size

    ggsave(p, file = "test.png", width = 20, height = 20, dpi = 100, scale = .5)
    

    enter image description here