расположить легенду с помощью gtable

Я сделал следующий сюжет, состоящий из нескольких сюжетов. Я очень доволен этим, но легенда начинается в середине нижней строки, и я хотел бы разместить ее левее.

введите здесь описание изображения

Однако я не могу найти, как это сделать. Вот так я разместил легенду под графиком.

# extract legend
leg1 <- g1$grobs[[which(g1$layout$name == "guide-box")]]
leg2 <- g2$grobs[[which(g2$layout$name == "guide-box")]]

g$grobs[[which(g$layout$name == "guide-box")]] <- 
  gtable:::cbind_gtable(leg1, leg2, "first")
grid.draw(g)

Большое спасибо за Вашу помощь!

ДАННЫЕ

out121<-structure(list(MEt_R = c(-0.0541818151603231, -0.0562844791428272, 
-0.0558715941992024, -0.0562399962945622, -0.0560460386125185, 
-0.0570608897132082, -0.0569943385875705, -0.0568252787782472, 
-0.0569942506473323, -0.0565197621205338, -0.056900534973487, 
-0.0571427349989937, -0.0569618449465491, -0.0566601716889117, 
-0.0563552308197707, -0.0568648464047371, -0.057047451157018, 
-0.0571837090302319, -0.0588902340655496, -0.0592472918164029
), MEp_R = c(-0.247452286142448, -0.250297111391169, -0.249928846077379, 
-0.25046029682347, -0.250073673565474, -0.250875645110485, -0.250823269975906, 
-0.250803625118812, -0.250975027824198, -0.250800205283021, -0.249498983660567, 
-0.249414312295583, -0.248700460230235, -0.247557861440942, -0.246180020784707, 
-0.245773209833456, -0.245867722008906, -0.245832189026612, -0.248451853542242, 
-0.248819121423065), MEt_Irr = c(-0.0930626749780042, -0.0924059309460578, 
-0.0924771937440385, -0.0905386156125412, -0.0914934037180768, 
-0.0898948119109486, -0.0898827200499507, -0.090372707751177, 
-0.0901901622784647, -0.0914484064620663, -0.0925147845884521, 
-0.0927733849042059, -0.0960873954367445, -0.0948131376144847, 
-0.0955133693827158, -0.0933133384990093, -0.0927340360155418, 
-0.0925138612415783, -0.0896139882242573, -0.0912014136494108
), MEp_Irr = c(-0.134285798811785, -0.130421729939034, -0.130843425161555, 
-0.125678194629783, -0.12773193697829, -0.124481076478246, -0.124497401309687, 
-0.125610694968169, -0.123946111674758, -0.123370795186237, -0.126287791384532, 
-0.126473323542922, -0.132539755897724, -0.132493992548119, -0.136001653508856, 
-0.134027790837091, -0.133453827739445, -0.133605798794612, -0.125624822911512, 
-0.12651195788011), se_MEt_Rainfed = c(0.124867384884912, 0.124157398945455, 
0.124169568385358, 0.124110270348855, 0.12391954965997, 0.123742628011372, 
0.123766054757713, 0.123576175335345, 0.12353428904291, 0.123443556846824, 
0.122869340273675, 0.122594726299249, 0.122332685310317, 0.12197210341919, 
0.121115745201095, 0.120880251090657, 0.120851770150267, 0.120746714650168, 
0.120922991632831, 0.120866928018865), se_MEp_Rainfed = c(0.143672836801446, 
0.144657376398904, 0.144507363687457, 0.144769378821498, 0.144648550573144, 
0.144872373777953, 0.145051397794363, 0.144915196543632, 0.144991517393619, 
0.144873626704144, 0.143989720401395, 0.143853417769885, 0.143333599218362, 
0.1427407217193, 0.142440215481916, 0.142160801176927, 0.142096501723151, 
0.14202065464998, 0.143129678943783, 0.143137620878338), se_MEt_Irrigation = c(0.0790595725119853, 
0.0819113174332981, 0.0818328749299557, 0.0834638025854297, 0.0818357384597404, 
0.0830466544695816, 0.0830677796154873, 0.0829941906461297, 0.083141965909444, 
0.082714324704666, 0.0809987066350066, 0.0810565659915952, 0.0792023249112186, 
0.0779277210970589, 0.0797106575341609, 0.0796897823245035, 0.0793238667046254, 
0.0794345101645159, 0.0805370559814554, 0.0816802765047257), 
    se_MEp_Irrigation = c(0.0739612622169091, 0.0737063705751054, 
    0.07367641793811, 0.0723914728669354, 0.0740776203174818, 
    0.069800467728211, 0.0696877344237401, 0.069931499405769, 
    0.0696836713882552, 0.0698379678577116, 0.0715460291976299, 
    0.0716115167234236, 0.0766235981234074, 0.0784897268021916, 
    0.083907652449956, 0.0837898365477357, 0.083360196343319, 
    0.0836313050243269, 0.0820421848807231, 0.0830267028200501
    ), Irrigationtotal = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0), Irrigation0 = c(0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), Irrigation10 = c(537, 
    532, 526, 524, 520, 517, 516, 511, 505, 500, 489, 482, 478, 
    471, 465, 463, 457, 455, 446, 439), Irrigation20 = c(384, 
    384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 384, 
    384, 384, 384, 384, 384, 384, 384), Irrigation30 = c(268, 
    268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, 
    268, 268, 268, 268, 268, 268, 268), Irrigation40 = c(272, 
    272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 272, 
    272, 272, 272, 272, 272, 272, 272), Irrigation50 = c(246, 
    246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 
    246, 246, 246, 246, 246, 246, 246), Irrigation60 = c(185, 
    185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 185, 
    185, 185, 185, 185, 185, 185, 185), Irrigation70 = c(194, 
    194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 
    194, 194, 194, 194, 194, 194, 194), Irrigation80 = c(184, 
    184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 184, 
    184, 184, 184, 184, 184, 184, 184), Irrigation90 = c(172, 
    172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 172, 
    172, 172, 172, 172, 172, 172, 172), Irrigation100 = c(1168, 
    1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 
    1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168, 1168), perc1 = 1:20, 
    perc = structure(1:20, .Label = c("1", "2", "3", "4", "5", 
    "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", 
    "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", 
    "27", "28", "29", "30", "31", "32", "33", "34", "35", "36", 
    "37", "38", "39", "40", "41", "42", "43", "44", "45", "46", 
    "47", "48", "49", "50", "51", "52", "53", "54", "55", "56", 
    "57", "58", "59", "60", "61", "62", "63", "64", "65", "66", 
    "67", "68", "69", "70", "71", "72", "73", "74", "75", "76", 
    "77", "78", "79", "80", "81", "82", "83", "84", "85", "86", 
    "87", "88", "89", "90", "91", "92", "93", "94", "95", "96", 
    "97", "98", "99", "100", "101", "102", "103", "104", "105", 
    "106", "107", "108", "109", "110", "111", "112", "113", "114", 
    "115", "116", "117", "118", "119", "120", "121", "122", "123", 
    "124", "125", "126", "127", "128", "129", "130", "131", "132", 
    "133", "134", "135", "136", "137", "138", "139", "140", "141", 
    "142", "143", "144", "145", "146", "147", "148", "149", "150", 
    "151", "152", "153", "154", "155", "156", "157", "158", "159", 
    "160", "161", "162", "163", "164", "165", "166", "167", "168", 
    "169", "170", "171", "172", "173", "174", "175", "176", "177", 
    "178", "179", "180", "181", "182", "183", "184", "185", "186", 
    "187", "188", "189", "190", "191", "192", "193", "194", "195", 
    "196", "197", "198", "199", "200", "201", "202", "203", "204", 
    "205", "206", "207", "208", "209", "210", "211", "212", "213", 
    "214", "215", "216", "217", "218", "219", "220", "221", "222", 
    "223", "224", "225", "226", "227", "228", "229", "230", "231", 
    "232", "233", "234", "235", "236", "237", "238", "239", "240", 
    "241", "242", "243", "244", "245", "246", "247", "248", "249", 
    "250", "251", "252", "253", "254", "255", "256", "257", "258", 
    "259", "260", "261", "262", "263", "264", "265", "266", "267", 
    "268", "269", "270", "271", "272", "273", "274", "275", "276", 
    "277", "278", "279", "280", "281", "282", "283", "284", "285", 
    "286", "287", "288", "289", "290", "291", "292", "293", "294", 
    "295", "296", "297", "298", "299", "300", "301", "302", "303", 
    "304", "305", "306", "307", "308", "309", "310", "311", "312", 
    "313", "314", "315", "316", "317", "318", "319", "320", "321", 
    "322", "323", "324", "325", "326", "327", "328", "329", "330", 
    "331", "332", "333", "334", "335", "336", "337", "338", "339", 
    "340", "341", "342", "343", "344", "345", "346", "347", "348", 
    "349", "350", "351", "352", "353", "354", "355", "356", "357", 
    "358", "359", "360", "361", "362", "363", "364", "365", "366", 
    "367", "368", "369", "370", "371", "372", "373", "374", "375", 
    "376", "377", "378", "379", "380", "381", "382", "383", "384", 
    "385", "386", "387", "388", "389", "390", "391", "392", "393", 
    "394", "395", "396", "397", "398", "399", "400", "401", "402", 
    "403", "404", "405", "406", "407", "408", "409", "410", "411", 
    "412", "413", "414", "415", "416", "417", "418", "419", "420", 
    "421", "422", "423", "424", "425", "426", "427", "428", "429", 
    "430", "431", "432", "433", "434", "435", "436", "437", "438", 
    "439", "440", "441", "442", "443", "444", "445", "446", "447", 
    "448", "449", "450", "451", "452", "453", "454", "455", "456", 
    "457", "458", "459", "460", "461", "462", "463", "464", "465", 
    "466", "467", "468", "469", "470", "471", "472", "473", "474", 
    "475", "476", "477", "478", "479", "480", "481", "482", "483", 
    "484", "485", "486", "487", "488", "489", "490", "491", "492", 
    "493", "494", "495", "496", "497", "498", "499", "500", "501", 
    "502", "503", "504", "505", "506", "507", "508", "509", "510", 
    "511", "512", "513", "514", "515", "516", "517", "518", "519", 
    "520", "521", "522", "523", "524", "525", "526", "527", "528", 
    "529", "530", "531", "532", "533", "534", "535", "536", "537", 
    "538", "539", "540", "541", "542", "543", "544", "545", "546", 
    "547", "548", "549", "550", "551", "552", "553", "554", "555", 
    "556", "557", "558", "559", "560", "561", "562", "563", "564", 
    "565", "566", "567", "568", "569", "570", "571", "572", "573", 
    "574", "575", "576", "577", "578", "579", "580", "581", "582", 
    "583", "584", "585", "586", "587", "588", "589", "590", "591", 
    "592", "593", "594", "595", "596", "597", "598", "599", "600", 
    "601", "602", "603", "604", "605", "606", "607", "608", "609", 
    "610", "611", "612", "613", "614", "615", "616", "617", "618", 
    "619", "620", "621", "622", "623", "624", "625", "626", "627", 
    "628", "629", "630", "631", "632", "633", "634", "635", "636", 
    "637", "638", "639", "640", "641", "642", "643", "644", "645", 
    "646", "647", "648", "649", "650", "651", "652", "653", "654", 
    "655", "656", "657", "658", "659", "660", "661", "662", "663", 
    "664", "665", "666", "667", "668", "669", "670", "671", "672", 
    "673", "674", "675", "676", "677", "678", "679", "680", "681", 
    "682", "683", "684", "685", "686", "687", "688", "689", "690", 
    "691", "692", "693", "694", "695", "696", "697", "698", "699", 
    "700", "701", "702", "703", "704", "705", "706", "707", "708", 
    "709", "710", "711", "712", "713", "714", "715", "716", "717", 
    "718", "719", "720", "721", "722", "723", "724", "725", "726", 
    "727", "728", "729", "730", "731", "732", "733", "734", "735", 
    "736", "737", "738", "739", "740", "741", "742", "743", "744", 
    "745", "746", "747", "748", "749", "750", "751", "752", "753", 
    "754", "755", "756", "757", "758", "759", "760", "761", "762", 
    "763", "764", "765", "766", "767", "768", "769", "770", "771", 
    "772", "773", "774", "775", "776", "777", "778", "779", "780", 
    "781", "782", "783", "784", "785", "786", "787", "788", "789", 
    "790", "791", "792", "793", "794", "795", "796", "797", "798", 
    "799", "800", "801", "802", "803", "804", "805", "806", "807", 
    "808", "809", "810", "811", "812", "813", "814", "815", "816", 
    "817", "818", "819", "820", "821", "822", "823", "824", "825", 
    "826", "827", "828", "829", "830", "831", "832", "833", "834", 
    "835", "836", "837", "838", "839", "840", "841", "842", "843", 
    "844", "845", "846", "847", "848", "849", "850", "851", "852", 
    "853", "854", "855", "856", "857", "858", "859", "860", "861", 
    "862", "863", "864", "865", "866", "867", "868", "869", "870", 
    "871", "872", "873", "874", "875", "876", "877", "878", "879", 
    "880", "881", "882", "883", "884", "885", "886", "887", "888", 
    "889", "890", "891", "892", "893", "894", "895", "896", "897", 
    "898", "899", "900", "901", "902", "903", "904", "905", "906", 
    "907", "908", "909", "910", "911", "912", "913", "914", "915", 
    "916", "917", "918", "919", "920", "921", "922", "923", "924", 
    "925", "926", "927", "928", "929", "930", "931", "932", "933", 
    "934", "935", "936", "937", "938", "939", "940", "941", "942", 
    "943", "944", "945", "946", "947", "948", "949", "950", "951", 
    "952", "953", "954", "955", "956", "957", "958", "959", "960", 
    "961", "962", "963", "964", "965", "966", "967", "968", "969", 
    "970", "971", "972", "973", "974", "975", "976", "977", "978", 
    "979", "980", "981", "982", "983", "984", "985", "986", "987", 
    "988", "989", "990", "991", "992", "993", "994", "995", "996", 
    "997", "998", "999"), class = "factor")), .Names = c("MEt_R", 
"MEp_R", "MEt_Irr", "MEp_Irr", "se_MEt_Rainfed", "se_MEp_Rainfed", 
"se_MEt_Irrigation", "se_MEp_Irrigation", "Irrigationtotal", 
"Irrigation0", "Irrigation10", "Irrigation20", "Irrigation30", 
"Irrigation40", "Irrigation50", "Irrigation60", "Irrigation70", 
"Irrigation80", "Irrigation90", "Irrigation100", "perc1", "perc"
), row.names = c(NA, 20L), class = "data.frame")

