thiagoveloso
thiagoveloso

Reputation: 2763

R - Generate a 2x2 panel with four plots created from list

I have a list with four data frames that I use to create plots in a lapply function. The plots are created individually, however I would like to organize them in a 2x2 panel like this sample:

enter image description here

This is the code I am using:

# create letters for legend
leg <- LETTERS[1:15]

# run function
l_ply(alldat, function(dat) {
    # first plot - ref data and one model
    taylor.diagram(dat[,2], dat[,3], pch=leg[1], col='black', pcex=1, normalize=T)

    # add remaining models
    for (i in 3:dim(dat)[2]) {
      model.wanted <- dat[,i]
      taylor.diagram(dat$CRU, model.wanted, add=T, col='black', pch=leg[i-2], pcex=1, normalize=T)
      }

  # add legend
  legend(x='top',
  legend=names(dat)[3:length(names(dat))],
  pch=leg, pt.cex=1,ncol=2)

})

Any directions on what I should do to achieve this? Should I save the plots in different objects and organize them after the lapply function?

Here is an excerpt of my data:

require(plotrix)
require(plyr)

cloud <- structure(list(date = structure(c(0, 31, 59, 90, 120, 151), class = "Date"), 
    CRU = c(67.6552579213225, 64.8199295882443, 67.6882136843717, 
    64.4932343486913, 62.0941221490892, 59.9333537425379), CanESM2 = c(66.972917385659, 
    71.4248852462099, 65.1381412601471, 67.1597958635029, 62.9675122718923, 
    65.6251207369531), `GFDL-ESM2M` = c(62.5805390942166, 62.8894567998808, 
    60.5108804320452, 64.7156850235086, 61.0681295548824, 64.5205937542971
    ), `GISS-E2-H` = c(61.6562727435151, 63.6979377938432, 61.934720028102, 
    62.9147267351652, 62.9400740659167, 64.0185837954248), `GISS-E2-R-CC` = c(63.0442187081722, 
    60.0853062955399, 60.9436761706614, 60.8772572772824, 61.7701362701327, 
    59.043906825997), `GISS-E2-R` = c(59.6711430384541, 62.8334974371481, 
    63.0131761539749, 61.7294481121309, 62.2555191908942, 61.5088982333356
    ), `HadGEM2-AO` = c(54.154605609548, 53.5172215357719, 54.4719170376292, 
    50.5503675739528, 51.8468629765371, 56.0233048048772), `HadGEM2-CC` = c(55.2767160056209, 
    55.4545621321912, 48.5067733614208, 49.7513141190709, 52.4741278958181, 
    49.7424716037677), `IPSL-CM5A-MR` = c(66.7466522042235, 63.6054491778145, 
    61.935661862022, 61.245452060337, 58.9980974818949, 60.1933125803763
    ), `IPSL-CM5B-LR` = c(61.5338846590087, 65.7333456200048, 
    67.3005378140901, 61.2494067126826, 62.0015259754588, 65.9300494528375
    ), MIROC4h = c(56.6392694529316, 56.7074476707051, 51.0562354028364, 
    51.0794469888308, 52.1698227633231, 54.4719042536529), `MRI-CGCM3` = c(63.6631087715584, 
    61.2187020278953, 59.3379579304255, 56.2363349944667, 56.8857660830788, 
    55.78558572393), `NorESM1-M` = c(65.0169360325908, 62.0288071442766, 
    57.6896775396247, 54.8514090107477, 55.3626083968536, 54.2549283168748
    ), `bcc-csm1-1-m` = c(56.3135573432878, 53.4686209116205, 
    56.6030430885226, 55.732017360598, 51.6051707954295, 53.9728077055279
    ), `bcc-csm1-1` = c(58.3639905689753, 59.9757869293257, 59.9353082093579, 
    58.3831427846875, 58.2989891237962, 61.5507059627109), inmcm4 = c(70.8259646403441, 
    69.1040767391383, 64.5515271993269, 64.6499744101575, 67.712215046297, 
    67.1942041779122)), .Names = c("date", "CRU", "CanESM2", 
"GFDL-ESM2M", "GISS-E2-H", "GISS-E2-R-CC", "GISS-E2-R", "HadGEM2-AO", 
"HadGEM2-CC", "IPSL-CM5A-MR", "IPSL-CM5B-LR", "MIROC4h", "MRI-CGCM3", 
"NorESM1-M", "bcc-csm1-1-m", "bcc-csm1-1", "inmcm4"), row.names = 1441:1446, class = "data.frame")

