R 如何使ggplot2中的图例与绘图的高度相同?

R 如何使ggplot2中的图例与绘图的高度相同?,r,plot,ggplot2,scale,colorbar,R,Plot,Ggplot2,Scale,Colorbar,我使用ggplot2(版本0.9.3.1)在R(版本R版本3.0.1(2013-05-16))中生成了一个简单的绘图,显示了一组数据的相关系数。目前,绘图右侧的图例颜色栏只是整个绘图大小的一小部分 我希望图例颜色条与绘图的高度相同。我想我可以使用legend.key.height来实现这一点,但我发现事实并非如此。我调查了网格包单元函数,发现里面有一些标准化的单元,但当我尝试它们时(单元(1,“npc”)),色条太高,超出了页面 如何使图例的高度与绘图本身的高度相同 下面是一个完整的自包含示例:

我使用
ggplot2
(版本0.9.3.1)在R(版本R版本3.0.1(2013-05-16))中生成了一个简单的绘图,显示了一组数据的相关系数。目前,绘图右侧的图例颜色栏只是整个绘图大小的一小部分

我希望图例颜色条与绘图的高度相同。我想我可以使用
legend.key.height
来实现这一点,但我发现事实并非如此。我调查了
网格
单元
函数,发现里面有一些标准化的单元,但当我尝试它们时(
单元(1,“npc”)
),色条太高,超出了页面

如何使图例的高度与绘图本身的高度相同

下面是一个完整的自包含示例:

# Load the needed libraries
library(ggplot2)
library(grid)
library(scales)
library(reshape2)

# Generate a collection of sample data
variables = c("Var1", "Var2", "Var3")
data = matrix(runif(9, -1, 1), 3, 3)
diag(data) = 1
colnames(data) = variables
rownames(data) = variables

# Generate the plot
corrs = data
ggplot(melt(corrs), aes(x = Var1, y = Var2, fill = value)) +
  geom_tile() +
  geom_text(parse = TRUE, aes(label = sprintf("%.2f", value)), size = 3, color = "white") +
  theme_bw() +
  theme(panel.border = element_blank(),
        axis.text.x = element_text(angle = 90, vjust = 0.5, hjust = 1),
        aspect.ratio = 1,
        legend.position = "right",
        legend.key.height = unit(1, "inch")) +
        labs(x = "", y = "", fill = "", title = "Correlation Coefficients") +
        scale_fill_gradient2(limits = c(-1, 1), expand = c(0, 0),
                             low = muted("red"),
                             mid = "black",
                             high = muted("blue"))

这似乎很棘手,我最接近的是这个

## panel height is 1null, so we work it out by subtracting the other heights from 1npc
## and 1line for the default plot margins

panel_height = unit(1,"npc") - sum(ggplotGrob(plot)[["heights"]][-3]) - unit(1,"line")
plot + guides(fill= guide_colorbar(barheight=panel_height))

不幸的是,垂直对齐有点不正确。

编辑更新到ggplot v3.0.0

这是混乱的,但基于ggplot grob,并深入挖掘ggplot grob,可以精确定位图例

# Load the needed libraries
library(ggplot2)
library(gtable)  # 
library(grid)
library(scales)
library(reshape2)

# Generate a collection of sample data
variables = c("Var1", "Var2", "Var3")
data = matrix(runif(9, -1, 1), 3, 3)
diag(data) = 1
colnames(data) = variables
rownames(data) = variables

# Generate the plot
corrs = data
plot  = ggplot(melt(corrs), aes(x = Var1, y = Var2, fill = value)) + 
   geom_tile() +
   theme_bw() + 
   theme(panel.border = element_blank()) +
   theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust = 1)) +
   theme(aspect.ratio = 1) +
   # theme(legend.position = "right", legend.key.height = unit(1, "inch")) +
   labs(x = "", y = "", fill = "", title = "Correlation Coefficients") +
   scale_fill_gradient2(limits = c(-1, 1), breaks = c(-1, -.5, 0, .5, 1), expand = c(0,0), 
      low = muted("red"), mid = "black", high = muted("blue")) +  # Modified line
   geom_text(parse = TRUE, aes(label = sprintf("%.2f", value)), size = 3, color = "white") +
   scale_x_discrete(expand = c(0,0)) +  # New line
   scale_y_discrete(expand = c(0,0))    # New line
plot

# Get the ggplot grob
gt = ggplotGrob(plot)

# Get the legend
leg = gtable_filter(gt, "guide-box")

# Raster height
leg[[1]][[1]][[1]][[1]][[1]][[2]]$height = unit(1, "npc")

# Positions for labels and tick marks - five breaks, therefore, five positions
pos = unit.c(unit(0.01,"npc"), unit(.25, "npc"), unit(.5, "npc"), unit(.75, "npc"), unit(.99, "npc"))

# Positions the labels 
leg[[1]][[1]][[1]][[1]][[1]][[3]]$children[[1]]$y = pos

# Positions the tick marks
leg[[1]][[1]][[1]][[1]][[1]][[5]]$y0 = pos
leg[[1]][[1]][[1]][[1]][[1]][[5]]$y1 = pos

# Legend key height ?
leg[[1]][[1]][[1]][[1]]$heights = unit.c(rep(unit(0, "mm"), 3),
                                         unit(1, "npc"),
                                         unit(0, "mm"))
# Legend height
leg[[1]][[1]]$heights[[3]] = sum(rep(unit(0, "mm"), 3),
                                 unit(1, "npc"),
                                 unit(0, "mm"))

# grid.draw(leg)  # Check on heights and y values

# gtable_show_layout(gt) # Manually locate position of legend in layout
gt.new = gtable_add_grob(gt, leg, t = 7, l = 9)

# Draw it
grid.newpage()
grid.draw(gt.new)

请发布一个最小的独立可复制示例OK,问题编辑为完整的可运行示例Pretty durned close。。。。也许再调整一点,但我继续,并将其标记为已回答。谢谢你的指点。有没有办法防止它输出一个空的绘图?当我运行面板高度线时,将显示一个空绘图。不理想,因为它会导致保存空绘图。在尝试执行此示例时,我遇到了一个
无效的'layout.pos.row'
错误。您以前见过吗?@spacedSparking在这种情况下,当“t”和/或“l”超出给定gtable的可能值时,通常会发生错误。然而,代码对我来说是有效的——我使用的是Rv3.5.1、GGPLOT2v3.1.0、GTablev0.2.0。我猜您使用的是ggplot2的旧版本。