# resizing plot panels to fit data distribution

March 3, 2013
By

(This article was first published on metvurst, and kindly contributed to R-bloggers)

I am a big fan of lattice/latticeExtra. In fact, nearly all visualisations I have produced so far make use of this great package. The possibilities for customisation are endless and the amount of flexibility it provides is especially valuable for producing visualisations in batch mode/programatically.

Today I needed to visualise some precipitation data for a poster presentation of climate observations at Mt. Kilimanjaro. I wanted to show monthly precipitation observations in relation to long term mean monthly precipitation in order to show which months have been particularly wet or dry.
The important point here is that by combining two different visualisations of the same data, we need to make sure that we make these directly comparable. This means that the scales of the absolute rain amounts and the deviations need to be similar, so we can get an instant impression of the deviation in relation to the absolute amounts.

Here's what I've done with latticeExtra (using mock data):

First, we need some (semi-) random data.

## LOAD PACKAGE
library(latticeExtra, quietly = TRUE)

## CREATE MOCK DATA
# precipitation long term mean
pltmean <- 800
# precipitation long term standard deviation
pltsd <- 200
# precipitation observations
pobs <- rnorm(12, pltmean, pltsd)
# preceipitation deviation from long term mean
pdev <- rnorm(12, 0, 150)
# months
dates <- 1:12


Then we calculate the panel heights to be relative to the (precipitation) data distribution. This is crucial because we want the deviation data to be directly comparable to the observed values.

## CALCULATE RELATIVE PANEL HEIGHTS
y.abs <- max(abs(pobs))
y.dev <- range(pdev)[2] - range(pdev)[1]
yy.aspect <- y.dev/y.abs


Then, we create the bar charts as objects.

## COLOUR
clrs <- rev(brewer.pal(3, "RdBu"))

## CREATE THE PLOT OBJECTS
abs <- barchart(pobs ~ dates, horizontal = FALSE, strip = FALSE, origin = 0,
between = list(y = 0.3),
ylab = "Precipitation [mm]", xlab = "Months", col = clrs[1])

dev <- barchart(pdev ~ dates, horizontal = FALSE, origin = 0,
col = ifelse(pdev > 0, clrs[1], clrs[length(clrs)]))


Now, we combine the two plot objects into one and also create strips to be plotted at the top of each panel with labels providing some detail about the respective panel.

## COMBINE PLOT OBJECTS INTO ONE AND CREATE CUSTOM STRIPS FOR LABELLING
out <- c(abs, dev, x.same = TRUE, y.same = FALSE, layout = c(1,2))
out <- update(out, scales = list(y = list(rot = 0)),
strip = strip.custom(bg = "grey40",
par.strip.text = list(col = "white",
font = 2),
strip.names = FALSE, strip.levels = TRUE,
factor.levels = c("observed",
"deviation from long term monthly mean")))


As a final step, we re-size the panels according to the panel heights calculated earlier.

## RESIZE PANELS RELATIVE TO DATA DISTRIBUTION
out <- resizePanels(out, h = c(1,yy.aspect), w = 1)


And this is what the final product looks like.

## PRINT PLOT
print(out)


Note: I suggest you rerun this example a few times to see how the relative panel sizes change with the data distribution (which is randomly created during each run). This highlights the usefulness of such an approach for batch visualisations.

sessionInfo()

## R version 2.15.3 (2013-03-01)
## Platform: x86_64-pc-linux-gnu (64-bit)
##
## locale:
##  [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C
##  [3] LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8
##  [5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8
##  [7] LC_PAPER=C                 LC_NAME=C
## [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C
##
## attached base packages:
## [1] grid      parallel  stats     graphics  grDevices utils     datasets
## [8] methods   base
##
## other attached packages:
##  [1] gridBase_0.4-6      abind_1.4-0         fields_6.7
##  [4] spam_0.29-2         reshape_0.8.4       plyr_1.8
##  [7] latticeExtra_0.6-19 lattice_0.20-13     RColorBrewer_1.0-5
## [10] RWordPress_0.2-3    rgdal_0.8-5         raster_2.0-41
## [13] sp_1.0-5            knitr_1.1
##
## loaded via a namespace (and not attached):
## [1] digest_0.6.3   evaluate_0.4.3 formatR_0.7    markdown_0.5.4
## [5] RCurl_1.95-3   stringr_0.6.2  tools_2.15.3   XML_3.95-0
## [9] XMLRPC_0.2-5