rhum <- structure(list(date = structure(c(0, 31, 59, 90, 120, 151), class = "Date"), 
    CRU = c(73.071142795189, 72.116517171492, 75.4633207613727, 
    74.9045111133869, 74.5648160247136, 75.5390179521703), CanESM2 = c(82.1738954084519, 
    84.2968531301844, 83.2241528402853, 82.4713266361527, 81.9882784900331, 
    82.2132649960434), `GFDL-ESM2M` = c(76.1144124999242, 75.513665275741, 
    73.7942696812278, 76.1981389223065, 77.0376873674448, 77.2976291681033
    ), `GISS-E2-H` = c(73.1633360881694, 73.7535375028465, 73.723200571049, 
    72.6744510703059, 72.5031851158365, 72.5837847137451), `GISS-E2-R-CC` = c(71.1623239923221, 
    71.5630121183116, 71.9035651911908, 71.8883493576273, 72.1201485964011, 
    71.100014834153), `GISS-E2-R` = c(72.9110190015648, 73.3857936309234, 
    72.300836242765, 73.3048428362573, 72.5734859763251, 73.6193392333092
    ), `HadGEM2-AO` = c(71.7564950985936, 72.6083887837505, 72.7375342461659, 
    72.740344318256, 71.66267194681, 73.9705993920042), `HadGEM2-CC` = c(71.7338096720155, 
    73.4017465092843, 72.2130968345954, 69.8187574099937, 71.6096575044331, 
    70.2428292344746), `IPSL-CM5A-MR` = c(78.288059507225, 77.7982102562531, 
    77.9391756146972, 77.3570118881806, 76.9254102912144, 78.1113354206643
    ), `IPSL-CM5B-LR` = c(75.3990921536942, 77.3814960362618, 
    77.868640870546, 75.6332361338431, 75.5473474519295, 76.3470846818623
    ), MIROC4h = c(79.4069241143388, 80.0844909618891, 79.6346667043229, 
    79.0549592401828, 78.8346751581159, 81.0161486809714), `MRI-CGCM3` = c(81.8501322783085, 
    81.2568695034897, 80.4855355377643, 78.7182931088007, 78.8133439352917, 
    79.2912475172121), `NorESM1-M` = c(78.3120701427348, 77.4754017090379, 
    78.7131021740562, 78.1530052865458, 77.5852423941183, 78.1157005267673
    ), `bcc-csm1-1-m` = c(70.2950344625551, 69.4160485183984, 
    71.8456119878669, 70.8761688262538, 69.9851922515958, 70.2416348498607
    ), `bcc-csm1-1` = c(70.8614835346512, 70.4910287544741, 71.8480513221339, 
    70.8844927347194, 68.8084697254917, 71.9636850577907), inmcm4 = c(78.5251270969012, 
    78.1160855633474, 77.6402386801424, 78.1458952445315, 80.520200454645, 
    81.1088210504097)), .Names = c("date", "CRU", "CanESM2", 
"GFDL-ESM2M", "GISS-E2-H", "GISS-E2-R-CC", "GISS-E2-R", "HadGEM2-AO", 
"HadGEM2-CC", "IPSL-CM5A-MR", "IPSL-CM5B-LR", "MIROC4h", "MRI-CGCM3", 
"NorESM1-M", "bcc-csm1-1-m", "bcc-csm1-1", "inmcm4"), row.names = 1441:1446, class = "data.frame")

