【问题标题】:When using ggplot in R, how do I remove margins surrounding the plot area?在 R 中使用 ggplot 时,如何删除绘图区域周围的边距?
【发布时间】:2015-07-06 19:56:26
【问题描述】:

我正在尝试生成一些分形,并且对 R 中 ggplot 的边距有疑问。我正在使用以下代码生成分形。

library(ggplot2)
library(grid)

max_iter=25
cl=colours()
step=seq(-2,0.8,by=0.005)
points=array(0,dim=c(length(step)^2,3))
t=0

for(a in step) {
  for(b in step+0.6) {
    x=0;y=0;n=0;dist=0
    while(n<max_iter & dist<4)  {
      n=n+1
      newx=a+x^2-y^2
      newy=b+2*x*y
      dist=newx^2+newy^2
      x=newx;y=newy
    }

    if(dist<4)  { 
      color=24 # black
    } else {
      color=n*floor(length(cl)/max_iter)
    }
    t=t+1
    points[t,]=c(a,b,color)
  }
}

df=as.data.frame(points)    

ggplot(data=df, aes(V1, V2, color=cl[V3]))+ 
  geom_point() + 
  theme(panel.background=element_blank(), 
       panel.grid.major=element_blank(), 
       panel.grid.minor=element_blank(), 
       panel.margin = unit(c(0, 0, 0, 0), "cm"),       
       axis.ticks=element_blank(), 
       axis.text.x=element_blank(), 
       axis.text.y=element_blank(), 
       axis.title.x=element_blank(), 
       axis.title.y=element_blank(),
       plot.background = element_rect(fill = "transparent",colour = NA),
       plot.margin = unit(c(0, 0, 0, 0), "cm"),
       legend.position = 'none')

last_plot() + scale_colour_manual(values=sort(c("#00000000", rainbow(35)), decreasing=FALSE))

ggsave('mandelbrot.png');
print('Image Saved.')

我正在寻找删除情节区域周围边距的想法。我尝试了一大堆技巧,例如在“par”中设置参数,xaxes / yaxes,last_plot() + labs(x=NULL, y=NULL) 等,但似乎没有任何效果。

有没有人想从情节中删除这个棘手的边缘?我还考虑过设置透明背景,但我必须剪掉边距——这是我想避免的步骤。

【问题讨论】:

  • 尝试以null为单位,即plot.margin = unit(c(0, 0, 0, 0), "null")

标签: r plot ggplot2


【解决方案1】:

您也可以使用cowplot 包中的theme_nothing()

require(cowplot)
qplot(1:10, (1:10)^2, geom='line') + theme_nothing() + 
  scale_x_continuous(expand=c(0,0)) +
  scale_y_continuous(expand=c(0,0)) +
  labs(x = NULL, y = NULL)

不幸的是,您仍然需要添加labs(x = NULL, y = NULL),因为在ggplot2 的主题机制中没有办法完全删除轴。并且您需要在比例参数中设置expand=c(0,0),以确保比例不会超出您的数据范围。

结果:

【讨论】:

    【解决方案2】:

    使用您的代码后,我更清楚地看到了您要查找的内容。这个:

    gg <- ggplot(data=df, aes(V1, V2, color=cl[V3]))
    gg + 
      geom_point() +
      labs(x = NULL, y = NULL, title = NULL) +
      scale_x_continuous(expand = c(0, 0), limits = range(df$V1)) +
      scale_y_continuous(expand = c(0, 0), limits = range(df$V2)) +
      scale_colour_manual(values = sort(c("#00000000", rainbow(35)), decreasing = FALSE)) +
      theme(
        panel.background = element_rect(fill = "transparent", colour = NA),
        plot.background = element_rect(fill = "transparent", colour = NA),
        panel.grid = element_blank(),
        panel.border = element_blank(),
        plot.margin = unit(c(0, 0, 0, 0), "null"),
        panel.margin = unit(c(0, 0, 0, 0), "null"),
        axis.ticks = element_blank(),
        axis.text = element_blank(),
        axis.title = element_blank(),
        axis.line = element_blank(),
        legend.position = "none",
        axis.ticks.length = unit(0, "null"),
        axis.ticks.margin = unit(0, "null"),
        legend.margin = unit(0, "null")
      )
    

    您必须删除标签,不扩展 x 和 y 轴并设置硬限制。 nulls 也很重要。'

    这也可以通过 gb &lt;- ggplotGrob(gg) 并手动编辑 grobs 和参数来完成,但我认为这可能会满足您的需求。

    【讨论】:

    • 或者,代替所有这些主题声明,使用来自 cowplot 包的theme_nothing()。不过基本上是一样的。
    • 教鱼……我认为"null"s 比"lines" 工作得更好,如果内存用于完全消除间距,如果是这样的话,可以在 grob 级别进行验证(我可以稍后检查)。
    • 我肯定想知道在这个应用程序中null 是否比lines 更好的单位选择,所以请告诉我你发现了什么。先验,null 似乎产生了一些不必要的开销,因为它是一个相对单位,可以根据图中其他元素的大小而增长和缩小。
    • 强制弃用:现在是 panel.spacing 而不是 panel.margin
    【解决方案3】:

    一种仅从 ggplot 布局中选择绘图面板的方法。它创建 ggplot,将绘图面板中的元素设置为 element_blank,并且不扩展 x 和 y 比例。然后它创建 ggplot grob 以便只能从布局中选择绘图面板。

    小修改:更新到 ggplot2 2.2.0

    library(ggplot2)
    library(grid)
    
    max_iter=25
    cl=colours()
    step=seq(-2,0.8,by=0.005)
    points=array(0,dim=c(length(step)^2,3))
    t=0
    
    for(a in step) {
      for(b in step+0.6) {
        x=0;y=0;n=0;dist=0
        while(n<max_iter & dist<4)  {
          n=n+1
          newx=a+x^2-y^2
          newy=b+2*x*y
          dist=newx^2+newy^2
          x=newx;y=newy
        }
    
        if(dist<4)  { 
          color=24 # black
        } else {
          color=n*floor(length(cl)/max_iter)
        }
        t=t+1
        points[t,]=c(a,b,color)
      }
    }
    
    df=as.data.frame(points)    
    
    # ggplot with elements in the plot panel set to element_blank()
    # and no expansion on the scales
    p = ggplot(data=df, aes(V1, V2, color=cl[V3]))+ 
      geom_point() + 
      scale_x_continuous(expand = c(0,0), limits=range(df$V1)) +
      scale_y_continuous(expand = c(0,0), limits=range(df$V2))+
      theme(panel.grid=element_blank(), 
           panel.background=element_rect(fill = "transparent",colour = NA),
           panel.border=element_blank()) +
      scale_colour_manual(values=sort(c("#00000000", rainbow(35)), decreasing=FALSE))
    
    # Get the ggplot grob
    gt = ggplotGrob(p)
    
    # Select plot panel only
    #   gt = gt[6,4]    # Using index notation; OR
    gt = gtable::gtable_filter(gt, "panel")  
    
    # Draw it
    grid.newpage()
    grid.draw(gt)
    
    
    # Set up a print method 
    class(gt) = c("Panel", class(gt))
    print.Panel <- function(x) {
       grid.newpage()   
       grid.draw(x)
    }
    
    gt
    ggsave('mandelbrot.png', gt)
    

    【讨论】:

    • gtable_filter(gt, "panel") 选择面板可能更具可读性
    【解决方案4】:

    通过设置负的绘图边距并将轴标题设置为NULL,我能够摆脱白色边框。我已经在下面的代码中标记了修改。

    p = ggplot(data=df, aes(V1, V2, color=cl[V3]))+ 
      geom_point() + 
      theme(panel.background=element_blank(), 
            panel.grid.major=element_blank(), 
            panel.grid.minor=element_blank(), 
            panel.margin = unit(c(0, 0, 0, 0), "cm"),       
            axis.ticks=element_blank(), 
            axis.text.x=element_blank(), 
            axis.text.y=element_blank(), 
            axis.title.x=element_blank(), 
            axis.title.y=element_blank(),
            plot.background = element_rect(fill = "transparent",colour = NA),
            plot.margin = unit(c(-1, -1.2, -1.2, -1.5), "cm"),  # Edited code
            legend.position = 'none') +
      labs(x=NULL, y=NULL) # New code
    

    【讨论】:

    • 那些硬编码的plot.margin 条目是专门针对这个情节的吗?如果是这样,我的答案中的null 解决方案(现在可以使用)使它更通用。
    • 是的。它们是硬编码的,因此通用解决方案肯定更好。
    • 另外,参数名好像变了!? panel.margin 已弃用。请改用panel.spacing 属性
    猜你喜欢
    • 2012-08-31
    • 2013-05-02
    • 2020-03-02
    • 1970-01-01
    • 2020-06-11
    • 1970-01-01
    • 2011-04-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多