2

I am trying to move the legend text and legend boxes further apart (horizontally) on a box and jitter plot. The complicating factor is the coord_flip I used to make the boxplot horizontal. In theme I tried using both legend.spacing.x and legend.spacing.y but neither had any effect on the distance between legend text and legend boxes.

Here is the graph with fake data. More complex than necessary I know but I need to be able to make it work with all the complications.

library(dplyr)
library(ggplot2)
set.seed(01234)

# make some data
totDays <- data.frame(id = 1:80,
                      group = rep(c("Placebo", "Drug"), each = 40),
                      total84 = c(pmin(abs(round(rnorm(40, 55, 30))),84), pmin(abs(round(rnorm(40, 38, 30))),84)))


# get some descriptives
(groupDF <- totDays %>% group_by(group) %>%
                        dplyr::summarise(m = mean(total84, na.rm = T),
                                         sd = sd(total84, na.rm = T),
                                         count = n()) %>%
                        mutate(se = sd/sqrt(count)))

# now for the box and scatter plot
(g <- ggplot(totDays, aes(group, total84, colour = group)) +
              geom_jitter(size = 1, width = 0.1) + # so points aren't overlaid, width controls how much jitter
              geom_point(stat = "summary", fun.y = "mean", shape = 3, size = 3, colour = "black") + # crosses for mean
              geom_boxplot(alpha = 0, width = 0.5, lwd = 1, size = 0.5) +
              scale_color_manual(values = c("#00AFBB", "#E7B800")) +
              scale_y_continuous(breaks = seq(0,84,14), minor_breaks = seq(0, 84, 14)) + # changes minor break line
              coord_flip() +
              labs(y = "Score") +
              geom_hline(yintercept = c(groupDF$m), linetype = "dotted") +
              geom_segment(x = 2.38, xend = 2.38, y = groupDF$m[2] + .1, yend = groupDF$m[1] - .1, size = .7, arrow = arrow(end = "both", type = "open", length = unit(0.15, "cm")), colour = "#696969") +
              annotate("text", x = 2.46, y = mean(groupDF$m), label = paste0("italic(p) == ", 0.02), parse = T) +
              theme_bw() +
              theme(axis.title.y = element_blank(),
                    axis.ticks.y = element_blank(),
                    axis.text.y = element_blank(),
                    axis.text.x = element_text(size = 13),
                    axis.title.x = element_text(size = 13, face = "bold", margin = margin(t = 0, r = 0, b = 10, l = 0), vjust = -2), # note the use of margin to move the title away from the axis text
                    legend.title = element_blank(),
                    legend.position = "top",
                    legend.spacing.y = unit(.1, "cm"),
                    legend.box.spacing = unit(.1, "cm"), # adjusts distance of box from x-axis
                    legend.key.size = unit(1, "cm"),
                    legend.text = element_text(size = 13, face = "bold"),
                    strip.text = element_text(size = 13, face = "bold"),
                    panel.grid.major.y = element_blank(),
                    panel.grid.major.x = element_line(size=.4, color="#F7F7F7")))

enter image description here

llewmills
  • 2,959
  • 3
  • 31
  • 58
  • Can you post the current plot? – Tung Mar 12 '19 at 01:56
  • See if these work for you https://stackoverflow.com/a/50615868/ & https://stackoverflow.com/a/50885122/ – Tung Mar 12 '19 at 02:06
  • Thanks @Tung. I have posted the plot. I used the first of your referred posts to create the existing graphs but can't seem to get around the `coord_flip()` problem. – llewmills Mar 12 '19 at 03:35
  • Can you include an illustration of what your desired outcome would look like? Going by your description, it sounds like adding `legend.spacing.x = unit([some positive number], "cm")` gives that result? – Z.Lin Mar 12 '19 at 04:34

1 Answers1

1

Use either stringr::str_pad() or theme(legend.spacing.x = ...) or both

g <- ggplot(totDays, aes(group, total84, colour = group)) +
    geom_jitter(size = 1, width = 0.1) + # so points aren't overlaid, width controls how much jitter
    geom_point(stat = "summary", fun.y = "mean", shape = 3, size = 3, colour = "black") + # crosses for mean
    geom_boxplot(alpha = 0, width = 0.5, lwd = 1, size = 0.5) +
    scale_color_manual(values = c("#00AFBB", "#E7B800"),

                       ### added
                       labels = stringr::str_pad(c("Drug", "Placebo"), 10, "right")) +

    scale_y_continuous(breaks = seq(0,84,14), minor_breaks = seq(0, 84, 14)) + # changes minor break line
    coord_flip() +
    labs(y = "Score") +
    geom_hline(yintercept = c(groupDF$m), linetype = "dotted") +
    geom_segment(x = 2.38, xend = 2.38, y = groupDF$m[2] + .1, yend = groupDF$m[1] - .1, size = .7, 
                 arrow = arrow(end = "both", type = "open", length = unit(0.15, "cm")), colour = "#696969") +
    annotate("text", x = 2.46, y = mean(groupDF$m), label = paste0("italic(p) == ", 0.02), parse = T) +
    theme_bw() +
    theme(axis.title.y = element_blank(),
          axis.ticks.y = element_blank(),
          axis.text.y = element_blank(),
          axis.text.x = element_text(size = 13),
          axis.title.x = element_text(size = 13, face = "bold", 
                                      margin = margin(t = 0, r = 0, b = 10, l = 0), vjust = -2), 
          legend.title = element_blank(),
          legend.position = "top",

          ### added
          legend.spacing.x = unit(0.25, 'cm'),

          legend.spacing.y = unit(.1, "cm"),
          legend.box.spacing = unit(.1, "cm"), # adjusts distance of box from x-axis
          legend.key.size = unit(1, "cm"),
          legend.text = element_text(size = 13, face = "bold"),
          strip.text = element_text(size = 13, face = "bold"),
          panel.grid.major.y = element_blank(),
          panel.grid.major.x = element_line(size=.4, color="#F7F7F7"))

Created on 2019-03-11 by the reprex package (v0.2.1.9000)

Tung
  • 26,371
  • 7
  • 91
  • 115
  • @llewmills: `legend.spacing.x` will change the space between the box and the text within one legend key. Whereas, `str_pad()` will add more space between two or more legend keys – Tung Mar 12 '19 at 22:45
  • Thank you for clarifying @Tung. I will comment my script accordingly. – llewmills Mar 13 '19 at 02:08