prec <- structure(list(date = structure(c(0, 31, 59, 90, 120, 151), class = "Date"), 
    CRU = c(5.49765705623559, 4.77359806046721, 5.62158322758403, 
    4.67963243680965, 4.2224734968374, 3.36206455563072), CanESM2 = c(4.79841013514418e-05, 
    5.37084366300876e-05, 4.72436063370894e-05, 5.07240040760987e-05, 
    4.37060840171321e-05, 4.41549152620003e-05), `GFDL-ESM2M` = c(6.3110190671931e-05, 
    5.65601672228163e-05, 5.67905323120218e-05, 5.58747174119601e-05, 
    5.10299194571122e-05, 5.14087758533192e-05), `GISS-E2-H` = c(4.40334130183662e-05, 
    5.78179278927125e-05, 5.76373298150557e-05, 5.13821649194105e-05, 
    5.06616003234137e-05, 4.60405440060584e-05), `GISS-E2-R-CC` = c(4.61461863558762e-05, 
    4.68618486326754e-05, 4.74821135265079e-05, 4.96532111588744e-05, 
    4.66607892112438e-05, 4.53600483364368e-05), `GISS-E2-R` = c(4.2961224350566e-05, 
    4.73954128346998e-05, 4.55096010495126e-05, 4.86006751348426e-05, 
    4.62571152892935e-05, 4.80067136455394e-05), `HadGEM2-AO` = c(4.50663401267986e-05, 
    4.40587125943942e-05, 5.41502610411833e-05, 4.86846159373331e-05, 
    4.85895249255265e-05, 4.72307926738793e-05), `HadGEM2-CC` = c(4.95938421491449e-05, 
    5.13035752101009e-05, 3.91581380304816e-05, 4.72639322614053e-05, 
    4.97923195981998e-05, 4.55380785145821e-05), `IPSL-CM5A-MR` = c(4.53951482623454e-05, 
    4.92054317849646e-05, 4.50621633685784e-05, 4.64624592856241e-05, 
    4.61646753878609e-05, 4.31003875327151e-05), `IPSL-CM5B-LR` = c(4.17308168575824e-05, 
    5.44154765751375e-05, 6.03962372881687e-05, 4.75167315044657e-05, 
    4.53351027522876e-05, 4.82428198335856e-05), MIROC4h = c(5.41267226016149e-05, 
    5.48366948503037e-05, 3.91468390362469e-05, 4.19957443512316e-05, 
    4.23787540871146e-05, 4.59629308941648e-05), `MRI-CGCM3` = c(5.67073841622448e-05, 
    6.00310012922815e-05, 5.07071712055857e-05, 4.64848152199045e-05, 
    4.70707970739826e-05, 4.64690827108151e-05), `NorESM1-M` = c(5.75674811670015e-05, 
    4.47625188467447e-05, 4.30881349345795e-05, 4.36944636932066e-05, 
    3.76844750636054e-05, 4.15962233582706e-05), `bcc-csm1-1-m` = c(4.39661514721367e-05, 
    3.6267821524052e-05, 4.96688538581108e-05, 4.90777169791919e-05, 
    4.50199953206488e-05, 5.09378733154497e-05), `bcc-csm1-1` = c(4.36386251524885e-05, 
    4.26126923570228e-05, 4.66884100523015e-05, 4.91951448592167e-05, 
    4.72643404938543e-05, 4.92076636119263e-05), inmcm4 = c(4.7871848561418e-05, 
    4.65707714989636e-05, 4.22968050234147e-05, 4.66198387367896e-05, 
    4.72156627251913e-05, 4.97391754662504e-05)), .Names = c("date", 
"CRU", "CanESM2", "GFDL-ESM2M", "GISS-E2-H", "GISS-E2-R-CC", 
"GISS-E2-R", "HadGEM2-AO", "HadGEM2-CC", "IPSL-CM5A-MR", "IPSL-CM5B-LR", 
"MIROC4h", "MRI-CGCM3", "NorESM1-M", "bcc-csm1-1-m", "bcc-csm1-1", 
"inmcm4"), row.names = 1441:1446, class = "data.frame")

