R使用视口添加数据表到ggplot图:缩放Grob

问题描述:

我想添加一个数据表到ggplot中制作的图表(类似于excel功能但具有更改轴的灵活性)R使用视口添加数据表到ggplot图:缩放Grob

我已经有几无二它,并保持击中缩放等等问题尝试1)是

library(grid) 
library(gridExtra) 
library(ggplot2) 
xta=data.frame(f=rnorm(37,mean=400,sd=50)) 
xta$n=0 
for(i in 1:37){xta$n[i]<-paste(sample(letters,4),collapse='')} 
xta$c=0 
for(i in 1:37){xta$c[i]<-sample((1:6),1)} 
rect=data.frame(xmi=seq(0.5,36.5,1),xma=seq(1.5,37.5,1),ymi=0,yma=10) 
xta=cbind(xta,rect) 
a = ggplot(data=xta,aes(x=n,y=f,fill=c)) + geom_bar(stat='identity') 
b = ggplot(data=xta,aes(x=n,y=5,label=round(f,1))) + geom_text(size=4) + geom_rect(aes(xmin=xmi,xmax=xma,ymin=ymi,ymax=yma),alpha=0,color='black') 
z = theme(axis.text=element_blank(),panel.background=element_rect(fill='white'),axis.ticks=element_blank(),axis.title=element_blank()) 
b=b+z 
la=grid.layout(nrow=2,ncol=1,heights=c(0.15,2),default.units=c('null','null')) 
grid.show.layout(la) 
grid.newpage() 
pushViewport(viewport(layout=la)) 
print(a,vp=viewport(layout.pos.row=2,layout.pos.col=1)) 
print(b,vp=viewport(layout.pos.row=1,layout.pos.col=1)) 

它生产

2 ggplots

第二次尝试2)是

xta1=data.frame(t(round(xta$f,1))) 
xtb=tableGrob(xta1,show.rownames=F,show.colnames=F,show.vlines=T,gpar.corefill=gpar(fill='white',col='black'),gp=gpar(fontsize=12),vp=viewport(layout.pos.row=1,layout.pos.col=1)) 
grid.newpage() 
la=grid.layout(nrow=2,ncol=1,heights=c(0.15,2),default.units=c('null','null')) 
grid.show.layout(la) 
grid.newpage() 
pushViewport(viewport(layout=la)) 
print(a,vp=viewport(layout.pos.row=2,layout.pos.col=1)) 
grid.draw(xtb) 

它生产

using a straight table grob and grid.draw

和最后3)

grid.newpage() 
print(a + annotation_custom(grob=xtb,xmin=0,xmax=37,ymin=450,ymax=460)) 

它生产

using annotate_custom

其中选项2将是最好的,如果我可以将tableGrob缩放到与情节相同的大小,但我不知道该怎么做。任何关于如何进一步采取的指针? - 谢谢

您可以尝试tableGrob的新版本;所产生的gtable宽度/高度可以设置为特定的大小(这里等距分布的NPC单位)

library(ggplot2) 
library(gridExtra) 
library(grid) 
tg <- tableGrob(head(iris), rows=NULL) 
tg$widths <- unit(rep(1/ncol(tg),ncol(tg)),"npc") 
tg$heights <- unit(rep(1/nrow(tg),nrow(tg)),"npc") 

qplot(colnames(iris), geom="bar")+ theme_bw() + 
    scale_x_discrete(expand=c(0,0)) + 
    scale_y_continuous(lim=c(0,2), expand=c(0,0)) + 
    annotation_custom(ymin=1, ymax=2, xmin=-Inf, xmax=Inf, tg) 

enter image description here

+0

谢谢@baptiste我还没有机会测试这个呢。将在周末这样做,但这看起来是正确的答案。感谢一个了不起的包裹 – 2013-04-12 10:28:30

+0

感谢@baptiste像一个魅力。万岁! – 2013-04-14 06:29:36

+0

快速问题@baptiste每次都必须加载'source_gist'吗?当你预计实验桌上的Grob会进入主流代码? – 2013-04-14 09:18:42

您可以使用例如ggplot创建的表格,并将它们结合起来使用,如blog。我在这里做了简化和工作示例:

首先出示你的情节:

library(ggplot2) 
library(reshape2) 
library(grid) 

df <- structure(list(City = structure(c(2L, 
    3L, 1L), .Label = c("Minneapolis", "Phoenix", 
    "Raleigh"), class = "factor"), January = c(52.1, 
    40.5, 12.2), February = c(55.1, 42.2, 16.5), 
    March = c(59.7, 49.2, 28.3), April = c(67.7, 
     59.5, 45.1), May = c(76.3, 67.4, 57.1), 
    June = c(84.6, 74.4, 66.9), July = c(91.2, 
     77.5, 71.9), August = c(89.1, 76.5, 
     70.2), September = c(83.8, 70.6, 60), 
    October = c(72.2, 60.2, 50), November = c(59.8, 
     50, 32.4), December = c(52.5, 41.2, 
     18.6)), .Names = c("City", "January", 
    "February", "March", "April", "May", "June", 
    "July", "August", "September", "October", 
    "November", "December"), class = "data.frame", 
    row.names = c(NA, -3L)) 

dfm <- melt(df, variable = "month") 

levels(dfm$month) <- month.abb 
p <- ggplot(dfm, aes(month, value, group = City, 
    colour = City)) 
p1 <- p + geom_line(size = 1) + theme(legend.position = "top") + xlab("") 

下产生ggplot的数据表。使用相同x轴的情节:

