将'mar'图形参数传递给绘图函数

4
我对于在plot函数中指定mar图形参数不起作用这一事实感到困惑。以下代码将会给你呈现出两个完全相同的图形:
plot(1:10, 10:1, xlab = "x", ylab = "y", mar = c(10, 0, 0, 0))
plot(1:10, 10:1, xlab = "x", ylab = "y", mar = c(0, 0, 0, 0))

然而,如果我尝试指定其他图形参数,例如下面例子中的col.lab,它会按预期工作。下面的内容将给出具有不同标签颜色的图:

plot(1:10, 10:1, xlab = "x", ylab = "y", col.lab = "red")
plot(1:10, 10:1, xlab = "x", ylab = "y", col.lab = "black")

令人困惑的是,将mar图形参数指定在函数外部可以正常工作,如下所示:

par.default <- par()
par(mar = c(10, 0, 0, 0))
plot(1:10, 10:1, xlab = "x", ylab = "y")
par(par.default)

有没有办法解决这种(在我看来)意外的行为?


1
这是一个公平的问题,也许它反映了图形等方面在几十年中的螺旋式发展。对我来说,这种行为表明选项传递的一些不一致性。我找不到一个简单的答案来解释为什么ProcessInlinePars没有正确映射它,所以我怀疑任何解决方案都需要修复R的深层内部,我不知道。修复?使用par(mar=...)或编写一个包装函数,检查...参数与names(par())进行显式处理。(未经测试!) - r2evans
1个回答

6

R中使用了三种不同类型的图形参数:

  • 普通类型(在底层C代码中表示为ptype 0)。
  • 非内联类型(ptype 1),意味着用户可以通过par设置,但不能通过高级函数进行内联设置。
  • 只读类型(ptype 2),用户无法设置,但会根据图形设备进行固定设置。

mar是非内联类型的参数。如果您阅读?par文档的详细信息部分,将列出所有其他图形参数,这些参数不能在高级绘图函数调用中设置,即所有非内联参数:

几个参数只能通过调用par()来设置:
- "ask", - "fig"、"fin", - "lheight", - "mai"、"mar"、"mex"、"mfcol"、"mfrow"、"mfg", - "new", - "oma"、"omd"、"omi", - "pin"、"plt"、"ps"、"pty", - "usr", - "xlog"、"ylog", - "ylbias"
其余参数也可以作为参数(通常通过...)传递给高级绘图函数。
这些参数都由C函数Specify处理,而ptype 0参数可以在高级绘图函数中使用,由C函数Specify2处理。

很明显,这些分配不是随机的,而是有意识的设计选择。我可以轻松地讲述一个“为什么”它们被这样设计的故事,例如,如果我制作了散点图并想添加线条、注释、标题或图例,那么我必须在我的调用到linesaxislegend等函数时使用同样的mar参数,以确保绘图区域匹配,否则将感觉比预先设置mar更糟糕的设计。"我为什么不能在绘图之前只设置一次然后就完成了呢!?"

但实际设计背后的原因需要来自开发人员本身(或者甚至是GRZ库的开发人员,基于该库构建了par系统)。

关于如何解决这个问题,除了定义一个新的高级绘图函数来设置 mar、绘制图形,然后重置旧的 mar 之外,几乎无法做任何事情。
plot_with_mar <- function(mar = par('mar'), ...) {
  parmar <- par('mar')
  par(mar = mar)
  plot(...)
  par(mar = parmar, new = FALSE)
  invisible(NULL)
}

这可以用作 plot 的替代方案:

set.seed(1)

x <- 1:10
y <- rnorm(10)

plot_with_mar(x, y, mar = c(2, 2, 2, 2))

enter image description here

plot_with_mar(x, y, mar = c(8, 8, 8, 8))

enter image description here

如果这种方式感觉有些笨重,那么考虑到这实际上是R中所有内置的高级绘图函数所做的。此外,如果您在使用plot_with_mar绘图后尝试添加线条或注释,您很快就会发现以这种方式进行操作是多么繁琐。 创建于2022-11-17,使用reprex v2.0.2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接