中心对齐底部图例视口或相对于带有网格包的绘图区域
Center align bottom legend viewport or grob relative to plot area with grid package
我正在尝试对齐图表底部的图例,分别以该图表为中心。但我无法对齐它。
下面的图片显示了当前的渲染图,您可以清楚地看到图例未对齐(红线作为指导)。
library(grid)
draw <- function() {
masterLayout <- grid.layout(
nrow = 4,
ncol = 1,
heights = unit(c(0.1, 0.7, 0.1, 0.1), rep("null", 4)))
vp1 <- viewport(layout.pos.row=1, layout.pos.col = 1, name="title")
vp2 <- viewport(layout.pos.row=2, layout.pos.col = 1, name="plot")
vp3 <- viewport(layout.pos.row=3, layout.pos.col = 1, name="legend")
vp4 <- viewport(layout.pos.row=4, layout.pos.col = 1, name="caption")
pushViewport(
vpTree(viewport(layout = masterLayout, name = "master"),
vpList(vp1, vp2, vp3, vp4)))
## Draw main plot
seekViewport("plot")
pushViewport(viewport(width=unit(.8, "npc")))
grid.rect(gp=gpar("fill"="red")) # dummy chart
popViewport(2)
## Draw legend
seekViewport("legend")
colors <- list(first="red", second="green", third="blue")
data.names <- names(colors)
legend.cols <- length(data.names)
pushViewport(viewport(
width = unit(0.8, "npc"),
layout = grid.layout(ncol=legend.cols * 2,
nrow=1,
widths=unit(2.5, "cm"),
heights=unit(0.25, "npc"))))
idx <- 0
for(name in data.names) {
idx <- idx + 1
pushViewport(viewport(layout.pos.row=1, layout.pos.col=idx))
grid.circle(x=0, r=0.35, gp=gpar(fill=colors[[name]], col=NA))
popViewport()
idx <- idx + 1
pushViewport(viewport(layout.pos.row=1, layout.pos.col=idx))
grid.text(x=unit(-0.8, "npc"), "text", just="left")
popViewport()
}
popViewport(2)
}
draw()
我不明白你为什么对单个视口做这么多。这使它变得非常复杂。我本以为为图例设置一个视口然后控制文本和圆圈相对于它的 x 坐标要容易得多。像这样的东西;我不确定这是否正是您想要的,但感觉如果您需要调整它应该很容易控制:
library(grid)
draw <- function() {
masterLayout <- grid.layout(
nrow = 4,
ncol = 1,
heights = unit(c(0.1, 0.7, 0.1, 0.1), rep("null", 4)))
vp1 <- viewport(layout.pos.row=1, layout.pos.col = 1, name="title")
vp2 <- viewport(layout.pos.row=2, layout.pos.col = 1, name="plot")
vp3 <- viewport(layout.pos.row=3, layout.pos.col = 1, name="legend")
vp4 <- viewport(layout.pos.row=4, layout.pos.col = 1, name="caption")
pushViewport(
vpTree(viewport(layout = masterLayout, name = "master"),
vpList(vp1, vp2, vp3, vp4)))
## Draw main plot
seekViewport("plot")
pushViewport(viewport(width=unit(.8, "npc")))
grid.rect(gp=gpar("fill"="red")) # dummy chart
popViewport(2)
## Draw legend
seekViewport("legend")
colors <- list(first="red", second="green", third="blue")
lab_centers <- seq(from = 0.2, to = 0.8, length = length(colors))
disp <- 0.03 # how far to left of centre circle is, and to right text is, in each label
for(i in 1:length(colors)){
grid.circle(x = lab_centers[i] - disp, r = 0.1, gp=gpar(fill = colors[[i]], col=NA))
grid.text("text", x = lab_centers[i] + disp)
}
popViewport(2)
}
draw()
grid.lines(c(0.5, 0.5), c(0, 1))
如果您的图例标签长度不同,您可能需要将它们左对齐并调整我使用 disp 参数的方式,但不应该太难。
我正在尝试对齐图表底部的图例,分别以该图表为中心。但我无法对齐它。 下面的图片显示了当前的渲染图,您可以清楚地看到图例未对齐(红线作为指导)。
library(grid)
draw <- function() {
masterLayout <- grid.layout(
nrow = 4,
ncol = 1,
heights = unit(c(0.1, 0.7, 0.1, 0.1), rep("null", 4)))
vp1 <- viewport(layout.pos.row=1, layout.pos.col = 1, name="title")
vp2 <- viewport(layout.pos.row=2, layout.pos.col = 1, name="plot")
vp3 <- viewport(layout.pos.row=3, layout.pos.col = 1, name="legend")
vp4 <- viewport(layout.pos.row=4, layout.pos.col = 1, name="caption")
pushViewport(
vpTree(viewport(layout = masterLayout, name = "master"),
vpList(vp1, vp2, vp3, vp4)))
## Draw main plot
seekViewport("plot")
pushViewport(viewport(width=unit(.8, "npc")))
grid.rect(gp=gpar("fill"="red")) # dummy chart
popViewport(2)
## Draw legend
seekViewport("legend")
colors <- list(first="red", second="green", third="blue")
data.names <- names(colors)
legend.cols <- length(data.names)
pushViewport(viewport(
width = unit(0.8, "npc"),
layout = grid.layout(ncol=legend.cols * 2,
nrow=1,
widths=unit(2.5, "cm"),
heights=unit(0.25, "npc"))))
idx <- 0
for(name in data.names) {
idx <- idx + 1
pushViewport(viewport(layout.pos.row=1, layout.pos.col=idx))
grid.circle(x=0, r=0.35, gp=gpar(fill=colors[[name]], col=NA))
popViewport()
idx <- idx + 1
pushViewport(viewport(layout.pos.row=1, layout.pos.col=idx))
grid.text(x=unit(-0.8, "npc"), "text", just="left")
popViewport()
}
popViewport(2)
}
draw()
我不明白你为什么对单个视口做这么多。这使它变得非常复杂。我本以为为图例设置一个视口然后控制文本和圆圈相对于它的 x 坐标要容易得多。像这样的东西;我不确定这是否正是您想要的,但感觉如果您需要调整它应该很容易控制:
library(grid)
draw <- function() {
masterLayout <- grid.layout(
nrow = 4,
ncol = 1,
heights = unit(c(0.1, 0.7, 0.1, 0.1), rep("null", 4)))
vp1 <- viewport(layout.pos.row=1, layout.pos.col = 1, name="title")
vp2 <- viewport(layout.pos.row=2, layout.pos.col = 1, name="plot")
vp3 <- viewport(layout.pos.row=3, layout.pos.col = 1, name="legend")
vp4 <- viewport(layout.pos.row=4, layout.pos.col = 1, name="caption")
pushViewport(
vpTree(viewport(layout = masterLayout, name = "master"),
vpList(vp1, vp2, vp3, vp4)))
## Draw main plot
seekViewport("plot")
pushViewport(viewport(width=unit(.8, "npc")))
grid.rect(gp=gpar("fill"="red")) # dummy chart
popViewport(2)
## Draw legend
seekViewport("legend")
colors <- list(first="red", second="green", third="blue")
lab_centers <- seq(from = 0.2, to = 0.8, length = length(colors))
disp <- 0.03 # how far to left of centre circle is, and to right text is, in each label
for(i in 1:length(colors)){
grid.circle(x = lab_centers[i] - disp, r = 0.1, gp=gpar(fill = colors[[i]], col=NA))
grid.text("text", x = lab_centers[i] + disp)
}
popViewport(2)
}
draw()
grid.lines(c(0.5, 0.5), c(0, 1))
如果您的图例标签长度不同,您可能需要将它们左对齐并调整我使用 disp 参数的方式,但不应该太难。