Код для создания графика

library(ggplot2)
library(gtable)
library(reshape2)

# line plot
out121$perc1<-c(1:999)
l64<-ggplot(out121,aes(perc1))
l65<-l64+geom_line(aes(y=MEt_R,colour="Rainfed"),size=1.3)+
  geom_line(aes(y=MEt_R+se_MEt_Rainfed,colour="Rainfed range"),size=0.7)+
  geom_line(aes(y=MEt_R-se_MEt_Rainfed,colour="Rainfed range"),size=0.7)+
  geom_line(aes(y=MEt_Irr,colour="Irrigation"),size=1.3)+
  geom_line(aes(y=MEt_Irr+se_MEt_Irrigation,colour="Irrigation range"),size=0.7)+
  geom_line(aes(y=MEt_Irr-se_MEt_Irrigation,colour="Irrigation range"),size=0.7)+
  scale_colour_manual(values=c("blue3","mediumslateblue","green3","green"), name="")+
  scale_x_discrete(name="Threshold irrigation (in percentage)",breaks=c(0, 250, 500,750,1000),
                   labels=c("0", "25", "50","75","100")) +
  scale_y_continuous(name="MEt",limits = c(-0.7, 0.5),breaks=c(-0.3,-0.1,0,0.1,0.3,0.5))

