Reputation: 143
I wonder how we can plot sub-labels on each plot and then have them side by side without space between subplots.
For example,
iris$petal.range <- findInterval(iris$Petal.Width, c(0, 0.75, 1.5))
iris$BigSpecies <- "type 2"
iris$BigSpecies[iris$Species == "versicolor"] <- "type 1"
mycolors <- ifelse(levels(iris$Species) == "setosa", "grey",
ifelse(levels(iris$Species) == "versicolor", "pink", "skyblue"))
par(mfrow = c(1,3))
boxplot(Petal.Length ~ Species, data = iris[iris$petal.range == 1,],
main = "petal.range = 1", xlab = "x", ylab = "y",
col = mycolors)
boxplot(Petal.Length ~ Species, data = iris[iris$petal.range == 2,],
main = "petal.range = 2", xlab = "x", ylab = "y",
col = mycolors)
boxplot(Petal.Length ~ Species, data = iris[iris$petal.range == 3,],
main = "petal.range = 3", xlab = "x", ylab = "y",
col = mycolors)
I would like my plot to look similar to this
The labels in the plot above are "Subject 2", "Subject 5", "Subject 4". The sub-labels are "LocLm" and "LocGP". The labels in my example will be petal.range: "petal.range = 1", "petal.range = 2", "petal.range = 3". The sub-labels will be BigSpecies: "type = 1", and "type = 2".
Upvotes: 0
Views: 296
Reputation: 160952
(This is a journey.)
The first attempt will use par("mar")
to set the margins. Note that I'm starting with the default margins of c(5, 4, 4, 2) + 0.1
; if you are using something else, make sure you change the mar
vector appropriately.
par(mfrow = c(1,3))
mar <- c(5, 4, 4, 2) + 0.2
par(mar = c(5.1, mar[2], mar[3], 0))
boxplot(Petal.Length ~ Species, data = iris[iris$petal.range == 1,],
main = "petal.range = 1", xlab = "x", ylab = "y",
col = mycolors)
par(mar = c(mar[1], 0, mar[3], 0))
boxplot(Petal.Length ~ Species, data = iris[iris$petal.range == 2,],
main = "petal.range = 2", xlab = "x", ylab = "y",
col = mycolors)
par(mar = c(mar[1], 0, mar[3], mar[4]))
boxplot(Petal.Length ~ Species, data = iris[iris$petal.range == 3,],
main = "petal.range = 3", xlab = "x", ylab = "y",
col = mycolors)
Problems: we have y-axes where we don't want them. Note that we also have the problem of unequal y ranges/limits, but I wanted to skip that for a moment to demonstrate the hazard of blindly removing the axis without safeguards.
Okay, here's remove the y-axes with yaxt="n"
:
par(mfrow = c(1,3))
mar <- c(5, 4, 4, 2) + 0.2
par(mar = c(5.1, mar[2], mar[3], 0))
boxplot(Petal.Length ~ Species, data = iris[iris$petal.range == 1,],
main = "petal.range = 1", xlab = "x", ylab = "y",
col = mycolors)
par(mar = c(mar[1], 0, mar[3], 0))
boxplot(Petal.Length ~ Species, data = iris[iris$petal.range == 2,],
main = "petal.range = 2", xlab = "x", ylab = "y",
col = mycolors, yaxt = "n")
par(mar = c(mar[1], 0, mar[3], mar[4]))
boxplot(Petal.Length ~ Species, data = iris[iris$petal.range == 3,],
main = "petal.range = 3", xlab = "x", ylab = "y",
col = mycolors, yaxt = "n")
This looks better, but it would be easy (natural) to assume that all of the boxplots are on the same y values, which they certainly are not. Let's add ylim=
to each based on the overall range.
ylim <- range(iris$Petal.Length)
par(mfrow = c(1,3))
mar <- c(5, 4, 4, 2) + 0.2
par(mar = c(5.1, mar[2], mar[3], 0))
boxplot(Petal.Length ~ Species, data = iris[iris$petal.range == 1,],
main = "petal.range = 1", xlab = "x", ylab = "y",
col = mycolors, ylim = ylim)
par(mar = c(mar[1], 0, mar[3], 0))
boxplot(Petal.Length ~ Species, data = iris[iris$petal.range == 2,],
main = "petal.range = 2", xlab = "x", ylab = "y",
col = mycolors, ylim = ylim, yaxt = "n")
par(mar = c(mar[1], 0, mar[3], mar[4]))
boxplot(Petal.Length ~ Species, data = iris[iris$petal.range == 3,],
main = "petal.range = 3", xlab = "x", ylab = "y",
col = mycolors, ylim = ylim, yaxt = "n")
Unfortunately, the widths of each panel are different. This is natural, frankly, as we really need to go through some (non-trivial) calcs to determine a priori how wide (in pixels) everything is going to be with the y-axis markings and without.
Fortunately, there are packages to help with this, and one good mechanism to use is called faceting. I recommend this option:
library(ggplot2)
ggplot(iris, aes(Species, Petal.Length)) +
facet_wrap(~ petal.range, nrow = 1) +
geom_boxplot(aes(fill = Species))
Upvotes: 2