将图例宽度设置为 100% 绘图宽度

rmf*_*rmf 6 r ggplot2

无论实际尺寸如何,如何将图例高度或宽度设置为绘图高度/宽度的 100%?

\n
library(ggplot2)\nggplot(iris, aes(Petal.Width, Sepal.Width, color=Petal.Length))+\n  geom_point()+\n  theme(\n    legend.title=element_blank(),\n    legend.position="bottom",\n    legend.key.width=unit(0.1,"npc"))\n
Run Code Online (Sandbox Code Playgroud)\n

\n

由reprex 包于 2022 年 2 月 11 日创建(v2.0.1)

\n\n\n会话信息\n\n
sessioninfo::session_info()\n#> \xe2\x94\x80 Session info \xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\n#>  setting  value\n#>  version  R version 4.1.0 (2021-05-18)\n#>  os       Ubuntu 20.04.3 LTS\n#> \xe2\x94\x80 Packages \xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\n#>  ggplot2     * 3.3.5   2021-06-25 [1] CRAN (R 4.1.0)\n#> \n#> \xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\n
Run Code Online (Sandbox Code Playgroud)\n\n

teu*_*and 5

请原谅我有双重答案,但我相信这是一种完全不同的方法,这个想法的版权归@benson23所有。

我们可以用来ggh4x::force_panelsizes()设置面板的绝对大小并匹配栏的宽度。优点是它相当容易做到,缺点是绘图的宽度不再自动适应窗口大小。

library(ggplot2)
library(ggh4x)

width <- unit(10, "cm")

ggplot(iris, aes(Petal.Width, Sepal.Width, color=Petal.Length))+
  geom_point() +
  guides(colour = guide_colorbar(barwidth = width)) +
  force_panelsizes(cols = width) +
  theme(
    legend.title=element_blank(),
    legend.position="bottom",
    legend.spacing.x = unit(0, "cm"))
Run Code Online (Sandbox Code Playgroud)

如果绘图有多个面板,该过程会变得稍微复杂一些,但它是不可撤消的。

ncol         <- 3
total_width  <- unit(10, "cm")
# Optionally: replace `theme_get()` with actual theme you're using
spacing      <- calc_element("panel.spacing.x", theme_get())
panel_widths <- (total_width - spacing * (ncol - 1)) / ncol

ggplot(iris, aes(Petal.Width, Sepal.Width, color=Petal.Length))+
  geom_point() +
  guides(colour = guide_colorbar(barwidth = total_width)) +
  facet_wrap(~ Species, ncol = ncol) +
  force_panelsizes(cols = panel_widths) +
  theme(
    legend.title=element_blank(),
    legend.position="bottom",
    legend.spacing.x = unit(0, "cm"))
Run Code Online (Sandbox Code Playgroud)

由reprex 包于 2022 年 2 月 11 日创建(v2.0.1)

免责声明:我是 {ggh4x} 的作者


teu*_*and 4

我知道的唯一方法是手动调整绘图 gtable 中的网格对象。AFAIK,指南大多以厘米(而不是相对单位)定义,因此让它们适应面板有点痛苦。我也很想知道更好的方法来做到这一点。

library(ggplot2)

g <- ggplot(iris, aes(Petal.Width, Sepal.Width, color=Petal.Length))+
  geom_point()+
  theme(
    legend.title=element_blank(),
    legend.position="bottom",
    legend.key.width=unit(0.1,"npc"),
    legend.margin = margin(), # pre-emptively set zero margins
    legend.spacing.x = unit(0, "cm"))

gt <- ggplotGrob(g) 

# Extract legend
is_legend <- which(gt$layout$name == "guide-box")
legend <- gt$grobs[is_legend][[1]]
legend <- legend$grobs[legend$layout$name == "guides"][[1]]

# Set widths in guide gtable
width <- as.numeric(legend$widths[4]) # save bar width (assumes 'cm' unit) 
legend$widths[4] <- unit(1, "null") # replace bar width

# Set width/x of bar/labels/ticks. Assumes everything is 'cm' unit.
legend$grobs[[2]]$width <- unit(1, "npc")
legend$grobs[[3]]$children[[1]]$x <- unit(
  as.numeric(legend$grobs[[3]]$children[[1]]$x) / width, "npc"
)
legend$grobs[[5]]$x0 <- unit(as.numeric(legend$grobs[[5]]$x0) / width, "npc")
legend$grobs[[5]]$x1 <- unit(as.numeric(legend$grobs[[5]]$x1) / width, "npc")

# Replace legend
gt$grobs[[is_legend]] <- legend

# Draw new plot
grid::grid.newpage()
grid::grid.draw(gt)
Run Code Online (Sandbox Code Playgroud)

由reprex 包于 2022 年 2 月 11 日创建(v2.0.1)