有没有办法在网格窗口中获得绘图区域的宽度?例如,如果更改plot.margin
或者y轴标签的font-size增加,它会增大或缩小。是隐藏在str(p)
的某个地方吗?
任何尺寸的尺寸都可行。我需要能够在不同情况下测量绘图区域宽度的相对变化,例如更改y轴标签的字体大小。
df = data.frame(x = (1:3),One=c(12, 8, 13),Two=c(13, 7, 11),Three=c(11, 9, 11))
df.melt = melt(df, id.vars="x")
p = ggplot(df.melt, aes(x=x, y=value, color=variable)) +
geom_line() +
coord_cartesian(xlim=c(min(df.melt$x),max(df.melt$x))) +
theme(legend.position="none", plot.margin = unit(c(1, 4, 1, 1), "cm"))
p
更新 - 澄清:请帮我计算a/b
。
p = ggplot(df.melt, aes(x=x, y=value, color=variable)) +
geom_line() + coord_cartesian(xlim=c(min(df.melt$x),max(df.melt$x))) +
theme(legend.position="none")
p1 = p + theme(plot.margin=unit(c(1,1,1,1),"cm"), axis.text.y=element_text(size=10))
p2 = p + theme(plot.margin=unit(c(1,1,1,2),"cm"), axis.text.y=element_text(size=30))
grid.arrange(p1, p2, ncol=2)
答案 0 :(得分:15)
ggplot2中的图使用网格图形。已生成的图形场景 使用网格图形包由grobs和视口组成。
您可以使用 gridDebug 包来检查grob。
showGrob显示用于绘制场景的凹凸的位置和名称
showGrob()
获取grob的gpath
sceneListing <- grid.ls(viewports=T, print=FALSE)
do.call("cbind", sceneListing)
name gPath
[1,] "ROOT" ""
[2,] "GRID.gTableParent.45019" ""
[3,] "background.1-5-6-1" "GRID.gTableParent.45019"
[4,] "spacer.4-3-4-3" "GRID.gTableParent.45019"
[5,] "panel.3-4-3-4" "GRID.gTableParent.45019"
[6,] "grill.gTree.44997" "GRID.gTableParent.45019::panel.3-4-3-4"
检索gorb
h <- grid.get(gPath="GRID.gTableParent.45019")
获取h属性(例如)
h$layoutvp$width
应用:
grid.get('x',grep=TRUE,global=T)
(polyline[panel.grid.minor.x.polyline.21899], polyline[panel.grid.major.x.polyline.21903], gTableChild[axis-l.3-3-3-3], gTableChild[axis-b.4-4-4-4], gTableChild[xlab.5-4-5-4])
> grid.get('x',grep=TRUE,global=T)[[3]]
gTableChild[axis-l.3-3-3-3]
> xx <- grid.get('x',grep=TRUE,global=T)[[3]]
> grobWidth(xx)
[1] sum(1grobwidth, 0.15cm+0.1cm)
答案 1 :(得分:9)
这让我很感兴趣,可以更深入地研究它。我希望grid.ls
函数能够提供导航到正确视口的信息来获取信息,但是对于你的例子,有一些步骤被'...'取代而我不能看看如何改变它以提供易于使用的东西。但是,使用grid.ls
或其他工具,您可以看到不同视口的名称。对于您的示例,感兴趣的视口都命名为“panel.3-4-3-4”,下面是一些导航到1st的代码,找到以英寸为单位的宽度,导航到第二个并找到那个的宽度以英寸为单位。
grid.ls(view=TRUE,grob=FALSE)
current.vpTree()
seekViewport('panel.3-4-3-4')
a <- convertWidth(unit(1,'npc'), 'inch', TRUE)
popViewport(1)
seekViewport('panel.3-4-3-4')
b <- convertWidth(unit(1,'npc'), 'inch', TRUE)
a/b
我无法找到一个简单的方法来到第二个面板而不弹出第一个面板。这很有用,并且提供了所需的信息,遗憾的是,由于它从列表中弹出第一个面板,您无法返回到它并查找其他信息或进行修改。但这确实可以提供您要求的信息,可以在以后的图表中使用。
也许其他人知道如何导航到第二个面板而不弹出第一个面板,或者让每个面板的完整vpPath直接导航。
答案 2 :(得分:5)
这个答案主要是回复@java_xof的评论。回复太长,包含代码,因此不适合评论。但是,它也可以帮助解决原始问题(或至少给出一个起点)。
这是一个函数和一些使用它的代码(它需要tcltk和tkrplot包):
library(ggplot2)
library(tkrplot)
TkPlotLocations <- function(FUN) {
require(tkrplot)
cl <- substitute(FUN)
replot <- function() eval(cl)
tt <- tktoplevel()
img <- tkrplot(tt, replot, vscale=1.5, hscale=1.5)
tkpack(img)
tkpack(xfr <- tkframe(tt), side='left')
tkpack(yfr <- tkframe(tt), side='left')
xndc <- tclVar()
yndc <- tclVar()
xin <- tclVar()
yin <- tclVar()
tkgrid(tklabel(xfr, text='x ndc'), tklabel(xfr, textvariable=xndc))
tkgrid(tklabel(yfr, text='y ndc'), tklabel(yfr, textvariable=yndc))
tkgrid(tklabel(xfr, text='x inch'), tklabel(xfr, textvariable=xin))
tkgrid(tklabel(yfr, text='y inch'), tklabel(yfr, textvariable=yin))
iw <- as.numeric(tcl("image","width", tkcget(img, "-image")))
ih <- as.numeric(tcl("image","height",tkcget(img, "-image")))
cc <- function(x,y) {
x <- (as.real(x)-1)/iw
y <- 1-(as.real(y)-1)/ih
c(x,y)
}
mm <- function(x, y) {
xy <- cc(x,y)
tclvalue(xndc) <- xy[1]
tclvalue(yndc) <- xy[2]
tclvalue(xin) <- grconvertX(xy[1], from='ndc', to='inches')
tclvalue(yin) <- grconvertY(xy[2], from='ndc', to='inches')
}
tkbind( img, "<Motion>", mm)
invisible()
}
x <- runif(25)
y <- rnorm(25, x, 0.25)
plot(x,y)
par()$pin
par()$plt
TkPlotLocations(plot(x,y))
qplot(x,y)
par()$pin
par()$plt
TkPlotLocations(print(qplot(x,y)))
qplot(x,y) + xlab('Multi\nline\nx\nlabel')
par()$pin
par()$plt
TkPlotLocations(print(qplot(x,y) + xlab('Multi\nline\nx\nlabel')))
定义上述函数,然后运行以下行将生成3个相同随机数据的图。您可以看到par()$pin
和par()$plt
(以及其他参数)的结果对于3个绘图完全相同,即使绘图区域在图中有所不同。
还会有3个新窗口弹出,在窗口中你可以将鼠标指针移动到图形上,在窗口底部你会看到指针在标准化设备坐标和英寸中的当前位置(均来自设备区域的左下角)。您可以将鼠标指针悬停在图形(或任何其他部分)的角上,以查看值并在3个图形之间进行比较。
这可能足以回答原始问题的至少一部分(只是不以编程方式,这将更有用)。可以修改功能以打印出其他测量值。如果其他人感兴趣,我可以扩展这个并将其包含在未来的包中。