temp <- structure(list(date = structure(c(0, 31, 59, 90, 120, 151), class = "Date"), 
    CRU = c(296.434223174652, 296.551152609827, 295.79685902342, 
    295.167607530997, 293.372857798867, 292.000823511404), CanESM2 = c(294.090026903654, 
    294.048913615266, 293.927266376339, 292.923982638532, 291.957568370083, 
    290.557879524454), `GFDL-ESM2M` = c(294.587617285656, 295.170026368258, 
    294.699185428731, 293.39897071883, 291.958153620491, 290.823281496282
    ), `GISS-E2-H` = c(296.045575347365, 295.993069888109, 295.901643246656, 
    294.701849734658, 292.999441203513, 291.91942751522), `GISS-E2-R-CC` = c(295.225379535162, 
    295.585000105295, 295.330113525391, 294.238700231362, 292.708886065567, 
    291.756369528966), `GISS-E2-R` = c(294.794358359889, 295.510733017949, 
    295.185885248909, 294.214823331777, 292.880296472025, 291.535325179965
    ), `HadGEM2-AO` = c(294.945626152886, 295.335533520436, 294.719626134683, 
    294.040903554102, 292.615202968664, 291.228220812703), `HadGEM2-CC` = c(294.22197507981, 
    294.441414809199, 294.401702411495, 293.49032785516, 292.14932653059, 
    290.87190355089), `IPSL-CM5A-MR` = c(293.578417786715, 293.78668991892, 
    293.352080970452, 292.406195291441, 290.799876584059, 289.835797813371
    ), `IPSL-CM5B-LR` = c(294.73205410606, 295.119550463582, 
    294.817129682574, 293.711843713236, 292.056669504266, 290.864620461269
    ), MIROC4h = c(294.70635495013, 294.670434784471, 294.147371413917, 
    293.527049790767, 292.226820807206, 291.332287333528), `MRI-CGCM3` = c(294.933276968616, 
    294.879510125054, 294.846681027775, 293.857122733133, 292.572892091985, 
    290.789874549553), `NorESM1-M` = c(293.444156356722, 293.137026285093, 
    293.051839199847, 292.416654266893, 291.405479215209, 290.793948976394
    ), `bcc-csm1-1-m` = c(295.051305850737, 295.442825940227, 
    295.005397121139, 294.329125025342, 293.283857271964, 292.067603042335
    ), `bcc-csm1-1` = c(294.754791763038, 295.030755277935, 294.58344368204, 
    293.739068664194, 292.679743609512, 291.334636694479), inmcm4 = c(293.541987832945, 
    293.698833764506, 293.124162988495, 292.419409972074, 290.939433379592, 
    290.38564940157)), .Names = c("date", "CRU", "CanESM2", "GFDL-ESM2M", 
"GISS-E2-H", "GISS-E2-R-CC", "GISS-E2-R", "HadGEM2-AO", "HadGEM2-CC", 
"IPSL-CM5A-MR", "IPSL-CM5B-LR", "MIROC4h", "MRI-CGCM3", "NorESM1-M", 
"bcc-csm1-1-m", "bcc-csm1-1", "inmcm4"), row.names = 1441:1446, class = "data.frame")

# create list with data frames
alldat <- list(cloud, prec, rhum, temp)

Upvotes: 0

Views: 3286

Answers (1)

r2evans
r2evans

Reputation: 160447

There are several mechanisms for doing multi-plots using base graphics. ggplot2 and lattice have different methods; somebody else will need to help with that if you lean that way.

par(mfrow)

You can set an even grid of plots with (for example) par(mfrow=c(2,2)) to set a 2x2 grid of plots, plotting across the rows first. You can alternatively use par(mfcol=c(2,2)), the difference being plots fill columns first. Regardless, you run this command once, then run your l_ply above with four plots and it just goes to town.

The upside is that it's trivial to use. The downside is that all graphs are the same size. For instance, mapping it out with your key as above would not be feasible. You can always set per-grid margins, for example, but some other things are a little less flexible.

layout()

This is a great alternative, though it takes a little more setup. One of the biggest things it lets you do is different widths/heights as well as multi-column/row spans. Your key above would not be difficult. I'd probably set it up with something like:

mtx <- matrix(c(1, 2, 5,
                3, 4, 5), byrow=TRUE, nrow=2)
layout(mtx, heights=c(1,1), widths=c(3,3,2))
## optional, will need to re-run layout() and not do this for actual plots
layout.show(n=6)

The numbers are the order of plots, so you can see that your fifth (of five) plots is two cells tall. You can have empty (ignored) cells with a value of 0. All must be integers 0 or greater, no NAs, no skipped numbers.

In your example, you'd run this code before your l_ply, and after that was done you'd have one more plot to put together your key.

At the expense of a little more setup than par(mfrow), this is a great tool. One huge benefit I like is that I can have a legend/key like above without any doubt that my images will have identical dimensions (where one alternative is to play with par(mar) until you have enough room outside the figure region).

par(fig)

This actually lets you overlap plots. This can be very confusing. I'll leave it as a mention and encourage you to do research if you think you want to get crazy with plots. No, really, it's fun but can be very confusing.

Upvotes: 2

Related Questions