*This post includes 1 update. In this post, I answer a question about how to adjust the offset for x and y axes in a simple R chart. The R script also shows how to make side by side comparison plots.
*

**Question**

*Andreas asked the question: *

* *

*“… right now I wonder about this: When doing a normal (not lattice) plot, xlim doesn’t really force the axis to start at 0*

*> x y plot(y~x, xlim=c(0,10),ylim=c(0,10))*

*there is still some kind of inner margin. Any idea how to remove it?”*

I had noticed that the plot() function offsets the x and y axes so that values can not overplot the axis lines. I just assumed that was the way R handled charts. Based on Andreas’s question, I decided to do a little search through R documentation to see if I could find a way to adjust the axes offset. This short post shows how I found the necessary parameter and shows a comparison of the same plot with and without the axes offsets.

**Documentation Search**

When I first started using R documentation, I found it intimidating, often giving me more options than I could possibly handle. In this case, however, it gave me exactly what I needed.

I typed **?par** in my R console and got a multipage listing of everything I could want to know about graphical parameters. Since I had a specific question, I scanned through the pars until I found ‘xaxs’, just what Andreas and I were looking for. Here’s part of the description':

“‘xaxs’ The style of axis interval calculation to be used for the

x-axis. Possible values are ‘”r”‘, ‘”i”‘, ‘”e”‘, ‘”s”‘,

‘”d”‘. The styles are generally controlled by the range of

data or ‘xlim’, if given. Style ‘”r”‘ (regular) first extends

the data range by 4 percent and then finds an axis with

pretty labels that fits within the range. Style ‘”i”‘

(internal) just finds an axis with pretty labels that fits

within the original data range.”

That’s it! We need to set ‘xaxs = “i” to get the axes to meet at 0. Let’s try it and see if it work.

**Plots With ‘xaxs=”r” and ‘xaxs = “i”**

Here’s a simple comparison chart that shows xaxs = “r” on left and xaxs = “i” on right.

It works just as advertised. Here’s the script.

# Here are two simple x and y vectors to be plotted

x <- c(0,1,2,3,4,5,6,7,8)

y <- c(0,1,2,3,4,5,6,7,8)

# Set layout() for side by side plots

layout(matrix(c(1,2), byrow=TRUE, ncol=2))

# xaxs = “r” adds 4% over specified limits

plot (y~x, xlim=c(0,10), ylim=c(0,10),

xaxs=”r”, yaxs = “r”, las = 1,

main = “Plot with ‘r’ axes placement”)

# The 4% expansion can be eliminated by specifying xaxs = “i” and yaxs = “i”

plot (y~x, xlim=c(0,10), ylim = c(0,10),

xaxs = “i”, yaxs = “i” , las = 1,

main = “Plot with ‘i’ axes placement”)

This small example demonstrates both the power of R and the quality of the documentation. While it can be overwhelming for beginners, it’s nice to know that R has both the capabilities and documentation to let me customize my charts as I like.

**Update 1**

Hadley asks in his comment: *“But why would you want to do that? It’s such a bad idea because your data points get squashed by the axes!”*

Good question. For me, I am used to looking at Excel charts that set the axes at the specified value (often 0), with no wiggle room. Let’s see how points along the x and y axis plot when we have them right up against the axis. Here’s our earlier chart with some 0 points added:

Hadley is right. The points that are right on the x and y axis limits are visible in the left chart (xaxs = “r”), however, they are almost completely hidden in the right chart (xaxs = “i”).

So what have we learned?

- R documentation is extensive, you can find what you need if you keep looking
- R default chart settings are well thought out
- Excel users may need to adjust our thinking about what an effective chart looks like

For data with actual zeroes, it is a bit of a problem, as pointed out above (removing the misleading line that extends the axis beyond zero helps). The ‘i’ option is FAR superior when you have data near zero but not zero. Visually, we all assume the axis crosses at zero unless told otherwise. If the left side was -100, fine, no problem. If the data are on a scale that starts with zero, any non-zero axis (like -4%) visually distorts the data to make it look more further from zero than the data are. Yes, we can reason it out if we pay attention but the point of graphs is to be as close as instantly clear as possible, or we would just use a table.

Pingback: Is it “..too hard” to change R plot defaults? Update 1 « Charts & Graphs

I think this dotplot clearly shows why the xaxs=”i” can be a good thing. In the example the reader otherwise – mistakenly – is led to believe more people answered disagree than is the case.

numbers <- matrix(c(73,28,1,0,65,35,3,1,54,36,11,3),ncol=3)

rækker <- c("Agree", "Somewhat agree", "Somewhat disagree", "disagree")

rownames(numbers) <- rækker

colnames(numbers) <- c("Var this", "Var that", "Var phat")

# we define the original par() so we are able to reset later

def.par <- par(no.readonly = TRUE)

# Laoyt change to 50 / 50

layout(matrix(c(1,2)), heights=c(5,5))

# xaxs=i

op <- par(xaxs="i")

dotchart(tal, xlim=c(0,100), cex=0.7, col=c(1,2,3,4), main="xaxs \"i\"")

# xaxs=r

op <- par(xaxs="r")

dotchart(tal, xlim=c(0,100), cex=0.7,col=c(1,2,3,4), main="xaxs default")

# reset par

par(def.par)

Pingback: Is it “..too hard” to change R plot defaults? « Charts & Graphs

I think the best way to do this is with a plot region beginning with -1, with an axis beginning at 1, drawn with a grey line. And with the “i” option.

Without the box

Agree somewhat with derek: The box sometimes obscures the viz (but the box is easy to remove I think). The good thing would be the choice to have the points layer above the axis, as derek suggest.

One could remedy the problem somewhat by using background color for points, something like:

pch=23, bg="RED", col="RED"

All this is important because people naturally think that 0 is actually 0 – not at some 4% margin.

That’s much better. See if you can persuade your fellow R users to abandon this silly bit of 1980s Clevelandiana. (though it’s not as bad as when the R *bar graphs* don’t start at zero!!)

Can you get the symbols to overlay the axes, instead of vice versa? Axes should not overlay symbols. Microsoft gets that much right, at least. (if you’re worried about clashing symbols and axes confusing people, then it’s time to arrange for axes to leave a little bit of white space in the region of the symbol)

Alternatively, if you really, really have to set the scales back, then they shouldn’t touch each other, either. Tufte is the better guide here.

(to be fair, it’s not the offset that’s the real villain, it’s Cleveland’s box around the whole thing. That’s what connects the scales together spuriously when they’re offset)

Incidentally, I can achieve every effect I’ve named here in Excel with ease. One of the things that lets R down is that when I point out the shortcomings of R standard functions to R users, they say “Oh, but it’s too hard to change the defaults!”

But why would you want to do that? It’s such a bad idea because your data points get squashed by the axes!

Thank you SO much for this paradigmatic walkthrough which I really appreciate. Altso I feel kind of studpid not being able to finde the help my self. Guess I quickly became intimidated…