在进行布置时是否可以裁剪一块地块? [英] Is it possible to crop a plot when doing arrangeGrob?

查看:143
本文介绍了在进行布置时是否可以裁剪一块地块?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个类似于下面的用例,我创建了多个图并使用 gridExtra 将它们排列在某个页面布局中,最后将其另存为PDF格式为 ggsave

  p1 < -  generate_ggplot1(...)$ b $ (p1,p2,...)
ggplot2 :: ggsave(filename = output.file ,plot = final,...)

是否可以绘制在使用 arrangeGrob 来排列页面布局时裁剪了p2 ?问题在于, p2 在它的顶部和底部有很多额外的空间,我想摆脱它,因为裁剪似乎不可行使用 ggplot2 只有我想也许有可能在裁剪时裁剪它...



UPDATE 下面是一个我自己使用的例子,我想通过任何方式去掉注释为红色的区域:

  library(ggplot2);库(dplyr);库(stringr);库(gridExtra)

df< - data.frame(group = c(Cars,Trucks,Motorbikes),n = c(25,25,50),
label2 = c(Cars are blah blah blah,Trucks some of the best in town,Motorbikes are great if you ...))
df $ ymax = cumsum(df $ n)
df $ ymin = cumsum(df $ n)-df $ n
df $ ypos = df $ ymin + df $ n / 2
df $ hjust = c(0,0,1 )

p1 < - ggplot(mtcars,aes(x = 1:nrow(mtcars),y = mpg))+ geom_point()

p2 < - ggplot (df%>%
mutate(label2 = str_wrap(label2,width = 10)),#change width来调整注释宽度
aes(x =,y = n,fill = group ))+
geom_rect(aes_string(ymax =ymax,ymin =ymin,xmax =2.5,xmin =2.0))+
expand_limits(x = c(2,4 ))+#在此处更改x轴范围限制
#不更改为主题
主题(axis.title = element_blank(),axis.text = element_blank(),
panel.background = element_rect(fill =white,color =grey50),
panel.grid = element_blank(),
a xis.ticks.length = unit(0,cm),axis.ticks.margin = unit(0,cm),
legend.position =none,panel.spacing = unit(0, lines),
plot.margin = unit(c(0,0,0,0),lines),complete = TRUE)+
geom_text(aes_string(label =label2, x =3,y =ypos,hjust =hjust))+
coord_polar(y,start = 0)+
scale_x_discrete()

(1),c(2)),
widths = c(4),heights = c(4,4),padding = 0.0,$(p1,p2,layout_matrix = rbind (b $ b respect = TRUE,clip =on)
plot(final)

输出结果如下:



解决方案

为此,需要一个多部分解决方案。

首先,为了改变单个图形的边距,在theme()中使用plot.margin,是一种方便的方式。然而,如果目标是将多个图组合在一起,这本身并不能解决问题。

为此,您需要将plot.margin和特定的组合在arrangeGrob()中绘制顺序。你需要一个特定的订单,因为地块是按照你所说的顺序打印的,因此,更改分散在其他地块后面的地块的边缘将更容易,而不是在地块前面。我们可以将它想象为覆盖我们想要缩小的地块边际,方法是将该地块扩大到我们想要缩小的地方。请参阅以下图表以获得说明:



在plot.margin设置之前

 #第一张图的主要代码可以在原始问题中找到。 

在plot.margin设置后

 #第二张图的主要代码: 
ggplot(df%>%
mutate(label2 = str_wrap(label2,width = 10)),
aes(x =,y = n,fill = group))+
geom_rect(aes_string(ymax =ymax,ymin =ymin,xmax =2.5,xmin =2.0))+
geom_text(aes_string(label =label2,x = (x = c(2,4))+ $ b $(3),y =ypos,hjust =hjust))+
coord_polar(theta ='y')+
(),
axis.ticks = element_blank(),
() axis.title = element_blank(),
axis.text.y = element_blank(),
axis.text.x = element_blank(),
panel.border = element_blank(),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.background = element_rect(fill =white),
plot.margin = unit (c(-2,0,-2,-1),cm),
legend.position =none)+
scale_x_discrete(limits = c(0,1))