l66<-l65+ theme_bw()+ggtitle("subsidies 1 large") + 
  theme(plot.title = element_text(lineheight=.8, face="bold"),legend.position="bottom")+
  guides(col=guide_legend(ncol=2))+
  theme(panel.background = element_rect(fill = NA),
        panel.grid.major = element_blank(), 
        panel.grid.minor = element_blank())
l66


# bar plot

test  <- data.frame(out121$perc,out121$Irrigation10,out121$Irrigation20,out121$Irrigation30,out121$Irrigation40,
                    out121$Irrigation50,out121$Irrigation60,out121$Irrigation70,out121$Irrigation80,
                    out121$Irrigation90,out121$Irrigation100)

# barplot(as.matrix(test))
library(reshape2)
foo.long<-melt(test)

foo.long$out121.perc<- as.character(foo.long$out121.perc)
foo.long$out121.perc <- factor(foo.long$out121.perc, levels=unique(foo.long$out121.perc))

cbbPalette <- c("yellow","greenyellow","#00FF00", "#00C639","#00AA55", "#00718E", "#0055AA", "#001CE3","blue4","midnightblue")

l2<-ggplot(foo.long, aes(out121.perc,value,fill=variable))+
  geom_bar(position="stack",stat="identity")+
  scale_fill_manual(values=cbbPalette,name = "% of irrigation",
                    labels = c("0-10% irrigation", "10-20% irrigation", "20-30% irrigation", 
                               "30-40% irrigation", "40-50% irrigation", "50-60% irrigation",
                               "60-70% irrigation", "70-80% irrigation", "80-90% irrigation",
                               "90-100% irrigation"))+
