R语言 ggplot2函数具有意外的递归大小调整和原始图覆盖

m3eecexj  于 2023-04-09  发布在  其他
关注(0)|答案(3)|浏览(89)

我正在尝试编辑gglot 2对象中不同元素的大小,例如使点更大。我需要在已经构造的对象上工作:也就是说,我得到了一个ggplot 2对象test_plot,我想创建一个函数,使我能够缩放点的大小并返回一个newggplot 2对象。我需要两个plot对象:原始图(具有未缩放的元素)和具有缩放的元素的新图。
然而,我下面的尝试似乎同时缩放了原来的和新的图--当多次调用时导致递归缩放。
我以为函数中的所有内容都是局部作用域的,不会触及全局环境中的原始绘图。

library(ggplot2)
test_plot = ggplot(mtcars) +
  geom_point(aes(y = mpg, x = hp), col = "black")

adjust_point_size <- function(gg_plot,element_size_adjust = 1) {
  build_data =  ggplot_build(gg_plot)$data
  point_size = unique(build_data[[1]]$size)

  gg_plot$layers[[1]]$aes_params$size <- point_size*element_size_adjust
  gg_plot
}

adjust_point_size(gg_plot = test_plot, element_size_adjust = 2) # ok

adjust_point_size(gg_plot = test_plot, element_size_adjust = 2) # why doubled

adjust_point_size(gg_plot = test_plot, element_size_adjust = 2) # why doubled again

test_plot # why different?

创建于2023-04-08使用reprex v2.0.2
我尝试将plot对象保存为函数中的一个新的临时对象,例如test_plot2 = test_plot,然后处理test_plot2。
我用的是ggplot 2 v3.4.1。
谢谢!

7hiiyaii

7hiiyaii1#

这是怎么回事?

adj_pt_size <- function(ggplot, size_adj) {
  ggplot$layers[[1]]$aes_params$size <- 1*size_adj
  return(ggplot)
}

test_plot = ggplot(mtcars) +
  geom_point(aes(y = mpg, x = hp), col = "black")

adj_pt_size(test_plot, 2)
9gm1akwq

9gm1akwq2#

虽然它更复杂,并且最初的答案符合操作的目的,但这里有一个稍微复杂一点的版本,我认为它完全符合操作的要求。如果绘图有多个图层,您需要调整功能以复制和编辑所需的图层。

library(ggplot2)
library(ggedit)

test_plot = ggplot(mtcars) +
  geom_point(aes(y = mpg, x = hp), col = "black")

adjust_point_size <- function(gg_plot, element_size_adjust = 1) {
  build_data =  ggplot_build(gg_plot)$data
  point_size = unique(build_data[[1]]$size)
  
  new_root <- cloneRoot(gg_plot)
  new_layer <- cloneLayer(gg_plot[["layers"]][[1]])
  
  new_plot <- new_root + new_layer
  new_plot$layers[[1]]$aes_params$size <- point_size*element_size_adjust
  new_plot
}
yiytaume

yiytaume3#

modifying ggplot objects after creation的帮助下,我得到了这个解决方案。
是什么让这个工作?

  • 一个关键是操纵data列表内的点大小而不是layers
  • 通过ggplot_build()获取预组装的ggplot,然后对其进行操作。通过ggplot_gtable()完成组装
require(ggplot2)

adj_pt_size <- function(gg_plot, element_size_adjust) {
  
  q <- ggplot_build(gg_plot)

  q$data[[1]]$size <- 
    q$data[[1]]$size * element_size_adjust
  
  return(plot(ggplot_gtable(q)))
}

adj_pt_size(gg_plot = test_plot, element_size_adjust = 10) # ok

相关问题