1

I am trying to add a box around my legend but the position of the box and the height of it are off. Also the line itself does not look straight and the thicknesses change from wall to wall. Sample data and code are:

DATA:

> dput(head(Moment_all))
structure(list(UG = c("UG-100", "UG-100", "UG-100", "UG-100", 
"UG-100", "UG-100"), S = c(12, 12, 12, 12, 12, 12), N_l = c(1, 
1, 1, 1, 1, 1), Sample = c("Sample", "Sample", NA, NA, NA, NA
), EQ = structure(c(1L, 1L, 2L, 2L, 8L, 8L), .Label = c("CSI", 
"AASHTO LRFD", "Modified Henry's Method", "Suksawang & Nassif", 
"Shahawy & Huang", "Rigid Rotation Method", "Cai", "Tarhini & Fredrick", 
"Phuvoravan et al.", "Puckett et al."), class = "factor"), `Moment LLDF` = c(0.407938350905721, 
0.543950313716982, 0.511219095092085, 0.816666666666667, 4.87812701892219, 
4.87812701892219), Girder = c("Interior", "Exterior", "Interior", 
"Exterior", "Exterior", "Interior"), Loading = c("Single", "Single", 
"Single", "Single", "Single", "Single"), X = c("Interior Girder\nSingle-lane", 
"Exterior Girder\nSingle-lane", "Interior Girder\nSingle-lane", 
"Exterior Girder\nSingle-lane", "Exterior Girder\nSingle-lane", 
"Interior Girder\nSingle-lane"), facet = structure(c(3L, 3L, 
3L, 3L, 3L, 3L), .Label = c("UG-84", "UG-92", "UG-100", "UG-108", 
"UG-116", "UG-124"), class = "factor")), row.names = c(NA, -6L
), class = c("tbl_df", "tbl", "data.frame"))

CODE:

b <- ggplot(data = subset(Moment_all, EQ == "CSI"), 
   aes(x = X, y = `Moment LLDF`, fill = factor(S,levels = c("9","12","15")))) +  theme_classic() +
    geom_boxplot(outlier.shape = NA, position = position_dodge(width = 0.75),
             fatten = 1, lwd = 0.2) +
    stat_summary(fun = mean, geom="point", shape=23, size=0.5, stroke = 0.2,
             position = position_dodge(width = 0.75)) + 
    stat_boxplot(geom ='errorbar', linetype=1, width=0.5, lwd = 0.2, 
             position = position_dodge(width = 0.75)) +
    geom_point(data = subset(Moment_all, EQ == "AASHTO LRFD"), 
           aes(shape = EQ), stroke = 0.3, size = 1, position = position_dodge(width = 0.75)) +
    geom_point(data = subset(Moment_all, EQ == "Modified Henry's Method"), 
           aes(shape = EQ), stroke = 0.3, size = 1, position = position_dodge(width = 0.75)) +
    geom_point(data = subset(Moment_all, EQ == "Suksawang & Nassif"), 
           aes(shape = EQ), stroke = 0.3, size = 1, position = position_dodge(width = 0.75)) +
   geom_point(data = subset(Moment_all, EQ == "Cai"), 
           aes(shape = EQ), stroke = 0.3, size = 1, position = position_dodge(width = 0.75)) +
    geom_point(data = subset(Moment_all, EQ == "Rigid Rotation Method"), 
           aes(shape = EQ), stroke = 0.3, size = 1, position = position_dodge(width = 0.75)) +
    geom_point(data = subset(Moment_all, EQ == "Shahawy & Huang"), 
           aes(shape = EQ), stroke = 0.3, size = 1, position = position_dodge(width = 0.75)) +
  geom_vline(xintercept = 1.5, col='gray', lwd=0.2) +
  geom_vline(xintercept = 2.5, col='gray', lwd=0.2) +
  geom_vline(xintercept = 3.5, col='gray', lwd=0.2) +
  annotate("segment", x=-Inf, xend=Inf, y=-Inf, yend=-Inf, size = 0.35)+
  annotate("segment", x=-Inf, xend=-Inf, y=-Inf, yend=Inf, size = 0.35) +
  annotate("segment", x=Inf, xend=Inf, y=-Inf, yend=Inf, size = 0.35) +
  scale_shape_manual(values = c(0:4,6)) +
  labs(x = element_blank(), shape = element_blank(), 
       fill = "Analytical Data with \n Girder Spacing (ft) of:") +
    theme(legend.title.align = 0.5, legend.position = "bottom", 
      axis.text.y = element_text(size=8, colour="black"),
      axis.text.x = element_text(size=8, colour="black", angle=40, vjust=0.6),
      axis.title.y = element_text(size=8, colour="black", vjust=0.5, margin = margin(0,4,0,-6)),
      axis.line=element_blank(), 
      axis.ticks = element_line(colour = "black", size = 0.2),
      legend.text = element_text(size=8, margin = margin(0,5,0,0)),
      legend.title = element_text(size=8, margin = margin(0,2,0,0)),
      strip.text.x = element_text(size = 8), axis.ticks.x=element_blank(),
      strip.background = element_rect(color = "black", size = 0.4),
      legend.spacing.x = unit(0.1, 'cm'), legend.spacing.y = unit(0.1, 'cm'),
      legend.margin = margin(-3,5,-2.6,4, unit="mm"),
      legend.box.background = element_rect(color = "black")) +
  guides(fill = guide_legend(label.position = "bottom", label.hjust = 0.8, title.vjust = 0.8),
     shape = guide_legend(keywidth = unit(3, "mm"),keyheight = unit(3.5, "mm"))) +
  facet_wrap(vars(facet), ncol = 2)

The results that I save as a pngs are:

enter image description here

Maral Dorri
  • 468
  • 5
  • 17
  • 2
    how about replacing `legend.margin = margin(-3,5,-2.6,4, unit="mm")` (which gives you the ill-fitting box) with `legend.background = element_blank()` – user20650 Feb 28 '21 at 18:21
  • See relevant answer: https://stackoverflow.com/a/47669217/6851825 – Jon Spring Feb 28 '21 at 22:36

1 Answers1

1

Here's your output using the sample data:

enter image description here

There are two issues. First, legend.margin has negative parameters on the top and bottom, leading the box to be smaller than its contents. You probably want positive numbers for each. I picked legend.margin = margin(2,5,2,4, unit="mm") below, to add 2mm padding on top and bottom. (The parameters are in order of top, right, bottom, left.). [EDIT - I had accidentally shown wrong order]

enter image description here

Second, you have white sub-legend edges that are overlapping on your overall legend, creating uneven line thicknesses.

We can see this if we make the sub-legend outlines red:

    ....
    legend.margin = margin(5,2,5,2, unit="mm"),
    legend.background = element_rect(color = "red"),  ### SEE HERE ###
    legend.box.background = element_rect(color = "black")) +

enter image description here

Adapting from stackoverflow.com/a/47669217/6851825, we can fix this by making those sub-legend edges blank:

    ....
    legend.margin = margin(5,2,5,2, unit="mm"),
    legend.background = element_blank(),
    legend.box.background = element_rect(color = "black")) +

enter image description here

Jon Spring
  • 55,165
  • 4
  • 35
  • 53