Stack Exchange
Horizontally multiple legend position ggplot2
I want to represent three factors (at 5, 2, and 3 levels). The DES factor is represented in the x-axis, while the temp is in fill (different color) and water is pattern.
I get a figure, but I don´t know how to independently position the two legends (the one for fill and the one for pattern). Here is the mwe:
library(ggplot2)
library(ggpubr)
library(tidyverse)
library(car)
library(multcomp)
library(palmerpenguins)
library(ggpattern)
library(multcompView)
library(egg)


dput(optdesign)
structure(list(DES = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 
4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 
5L, 5L, 5L, 5L, 5L), levels = c("B", "C", "F", "G", "H"), class = "factor"), 
    water = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 
    2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 
    1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 
    1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 
    2L, 2L, 2L, 2L, 2L), levels = c("1", "2"), class = "factor"), 
    temp = structure(c(1L, 1L, 2L, 2L, 3L, 3L, 1L, 1L, 2L, 2L, 
    3L, 3L, 1L, 1L, 2L, 2L, 3L, 3L, 1L, 1L, 2L, 2L, 3L, 3L, 1L, 
    1L, 2L, 2L, 3L, 3L, 1L, 1L, 2L, 2L, 3L, 3L, 1L, 1L, 2L, 2L, 
    3L, 3L, 1L, 1L, 2L, 2L, 3L, 3L, 1L, 1L, 2L, 2L, 3L, 3L, 1L, 
    1L, 2L, 2L, 3L, 3L), levels = c("1", "2", "3"), class = "factor"), 
    dummy = structure(c(1L, 1L, 2L, 2L, 3L, 3L, 4L, 4L, 5L, 5L, 
    6L, 6L, 1L, 1L, 2L, 2L, 3L, 3L, 4L, 4L, 5L, 5L, 6L, 6L, 1L, 
    1L, 2L, 2L, 3L, 3L, 4L, 4L, 5L, 5L, 6L, 6L, 1L, 1L, 2L, 2L, 
    3L, 3L, 4L, 4L, 5L, 5L, 6L, 6L, 1L, 1L, 2L, 2L, 3L, 3L, 4L, 
    4L, 5L, 5L, 6L, 6L), levels = c("1", "2", "3", "4", "5", 
    "6"), class = "factor"), PRY = c(10.1, 10.3, 11.5, 11.4, 
    11.71, 11.9, 11.85, 12.05, 13.25, 13.15, 13.46, 13.65, 7.1, 
    7.3, 8.5, 8.4, 8.71, 8.9, 8.85, 9.05, 10.25, 10.15, 10.46, 
    10.65, 16.1, 16.3, 17.5, 17.4, 17.71, 17.9, 17.85, 18.05, 
    19.25, 19.15, 19.46, 19.65, 14.1, 14.3, 15.5, 15.4, 15.71, 
    15.9, 15.85, 16.05, 17.25, 17.15, 17.46, 17.65, 5.1, 5.3, 
    6.5, 6.4, 6.71, 6.9, 6.85, 7.05, 8.25, 8.15, 8.46, 8.65), 
    CRY = c(8.1, 8.3, 9.5, 9.4, 9.71, 9.9, 9.85, 10.05, 11.25, 
    11.15, 11.46, 11.65, 5.1, 5.3, 6.5, 6.4, 6.71, 6.9, 6.85, 
    7.05, 8.25, 8.15, 8.46, 8.65, 14.1, 14.3, 15.5, 15.4, 15.71, 
    15.9, 15.85, 16.05, 17.25, 17.15, 17.46, 17.65, 12.1, 12.3, 
    13.5, 13.4, 13.71, 13.9, 13.85, 14.05, 15.25, 15.15, 15.46, 
    15.65, 3.1, 3.3, 4.5, 4.4, 4.71, 4.9, 4.85, 5.05, 6.25, 6.15, 
    6.46, 6.65), PCR = c(1.24691358024691, 1.24096385542169, 
    1.21052631578947, 1.21276595744681, 1.20597322348095, 1.2020202020202, 
    1.20304568527919, 1.19900497512438, 1.17777777777778, 1.17937219730942, 
    1.17452006980803, 1.17167381974249, 1.3921568627451, 1.37735849056604, 
    1.30769230769231, 1.3125, 1.29806259314456, 1.28985507246377, 
    1.29197080291971, 1.28368794326241, 1.24242424242424, 1.24539877300613, 
    1.23640661938534, 1.23121387283237, 1.14184397163121, 1.13986013986014, 
    1.12903225806452, 1.12987012987013, 1.12730744748568, 1.12578616352201, 
    1.12618296529968, 1.12461059190031, 1.11594202898551, 1.11661807580175, 
    1.11454753722795, 1.11331444759207, 1.16528925619835, 1.16260162601626, 
    1.14814814814815, 1.14925373134328, 1.14587892049599, 1.14388489208633, 
    1.14440433212996, 1.1423487544484, 1.13114754098361, 1.13201320132013, 
    1.12936610608021, 1.12779552715655, 1.64516129032258, 1.60606060606061, 
    1.44444444444444, 1.45454545454545, 1.42462845010616, 1.40816326530612, 
    1.41237113402062, 1.3960396039604, 1.32, 1.32520325203252, 
    1.30959752321981, 1.30075187969925)), row.names = c(NA, -60L
), class = c("tbl_df", "tbl", "data.frame"))