scale_x_discrete(name="Threshold irrigation (in percentage)",breaks=c(0, 250, 500,750,1000),
                 labels=c("0", "25", "50","75","100")) +
  scale_y_continuous(name="number of farms",limits = c(0, 10000), breaks=c(0, 1000,2000,3000, 4000))+
  theme(legend.position=c(0.7,0.4),panel.background = element_rect(fill = NA),
        panel.grid.major = element_blank(), 
        panel.grid.minor = element_blank())+
  guides(fill=guide_legend(title="Number of irrigated farms",ncol=3))

l2

# ggplotGrob

g1 <- ggplotGrob(l2)
g2 <- ggplotGrob(l66)


# Add plots together
pp <- c(subset(g2$layout, name == "panel", se = t:r))
g <- gtable_add_grob(g2, g1$grobs[[which(g1$layout$name == "panel")]], pp$t, 
                     pp$l, pp$b, pp$l)

# Add second axis for accuracy
ia <- which(g1$layout$name == "axis-l")
ga <- g1$grobs[[ia]]
ax <- ga$children[[2]]
ax$widths <- rev(ax$widths)
ax$grobs <- rev(ax$grobs)
ax$grobs[[1]]$x <- ax$grobs[[1]]$x - unit(1, "npc") + unit(0.15, "cm")
g <- gtable_add_cols(g, g1$widths[g1$layout[ia, ]$l], length(g$widths) - 1)
g <- gtable_add_grob(g, ax, pp$t, length(g$widths) - 1, pp$b)