none <- element_blank() 
data_table <- ggplot(dfm, aes(x = month, y = factor(City), 
    label = format(value, nsmall = 1), colour = City)) + 
    geom_text(size = 3.5) + 
    scale_y_discrete(labels = abbreviate)+ theme_bw() + 
    theme(panel.grid.major = none, legend.position = "none", 
     panel.border = none, axis.text.x = none, 
     axis.ticks = none) + theme(plot.margin = unit(c(-0.5, 
    1, 0, 0.5), "lines")) + xlab(NULL) + ylab(NULL) 

两者结合起来使用视:

Layout <- grid.layout(nrow = 2, ncol = 1, heights = unit(c(2, 
    0.25), c("null", "null"))) 
grid.show.layout(Layout) 
vplayout <- function(...) { 
    grid.newpage() 
    pushViewport(viewport(layout = Layout)) 
} 

subplot <- function(x, y) viewport(layout.pos.row = x, 
    layout.pos.col = y) 

mmplot <- function(a, b) { 
    vplayout() 
    print(a, vp = subplot(1, 1)) 
    print(b, vp = subplot(2, 1)) 
} 

mmplot(p1, data_table) 

注意,仍然需要一些调整,如情节的传奇人物的位置和的abbrevation城市名称的表格,但结果看起来不错: enter image description here

适用于你的例子:

library(grid) 
library(gridExtra) 
library(ggplot2) 
xta=data.frame(f=rnorm(37,mean=400,sd=50)) 
xta$n=0 
for(i in 1:37){xta$n[i]<-paste(sample(letters,4),collapse='')} 
xta$c=0 
for(i in 1:37){xta$c[i]<-sample((1:6),1)} 
rect=data.frame(xmi=seq(0.5,36.5,1),xma=seq(1.5,37.5,1),ymi=0,yma=10) 
xta=cbind(xta,rect) 
a = ggplot(data=xta,aes(x=n,y=f,fill=c)) + geom_bar(stat='identity')+ theme(legend.position = "top")+xlab("") 

none <- element_blank() 
z=ggplot(xta, aes(x = n, y = "fvalues", 
    label = round(f,1)))+ 
    geom_text(size = 3)+ theme_bw() + 
    theme(panel.grid.major = none, legend.position = "none", 
     panel.border = none, axis.text.x = none, 
     axis.ticks = none) + theme(plot.margin = unit(c(-0.5, 
    1, 0, 0.5), "lines")) + xlab(NULL) + ylab(NULL) 

Layout <- grid.layout(nrow = 2, ncol = 1, heights = unit(c(2, 
    0.25), c("null", "null"))) 
grid.show.layout(Layout) 
vplayout <- function(...) { 
    grid.newpage() 
    pushViewport(viewport(layout = Layout)) 
} 

subplot <- function(x, y) viewport(layout.pos.row = x, 
    layout.pos.col = y) 

mmplot <- function(a, b) { 
    vplayout() 
    print(a, vp = subplot(1, 1)) 
    print(b, vp = subplot(2, 1)) 
} 

mmplot(a, z) 

enter image description here

编辑:

类似于丹尼斯自己的解决方案,但不是barplot与+ coord_flip()。您可以删除后者,如果你不想甩掉它,但它增加了可读性:

ggplot(xta, aes(x=n,y=f,fill=c)) + 
    geom_bar() + 
    labs(color = "c") + 
    geom_text(aes(y = max(f)+30, label = round(f, 1)), size = 3, color = "black") + coord_flip() 
+0

感谢@ JT85这是有用的,我没有看到博客。我的第一次尝试(不使用tableGrob)本质上就是这个过程,但删除了函数调用,并在数字周围使用了矩形。如果我移动图例,我知道我可以使它工作,但我试图调整grob到图形的大小,而不是更改图形以允许显示数据。这几乎是我所需要的。 – 2013-04-05 10:43:07

+1

我为答案增加了另一个解决方案。谢谢@ JT85 – JT85 2013-04-05 11:25:51

+0

。这绝对是一个解决方案,但我希望尽可能到达实际的数据表。如果你不介意的话,我会推迟标记这个答案作为答案,因为它仍然看起来像一个注释,而不是一个明确的值表。我有一个确定的外观和感觉,我要去。 – 2013-04-06 10:27:44

恕我直言,这不是一个精心设计的图形。首先,我不明白为什么当数值范围从300到500时,你需要一个零原点,这是一种变相的说法,我不喜欢条形图隐喻。你也试图用栏填充来表示c值的差异,其中只有6个值。我相信这是解决问题的一种更简单的方法。鉴于你的xta数据,

# Convert the categories to a factor 
xta$N <- factor(xta$n, levels = xta$n) 

# Simple approach: 
ggplot(xta, aes(x = f, y = N, color = factor(c))) + 
    geom_point() + 
    labs(color = "c") + 
    geom_text(aes(x = 575, label = round(f, 1)), size = 4, color = "black") 

这对我来说不是一个有趣的图形。根据问题的上下文,可能会增加一点洞察力的是按递增顺序对响应进行排序,并添加一个尺寸审美以标明c的级别之间的差异。 (您也可以使用没有颜色的尺寸。)最后,因为我们将因子水平放置在垂直轴上,以便它们的标签清晰可见,所以我们还可以通过稍微扩展水平轴来将f值作为文本插入。

ggplot(xta, aes(x = f, y = reorder(N, f), color = factor(c), size = c)) + 
    geom_point() + 
    labs(color = "c") + 
    geom_text(aes(x = 575, label = round(f, 1)), size = 4, color = "black") 

在这段代码中有足够的提示让你采取不同的方向。我会留给你的。

+1

感谢您输入@Dennis。实际的数据被排序,数据集更适合使用barplot。我想到了这个dotplot,但是对于我的观众来说,我认为它只是混淆了事情,因为他们对图形不熟悉。我欣赏这个输入。我将在同一个项目中使用一个单独的视觉辅助点。 – 2013-04-05 10:40:57