合并plot.margin设置和arrangeGrob()重新排序后:



  #Main第三图的代码:
p1 < - ggplot(mtcars,aes(x = 1:nrow(mtcars),y = mpg))+ geom_point()

p2 < - ggplot (df%>%
mutate(label2 = str_wrap(label2,width = 10)),#change width来调整注释宽度
aes(x =,y = n,fill = group ))+
geom_rect(aes_string(ymax =ymax,ymin =ymin,xmax =2.5,xmin =2.0) )+
geom_text(aes_string(label =label2,x =3,y =ypos,hjust =hjust))+
coord_polar(theta ='y')+
expand_limits(x = c(2,4))+#在此处更改x轴范围限制
guides(fill = guide_legend(override.aes = list(color = NA)))+
theme(axis.line = element_blank(),
axis.ticks = element_blank(),
axis.title = element_blank(),
axis.text.y = element_blank(),
axis.text.x = element_blank(),
panel.border = element_blank(),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank( ),
panel.background = element_rect(fill =white),
plot.margin = unit(c(-2,0,-2,-.1),cm),
$ legend_position =none)+
scale_x_discrete(limits = c(0,1))

final< - arrangeGrob(p2,p1,layout_matrix = rbind(c (1),c(2)),
w idths = c(4),heights = c(2.5,4),respect = TRUE)

在最后的代码中,我将您在排列Grob中从p1,p2到p2,p1的顺序颠倒过来。然后我调整了绘制的第一个对象的高度,这是我们想缩小的那个。此调整允许较早的plot.margin调整生效,并且在生效时,最后按顺序打印的图表(即P1)将开始占用P2的边距的空间。如果您将其中一项调整与其他调整一起进行,则解决方案将无法工作。上述每个步骤对产生上述最终结果都很重要。


I have a use-case similar to the following where I create multiple plots and arrange them into some page layout using gridExtra to finally save it as a PDF with ggsave:

p1 <- generate_ggplot1(...)
p2 <- generate_ggplot2(...)

final <- gridExtra::arrangeGrob(p1, p2, ...)
ggplot2::ggsave(filename=output.file,plot=final, ...)

Is it possible to have plot p2 cropped while arranging it into the page layout with arrangeGrob? The problem is that p2 has a lot of extra space on the top and bottom of it that I'd like to get rid of and since cropping doesn't seem viable using ggplot2 only I was thinking maybe is possible to crop it while arranging it ...

UPDATE Here is a self-contained example of my use-case, I'd like to get rid of the areas annotated red by whatever means:

library(ggplot2); library(dplyr); library(stringr); library(gridExtra)

df <- data.frame(group = c("Cars", "Trucks", "Motorbikes"),n = c(25, 25, 50),
                 label2=c("Cars are blah blah blah", "Trucks some of the best in town", "Motorbikes are great if you ..."))
df$ymax = cumsum(df$n)
df$ymin = cumsum(df$n)-df$n
df$ypos = df$ymin+df$n/2
df$hjust = c(0,0,1)

p1 <- ggplot(mtcars,aes(x=1:nrow(mtcars),y=mpg)) + geom_point()

p2 <- ggplot(df %>%
         mutate(label2 = str_wrap(label2, width = 10)), #change width to adjust width of annotations
       aes(x="", y=n, fill=group)) +
  geom_rect(aes_string(ymax="ymax", ymin="ymin", xmax="2.5", xmin="2.0")) +
  expand_limits(x = c(2, 4)) + #change x-axis range limits here
  # no change to theme
  theme(axis.title=element_blank(),axis.text=element_blank(),
        panel.background = element_rect(fill = "white", colour = "grey50"),
        panel.grid=element_blank(),
        axis.ticks.length=unit(0,"cm"),axis.ticks.margin=unit(0,"cm"),
        legend.position="none",panel.spacing=unit(0,"lines"),
        plot.margin=unit(c(0,0,0,0),"lines"),complete=TRUE) +
  geom_text(aes_string(label="label2",x="3",y="ypos",hjust="hjust")) +
  coord_polar("y", start=0) +
  scale_x_discrete()