optdesign$DES<-factor(optdesign$DES)

optdesign$water<-factor(optdesign$water)

optdesign$temp<-factor(optdesign$temp)

optdesign_pry <- aov(PRY ~ DES * water * temp, data=optdesign)
summary(optdesign_pry)
optdesign_pry_Tukey <- TukeyHSD(optdesign_pry)
optdesign_pry_cld <- multcompLetters4(optdesign_pry, optdesign_pry_Tukey)
optdesign_pry_summary <- group_by(optdesign, DES, water, temp)%>%
  summarise(value=mean(PRY), sd=sd(PRY)) %>%
  arrange(desc(value))
optdesign_pry_summary
optdesign_pry_cld <- as.data.frame.list(optdesign_pry_cld $`DES:water:temp`)
optdesign_pry_summary$Tukey <- optdesign_pry_cld$Letters
optdesign_pry_summary

ggplot(optdesign_pry_summary, aes(x=DES, y=value, fill=temp, pattern=water))+
  geom_bar(stat="identity", position="dodge", color="black",alpha = 1, width=0.7)+
  geom_col_pattern(alpha=0.5, color="grey20",width=0.7, position="dodge")+
  scale_pattern_manual(name="Water content / %", values = c("1" = "none", "2" = "stripe"),labels = c("0", "47"))  +
  geom_errorbar(aes(ymax=value+sd, ymin=value-sd), position=position_dodge(0.7), width=0.25, color="black", alpha=0.5, show.legend = FALSE)+
  scale_fill_manual(name="Temperature (ºC)", values=c("#E69F00", "#56B4E9", "#009E73"),label=c("20", "30", "40"), guide = guide_legend(label.hjust = 0, override.aes = list(pattern = "none")))+
  geom_text(aes(label=Tukey, y = value + sd), vjust=-0.5, size = 6.5, color = "gray25",show.legend = FALSE, position = position_dodge(0.7))+
  geom_hline(yintercept = mean(optdesign_pry_summary$value, na.rm=TRUE),linetype='dotted', col = 'grey', linewidth=1)+
  theme_bw(base_size = 20) +
  theme(panel.grid.major=element_blank(), panel.grid.minor=element_blank(),axis.text=element_text(size=22), axis.title=element_text(size=22,face="bold"), legend.title=element_text(size=22, face="bold"),legend.text=element_text(size=20), axis.text.x=element_text(angle = 45, hjust = 1),legend.position = c(0.5, 0.85) )+ 
  labs(y = "R / %", x= "")+ 
  scale_y_continuous(expand = c(0, 0),limits=c(0, 30))
ggsave("optdesign_pry.png", width=16, height=10, units="in",dpi = 120) 


As shown in the figure, I want the legends to be horizontally aligned, so as not to disturb the plot. Moreover, I am also noting that the pattern is not visible in the pattern legend (the strip does not appear).


Inside the function theme(), you could used legend.position = "right" and check to see if that is your desired result. Else you have to use guide() and guide_legend() from ggplot2 to get the desired result

The thing is that I want them on top of the plot, parallel to de x-axis. Moreover, I just tried legend.position="top", legend.box = "horizontal" but it gives Error in seq.default(from, to, by) : invalid '(to - from)/by'.

I managed to obtain the horizontal position of the legend using in the theme() funcition legend.position=c(0.91,0.9), legend.box = "horizontal". However, I still don´t know how to get the strains in in the 47% water content legend (it is grey). It´s strange because in the RStudio viewer they appeared, but once I save the figure as png or pdf, it is not visible anymore.
