Adding text to a boxplot that does not have a numbered axes - r

I am interested in labeling my boxplot with the letter A in the top left corner, but because I have a categorical X axis comparing seasons (summer vs winter), I am unable to give coordinates for my added text. How do you add text to a boxplot with a categorical axis?
This is what I've tried, which doesn't work:
`boxplot(LogTHg~Season, data = HgSIS, xlab= "Season", ylab= "LogTHg", text ("topleft", "A"))'

Three points:
As Ben writes, you can add a legend with x="topleft". The inset parameter allows you to separate it from the top and left boundaries.
If you call boxplot() with a formula object that has a factor-like right hand side, then R will put the first boxplot over the horizontal coordinate 1, the second over 2 and so forth. Which still doesn't tell you what the exact coordinates of the top left corner of the plotting region are, but you can at least do a couple of things. Like putting labels above each separate boxplot.
Relatedly, you can use the xlim parameter for boxplot() to control the horizontal spacing. For instance, if you use xlim=c(0,3), then you know that you can put something at horizontal coordinate 0. And the same with ylim.

Related

How to expand horizontal date scale while keeping legend within plot w/ asymmetrical vertical expansion

I am using ggplot2 to make several area plots of time series. To my eye, the plots look better if the time series covers the entire x axis, the height of the highest area is about 5% - 10% below the top of the plot area, and the legend is situated in the lower right corner of the plot.
Let base.plot be a base plot that labels the x axis and formats its tick marks, adds NBER recession bars, and locates the legend in the lower right corner of the plot itself with:
base.plot <- base.plot + theme(
legend.justification = c(1,0),
legend.position = c(1,0),
legend.title = element_blank()
)
This seems to work fine with my line plots, but on the area plots the legend box sticks out to the right and below the plot itself. Instead, its lower right corner should be at the lower right corner of the plot area. How can I fix this?
To change the plot's extent relative to its axes, I tried using the expand argument to expand the plot horizontally and vertically. Documentation for this argument leaves something to be desired, to say the least:
expand
A numeric vector of length two giving multiplicative and additive expansion constants. These constants ensure that the data is placed some distance away from the axes. The defaults are c(0.05, 0) for continuous variables, and c(0, 0.6) for discrete variables.
Is it too much to ask for the formula so we can know what the multiplicative and additive constants actually do? Otherwise, how else can we know how to set them? The above description appears in the documentation for scale_x_date; is it too much to ask for some mention of the defaults for date variables?
Flying blind, thanks to the useless documentation, I tried the solution for continuous variables:
scale_x_date(expand = c(0,0)),
But this just scrunched up the plot towards the right of the chart. So where can I learn about using scale_x_date with the expand argument?
As for the vertical axis, scale_y_date(expand = c(0,0)) did bring the bottom of the area plots down to the x-axis. But the top is too high. Somewhere I saw that a modification to the scale_y_date code now allows four arguments, two for the lower bound and two for the upper one. I tried this too, but there's no discernible difference from the plot using only the two parameters.
So, how can I get the lowest area plot to sit on the x axis and the highest point to be about 0.5 in from the top?

R: Matching x-axis scales on upper and lower plot using layout with base graphics

I am trying to arrange 3 plots together. All 3 plots have the same y axis scale, but the third plot has a longer x axis than the other two. I would like to arrange the first two plots side by side in the first row and then place the third plot on the second row aligned to the right. Ideally I would like the third plot's x values to align with plot 2 for the full extent of plot 2 and then continue on below plot one. I have seen some other postings about using the layout function to reach this general configuration (Arrange plots in a layout which cannot be achieved by 'par(mfrow ='), but I haven't found anything on fine tuning the plots so that the scales match. Below is a crappy picture that should be able to get the general idea across.
I thought you could do this by using par("plt"), which returns the coordinates of the plot region as a fraction of the total figure region, to programmatically calculate how much horizontal space to allocate to the bottom plot. But even when using this method, manual adjustments are necessary. Here's what I've got for now.
First, set the plot margins to be a bit thinner than the default. Also, las=1 rotates the y-axis labels to be horizontal, and xaxs="i" (default is "r") sets automatic x-axis padding to zero. Instead, we'll set the amount of padding we want when we create the plots.
par(mar=c(3,3,0.5,0.5), las=1, xaxs="i")
Some fake data:
dat1=data.frame(x=seq(-5000,-2500,length=100), y=seq(-0.2,0.6,length=100))
dat2=data.frame(x=seq(-6000,-2500,length=100), y=seq(-0.2,0.6,length=100))
Create a layout matrix:
# Coordinates of plot region as a fraction of the total figure region
# Order c(x1, x2, y1, y2)
pdim = par("plt")
# Constant padding value for left and right ends of x-axis
pad = 0.04*diff(range(dat1$x))
# If total width of the two top plots is 2 units, then the width of the
# bottom right plot is:
p3w = diff(pdim[1:2]) * (diff(range(dat2$x)) + 2*pad)/(diff(range(dat1$x)) + 2*pad) +
2*(1-pdim[2]) + pdim[1]
# Create a layout matrix with 200 "slots"
n=200
# Adjustable parameter for fine tuning to get top and bottom plot lined up
nudge=2
# Number of slots needed for the bottom right plot
l = round(p3w/2 * n) - nudge
# Create layout matrix
layout(matrix(c(rep(1:2, each=0.5*n), rep(4:3,c(n - l, l))), nrow=2, byrow=TRUE))
Now create the graphs: The two calls to abline are just to show us whether the graphs' x-axes line up. If not, we'll change the nudge parameter and run the code again. Once we've got the layout we want, we can run all the code one final time without the calls to abline.
# Plot first two graphs
with(dat1, plot(x,y, xlim=range(dat1$x) + c(-pad,pad)))
with(dat1, plot(x,y, xlim=range(dat1$x) + c(-pad,pad)))
abline(v=-5000, xpd=TRUE, col="red")
# Lower right plot
plot(dat2, xaxt="n", xlim=range(dat2$x) + c(-pad,pad))
abline(v=-5000, xpd=TRUE, col="blue")
axis(1, at=seq(-6000,-2500,500))
Here's what we get with nudge=2. Note the plots are lined up, but this is also affected by the pixel size of the saved plot (for png files), and I adjusted the size to get the upper and lower plots exactly lined up.
I would have thought that casting all the quantities in ratios that are relative to the plot area (by using par("plt")) would have both ensured that the upper and lower plots lined up and that they would stay lined up regardless of the number of pixels in the final image. But I must be missing something about how base graphics work or perhaps I've messed up a calculation (or both). In any case, I hope this helps you get the plot layout you wanted.

Adding multiple categorical labels to a bar chart in R

Say I have some data on some experiment I conducted on Earth and on Wayne's World. There are control and treatment means:
means1<-c(1,2)
means2<-c(1.5,2.5)
data<-cbind(means1,means2)
rownames(data)=c('ctrl','treatment')
colnames(data)=c('Earth','Waynes World')
I would like to plot this data, so I do.
barplot(data,beside=T)
This generates paired control and treatment bars, separated by planet. Each pair of bars has an x axis label specifying what planet they are from. What I would like is a second set of x-axis labels underneath each bar that specifies ctrl or treatment. Bonus if you tilt this second set of labels, they don't overlap the first labels, and everything looks pretty.
I think something like this describes what you're after
bp<-barplot(data,beside=T, xaxt="n")
mtext(text=rownames(data)[row(bp)], at=bp, line=1, side=1)
mtext(text=colnames(data), at=colMeans(bp), line=2.2, side=1)

R Programming on Graphics

Suppose the following R code gives a multiple graph containing four graphs. There are enough spaces among the graphs. How to reduce the space between these graphs? Secondly, How to give axis name to only for the outer side i.e., from the first graph and second graph remove the x axis legend.
getOption("device")()
par(mfrow =c(2,2))
x<-seq(0.01,10,by=0.01)
plot(x,2*x)
plot(x,sin(x))
plot(x,cos(x))
plot(x,x^3)
Try using the margins argument in par(mar). The second plot x-axis is removed using the argument xlab="":
par(mfrow =c(2,2), mar=c(4,4,1,1))
x<-seq(0.01,10,by=0.01)
plot(x,2*x, xlab="") # here the label for the x axis is removed
plot(x,sin(x))
plot(x,cos(x))
plot(x,x^3)

setting mfg in a multi plot prevents drawin on margin

I'm trying to add common axes to a bunch of plots by putting them in the outer margin.
Plots are drawn first in a loop (not in the example) then I wanted to draw axes on the bottom of the two rows of plots.
But drawing the axis outside the plotting region is only possible without mfg being changed. How can I enable out-of-plot-drawing after changing mfg?
par(mfrow=c(2,2),
mar=c(1,1,0,0),
oma=c(3,0,0,0))
#Some plots
plot(function(x)x^2,from=-1,to=2, frame.plot=T,axes=F)
plot(function(x)x^3,from=-2,to=2, frame.plot=T,axes=F)
plot(rnorm(10), frame.plot=T,axes=F)
plot(1:10, frame.plot=T,axes=F)
# axis on last drawn plot (mfg=c(2,2)) - works
axis(side=1,line=0,outer=TRUE)
# set mfg to same value (mfg=c(2,2))
par(mfg=c(2,2))
# red axis is clipped to plot region, even with xpd?
axis(side=1,line=-.2,outer=FALSE,xpd=NA,col="red")
par(mfg=c(2,1))
axis(side=1,line=-.2,outer=FALSE,xpd=NA,col="red")
You can set :
par(xpd=NA)
to make sure that the axis is not clipped to the plotting region.

Resources