final <- arrangeGrob(p1,p2,layout_matrix = rbind(c(1),c(2)),
                     widths=c(4),heights=c(4,4), padding=0.0,
                     respect=TRUE, clip="on")
plot(final)

And the output is:

解决方案

For this, there's a multi-part solution needed.

First, for changing the margins in a single graph, using plot.margin inside theme() is a convenient way. However, this alone won't solve the issue if the goal is to combine multiple plots.

To do that you'll need a combination of plot.margin and a specific plotting order within arrangeGrob(). You'll need a specific order because plots get printed in the order you call them, and because of that, it will be easier to change the margins of plots that are layered behind other plots, instead of in front of plots. We can think of it like covering the plot margins we want to shrink by expanding the plot on top of the one we want to shrink. See the graphs below for illustration:

Before plot.margin setting:

#Main code for the 1st graph can be found in the original question.

After plot.margin setting:

#Main code for 2nd graph:
ggplot(df %>%
           mutate(label2 = str_wrap(label2, width = 10)),
                  aes(x="", y=n, fill=group)) +
  geom_rect(aes_string(ymax="ymax", ymin="ymin", xmax="2.5", xmin="2.0")) +
  geom_text(aes_string(label="label2",x="3",y="ypos",hjust="hjust")) +
  coord_polar(theta='y') +
  expand_limits(x = c(2, 4)) + 
  guides(fill=guide_legend(override.aes=list(colour=NA))) +
  theme(axis.line = element_blank(),
        axis.ticks=element_blank(),
        axis.title=element_blank(),
        axis.text.y=element_blank(),
        axis.text.x=element_blank(),
        panel.border = element_blank(),
        panel.grid.major = element_blank(),
        panel.grid.minor = element_blank(),
        panel.background = element_rect(fill = "white"),
        plot.margin = unit(c(-2, 0, -2, -.1), "cm"),
        legend.position = "none") +
 scale_x_discrete(limits=c(0, 1))

After combining plot.margin setting and arrangeGrob() reordering:

#Main code for 3rd graph:
p1 <- ggplot(mtcars,aes(x=1:nrow(mtcars),y=mpg)) + geom_point()

p2 <- ggplot(df %>%
               mutate(label2 = str_wrap(label2, width = 10)), #change width to adjust width of annotations
                      aes(x="", y=n, fill=group)) +
        geom_rect(aes_string(ymax="ymax", ymin="ymin", xmax="2.5", xmin="2.0")) +
        geom_text(aes_string(label="label2",x="3",y="ypos",hjust="hjust")) +
        coord_polar(theta='y') +
        expand_limits(x = c(2, 4)) + #change x-axis range limits here
        guides(fill=guide_legend(override.aes=list(colour=NA))) +
        theme(axis.line = element_blank(),
              axis.ticks=element_blank(),
              axis.title=element_blank(),
              axis.text.y=element_blank(),
              axis.text.x=element_blank(),
              panel.border = element_blank(),
              panel.grid.major = element_blank(),
              panel.grid.minor = element_blank(),
              panel.background = element_rect(fill = "white"),
              plot.margin = unit(c(-2, 0, -2, -.1), "cm"),
              legend.position = "none") +
        scale_x_discrete(limits=c(0, 1))

final <- arrangeGrob(p2,p1,layout_matrix = rbind(c(1),c(2)),
                     widths=c(4),heights=c(2.5,4),respect=TRUE)

Note that in the final code, I reversed the order you had in the arrangeGrob from p1,p2 to p2,p1. I then adjusted the height of the first object plotted, which is the one we want to shrink. This adjustment allows the earlier plot.margin adjustment to take effect, and as that takes effect, the graph printed last in order, which is P1, will start to take the space of what was the margins of P2. If you make one of these adjustments with out the others, the solution won't work. Each of these steps are important to produce the end result above.

这篇关于在进行布置时是否可以裁剪一块地块?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