获取ggplot2中的绘图区域宽度

Fra*_*ert 8 r ggplot2

有没有办法在网格窗口中获得绘图区域的宽度?例如,如果plot.margin更改或者y轴标签的font-size增加,它会增大或缩小.隐藏在str(p)哪里?

任何规模的措施都可行.我需要能够在不同的场景中测量绘图区域宽度的相对变化,例如更改y轴标签的font-size.

在此输入图像描述

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
Run Code Online (Sandbox Code Playgroud)

更新 - 澄清:请帮我计算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)
Run Code Online (Sandbox Code Playgroud)

ags*_*udy 15

ggplot2中的图使用网格图形.使用网格图形包生成的图形场景由grobs和视口组成.

您可以使用gridDebug包来检查grob.

  1. showGrob显示用于绘制场景的凹凸的位置和名称

          showGrob()
    
    Run Code Online (Sandbox Code Playgroud)
  2. 得到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"                   
    
    Run Code Online (Sandbox Code Playgroud)
  3. 检索gorb

    h <- grid.get(gPath="GRID.gTableParent.45019")
    
    Run Code Online (Sandbox Code Playgroud)
  4. 得到h属性(例如)

    h$layoutvp$width
    
    Run Code Online (Sandbox Code Playgroud)

应用:

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)
Run Code Online (Sandbox Code Playgroud)


Gre*_*now 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
Run Code Online (Sandbox Code Playgroud)

我想不出一个简单的方法来到第二个面板而不弹出第一个面板.这很有用,并且提供了所需的信息,遗憾的是,由于它从列表中弹出第一个面板,您无法返回到它并查找其他信息或进行修改.但这确实可以提供您要求的信息,可以在未来的情节中使用.

也许其他人知道如何导航到第二个面板而不弹出第一个面板,或者让每个面板的完整vpPath直接导航.


Gre*_*now 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')))
Run Code Online (Sandbox Code Playgroud)

定义上述函数,然后运行以下行将生成3个相同随机数据的图.您可以看到3个图的par()$pinpar()$plt(以及其他参数)的结果完全相同,即使绘图区域的绘图区域不同.

还会有3个新窗口弹出,在窗口中你可以将鼠标指针移动到图形上,在窗口底部你会看到指针在标准化设备坐标和英寸中的当前位置(均来自设备区域的左下角).您可以将鼠标指针悬停在图形(或任何其他部分)的角上,以查看值并在3个图形之间进行比较.

这可能足以回答原始问题的至少一部分(只是不以编程方式,这将更有用).可以修改功能以打印出其他测量值.如果其他人感兴趣,我可以扩展这个并将其包含在未来的包中.

  • @java_xof呃...`qplot`是包**ggplot2**中的一个函数,它最适用于R 2.15.2.您可以尝试安装该软件包,因为这是OP所询问的内容. (4认同)