Controlling axis ticks and axis lines separately on R lattice xyplot

*爱你&永不变心* 提交于 2019-12-05 19:33:26

问题


How can I go about removing the box around an xyplot, while keeping the axis scale tick marks? In the spirit of Edward Tufte's minimalist data graphic aesthetic, these axis lines are "non-data ink," and can (should?) be "erased."

library(lattice)
my.df <- data.frame(x=-10:10)
my.df$y <- my.df$x^2
xyplot(y~x,data=my.df)

It seems that the trellis display parameters (e.g. axis.line$col) control both the axis lines and axis ticks together:

xyplot(y~x,data=my.df,
       par.settings=list(axis.line=list(col="transparent")))

...which is not the desired result, so it doesn't look like there's a simple way to turn off the lines while leaving the box.

The best I've been able to come up with is a brute-force hack, where I build the tick marks by hand using panel.segments:

at.x=pretty(c(-10,10))
at.y=pretty(c(0,100))
xyplot(y~x,data=my.df,
       par.settings=list(axis.line=list(col="transparent")),
       scales=list(x=list(at=at.x,labels=at.x),
       y=list(at=at.y,labels=at.y)),
       panel=function(...){
           panel.xyplot(...)
           panel.segments(x0=at.x,x1=at.x,y0=-4,y1=-2)
           panel.segments(x0=-11.5,x1=-11,y0=at.y,y1=at.y)
       }
       )

This is close to the desired result, but there's quite a bit of fiddling required to get the tick marks to be a reasonable length and offset a "nice" distance from the data points. These values won't translate from one graphic to the next. Plus, note that the axis labels are now padded too far from the tick marks. I'm sure there's a way to reduce that padding, but that would only make the code even uglier and less portable.

So how can one go about suppressing just the lines that make up the "box" around the plot area, while leaving the tick marks and axis labels intact? Bonus points if this approach could also be used to suppress some, but not all of the lines (e.g. leave the left and lower lines, but suppress the top and right lines).


回答1:


This is still a bit hacky, but at least you don't have to do any figuring by hand. It uses a combination of par.settings and a custom axis function that takes an argument line.col and temporarily changes the axis line color by a call to trellis.par.set:

EDIT (removed unnecessary changing of trellis settings)

xyplot(y~x,data=my.df, par.settings = list(axis.line = list(col = "transparent")),
  # Pass custom axis function to argument 'axis'
  axis = function(side, line.col = "black", ...) {
    # Only draw axes on the left and bottom
    if(side %in% c("left","bottom")) {
      # Call default axis drawing function
      axis.default(side = side, line.col = "black", ...)
    }
  }
)

At the moment, I chalk up why line.col = "black" is required in the arguments of the custom axis function to magic. My guess is that it has to do with argument matching with the ellipses (...). Perhaps I'll be wiser tomorrow and find the true reason.

This results in:




回答2:


The easiest thing to do is to use the custom axis function (axis). Just set lwd (line width) to zero and tick marks (lwd.ticks) to something else. It worked like a charm!

plot(NA,NA,type="n",xaxt="n", lwd=linewidth, xlim=c(1,24), xlab="", ylab="",ylim=c(-300,500))
axis(side = 4, tck = .05, **lwd=0, lwd.ticks=1**, line = 0, labels = NA, col= cols_border[1], col.axis = cols_black)
axis(side = 4, lwd = 0, line = -4.5, las = 1, cex.axis=axis_fontsize, col= cols_border[1], col.axis = cols_black)
mtext("Light deviations (lum/sec)",side=4, padj=-2.5, cex=title_fontsize, col="black")


来源:https://stackoverflow.com/questions/12901396/controlling-axis-ticks-and-axis-lines-separately-on-r-lattice-xyplot

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!