# Add second y-axis title 
ia <- which(g1$layout$name == "ylab")
ax <- g1$grobs[[ia]]
# str(ax) # you can change features (size, colour etc for these - 
# change rotation below 
ax$rot <- 270
g <- gtable_add_cols(g, g1$widths[g1$layout[ia, ]$l], length(g$widths) - 1)
g <- gtable_add_grob(g, ax, pp$t, length(g$widths) - 1, pp$b)


# extract legend
leg1 <- g1$grobs[[which(g1$layout$name == "guide-box")]]
leg2 <- g2$grobs[[which(g2$layout$name == "guide-box")]]

g$grobs[[which(g$layout$name == "guide-box")]] <- 
  gtable:::cbind_gtable(leg1, leg2, "first")
grid.draw(g)

person user33125    schedule 27.02.2016    source источник
comment
Вы должны предоставить какой-то воспроизводимый пример. Очень трудно угадать, что может быть в переменных, на которые вы здесь ссылаетесь. Нам не нужны ваши фактические данные или сложный код форматирования, достаточно чего-то простого, с чем мы можем протестировать.   -  person MrFlick    schedule 27.02.2016
comment
Нет проблем, сейчас добавлю!   -  person user33125    schedule 27.02.2016
comment
Я добавил образец данных + полный код, который я использовал для построения графика   -  person user33125    schedule 27.02.2016


