3

By default, the cartesian axes in R are on the bottom and left side of a plot.
How do I center the axes, as shown in the picture below?

enter image description here

Example

## using; data; generated; by; bgoldst;;
## estimate curve
x <- seq(-1,1.5,0.1);
y <- c(1.3,1.32,1.33,1.32,1.25,1.1,0.7,0.5,0.4,0.38,0.4,0.41,0.42,0.43,0.44,0.4,0.3,0.1,0,-0.05,-0.1,-0.15,-0.2,-0.24,-0.28,-0.3);
f <- splinefun(x,y);

## calculate precise points along estimated curve
x <- seq(-1,1.5,0.01);
y <- f(x);
plot(x, y, type = 'l')

enter image description here

rawr
  • 20,481
  • 4
  • 44
  • 78
JACKY88
  • 3,391
  • 5
  • 32
  • 48
  • 2
    R doesn't like to make plots like this. You can turn off all the axes with `plot(..., axes=FALSE)` and then you can draw your own lines wher eever you want with `lines()` or `segments()` perhaps making them thicker with `lwd=`. It would be easier to answer if you actually provided a [reproducible example](http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) with some data to play with and the plotting package you intend to use if not base R. – MrFlick Jun 05 '15 at 04:09
  • actually you can do this easily with `axis(..., pos = 0)` if you really want the arrows, then the other answers can give you that `plot(x, y, xlim = c(-1.5, 1.5), ylim = c(-2, 2), axes = FALSE, ann = FALSE, type = 'n'); axis(1L, pos = 0, lwd.ticks = 0, labels = FALSE); axis(2L, pos = 0, lwd.ticks = 0, labels = FALSE); lines(x, y, col = 4L)` – rawr Oct 31 '17 at 16:59

2 Answers2

5

@ForrestRStevens was too quick for me, I was too busy trying to estimate your curve using a spline :)

## estimate curve
x <- seq(-1,1.5,0.1);
y <- c(1.3,1.32,1.33,1.32,1.25,1.1,0.7,0.5,0.4,0.38,0.4,0.41,0.42,0.43,0.44,0.4,0.3,0.1,0,-0.05,-0.1,-0.15,-0.2,-0.24,-0.28,-0.3);
f <- splinefun(x,y);

## calculate precise points along estimated curve
x <- seq(-1,1.5,0.01);
y <- f(x);

## precompute limits
xlim <- c(min(x),max(x));
ylim <- c(min(y)-0.4,max(y)+0.2);

## set global plot params
par(xaxs='i',yaxs='i',mar=c(1,1,3,3)+0.1); ## "internal" axis spacing, meaning no extended range, and slightly adjust margins

## draw plot
plot(NA,xlim=xlim,ylim=ylim,axes=F,ann=F); ## set plot bounds, no default ornaments
arrows(c(0,xlim[1]),c(ylim[1],0),c(0,xlim[2]),c(ylim[2],0),0.05); ## draw custom axes
mtext('y',3,1,at=0,las=1,cex=0.8,family='serif'); ## y label
mtext('x',4,1,at=0,las=1,cex=0.8,family='serif'); ## x label
lines(x,y,col='#aaaacc'); ## draw line on top

plot

In general, you can draw pretty much anything with base graphics, but it's often more involved than if you used more sophisticated packages, because you have to draw everything by hand.

bgoldst
  • 34,190
  • 6
  • 38
  • 64
4

I think something like the following does what you'd like in base graphics:

##  Simulate your data:
x <- seq(-3, 3, by=0.01)
y <- 0.5*x - 0.3*x^2 + 0.4*x^3

##  Plot the polynomial function, removing axis ticks and bounding box,
##    as well as the axis labels:
plot(x, y, 
     type="l", 
     xaxt='n', yaxt='n', 
     bty='n', 
     xlab='', ylab='', 
     col="blue")

##  Next add in your axis arrows:
arrows(min(x), 0, max(x), 0, lwd=1, length=0.15)
arrows(0, min(y), 0, max(y), lwd=1, length=0.15)

##  And plot your x/y labels.  Note that if you want them
##    actually at the end of the arrows you would need to 
##    remove the pos= argument and shorten your arrows by
##    a small amount.  To match your original figure, you can
##    alter the x/y coordinate to be the max() instead.
text(0, min(y), "y", pos=2)
text(min(x), 0, "x", pos=3)

Plot

Forrest R. Stevens
  • 3,435
  • 13
  • 21