Ответы (1)


Вы были близки. Я думаю, ваша проблема в том, что вы позиционируете легенду во втором сюжете, и это позиционирование распространяется на объединенную легенду, тем самым искажая ее. Кроме того, заголовок легенды должен располагаться сверху, а объединенная легенда требует немного больше места. Ваш первый сюжет в порядке. Вывод из вашего второго сюжета:

# Making adjustments to legend: adjusting position and title position
l2 <- ggplot(foo.long, aes(out121.perc,value,fill=variable))+
  geom_bar(position="stack",stat="identity")+
  scale_fill_manual(values=cbbPalette,name = "% of irrigation",
                    labels = c("0-10% irrigation", "10-20% irrigation", "20-30% irrigation", 
                               "30-40% irrigation", "40-50% irrigation", "50-60% irrigation",
                               "60-70% irrigation", "70-80% irrigation", "80-90% irrigation",
                               "90-100% irrigation"))+
scale_x_discrete(name="Threshold irrigation (in percentage)",breaks=c(0, 250, 500,750,1000),
                 labels=c("0", "25", "50","75","100")) +
  scale_y_continuous(name="number of farms",limits = c(0, 10000), breaks=c(0, 1000,2000,3000, 4000))+
  theme(legend.position="bottom", panel.background = element_rect(fill = NA),
        panel.grid.major = element_blank(), 
        panel.grid.minor = element_blank())+
  guides(fill=guide_legend(title="Number of irrigated farms",ncol=3, title.position = "top"))

l2

# ggplotGrob

g1 <- ggplotGrob(l2)
g2 <- ggplotGrob(l66)


# Add plots together
pp <- c(subset(g2$layout, name == "panel", se = t:r))
g <- gtable_add_grob(g2, g1$grobs[[which(g1$layout$name == "panel")]], pp$t, 
                     pp$l, pp$b, pp$l)

# Add second axis for accuracy
ia <- which(g1$layout$name == "axis-l")
ga <- g1$grobs[[ia]]
ax <- ga$children[[2]]
ax$widths <- rev(ax$widths)
ax$grobs <- rev(ax$grobs)
ax$grobs[[1]]$x <- ax$grobs[[1]]$x - unit(1, "npc") + unit(0.15, "cm")
g <- gtable_add_cols(g, g1$widths[g1$layout[ia, ]$l], length(g$widths) - 1)
g <- gtable_add_grob(g, ax, pp$t, length(g$widths) - 1, pp$b)


# Add second y-axis title 
ia <- which(g1$layout$name == "ylab")
ax <- g1$grobs[[ia]]
# str(ax) # you can change features (size, colour etc for these - 
# change rotation below 
ax$rot <- 270
g <- gtable_add_cols(g, g1$widths[g1$layout[ia, ]$l], length(g$widths) - 1)
g <- gtable_add_grob(g, ax, pp$t, length(g$widths) - 1, pp$b)


# extract legend
leg1 <- g1$grobs[[which(g1$layout$name == "guide-box")]]
leg2 <- g2$grobs[[which(g2$layout$name == "guide-box")]]

legc = gtable:::cbind_gtable(leg1, leg2, "first")


g$grobs[[which(g$layout$name == "guide-box")]] <- 
  gtable:::cbind_gtable(leg1, leg2, "first")
grid.draw(g)  # Note: Legend does not fit

g$heights[[6]] = unit(5, "cm")   # Add more space for the legend - can adjust this to suit
grid.draw(g)
person Sandy Muspratt    schedule 27.02.2016
comment
Большое спасибо! Думаю, я бы не нашел его сам. Я очень ценю ваш ответ! - person user33125; 28.02.2016