【问题标题】:Rmarkdown crop white space around ggplotsRmarkdown 裁剪 ggplots 周围的空白区域
【发布时间】:2017-05-31 08:34:55
【问题描述】:

虽然我在这里使用水平条形图作为示例,但这本身不是问题。一般问题是如何处理使用后在 rmarkdown 中围绕 ggplots 创建的空白

+coord_fixed(ratio=...)

为了减少条形图使用的空间,尤其是在很少因素的情况下,我更喜欢水平条形图,我使用 coord_fixed(ratio=...) 在条形的宽度和长度之间有一个合理的比率。

情节本身看起来像我想要的方式(见下面的第一个例子),但它周围有很多空白,我试图通过在 knitr-header 中使用 fig.height = ... 来删除它。正如下一个示例所示,结果并不理想。

library(ggplot2)
library(ggstance)
library(dplyr)

X <- data.frame(X = sample(c("A", "B"), 30, replace = TRUE))
X <- X %>% group_by(X) %>% summarise(n = n())
ggplot(X, aes(y = X, x = n))+
   geom_barh(stat = "identity")+
   coord_fixed(ratio = 1)+
   ggtitle("blub")

在我使用 x = 3 的 rmarkdown 中使用它; x = 1 ; x=0.5:

```{r,fig.height = x}

# see code above
```

这会导致:

fig.height=3

fig.height=1

fig.height=0.5

我希望它能做什么:

  • 裁剪白色边距
  • 同时保持绘图(绘图 +(轴)标题)区域本身不变

后者显然不会发生,因为情节区域变窄并且标题被移到情节内部。

我不知道是在 ggplot 中还是在 knitr 中找到解决方案。最重要的是,理想的解决方案应该很容易自动化,以便在循环内使用(使解决方案适应不断变化的因素数量)。

【问题讨论】:

  • 不确定这是否是您的真实代码,但它是 fig.height(您有 fig.heigth),因此可能无法按您希望的那样工作。
  • @sconfluentus 感谢您的注意,但检查真实代码,我可以说我在那里拼写正确。

标签: r ggplot2 r-markdown


【解决方案1】:

您可以将参数传递给fig.widthfig.height 块选项。您只需要在评估该块之前计算它们:

---
output: html_document
---

```{r, message=FALSE}
library(ggplot2)
library(ggstance)
library(dplyr)

X <- data.frame(X = sample(c("A", "B"), 30, replace = TRUE))
X <- X %>% group_by(X) %>% summarise(n = n())

hei <- length(X$X) + 1
len <- max(X$n) + 2

```

Text before the plot
```{r, fig.height=hei, fig.width=len, echo=FALSE}

ggplot(X, aes(y = X, x = n))+
  geom_barh(stat = "identity")+
  coord_fixed(ratio = 1)+
  ggtitle("blub") +
  theme(plot.background = element_rect(fill = 'red'))

```

Text after the plot

```{r, message=FALSE}

X <- data.frame(X = sample(c("A", "B", "C"), 30, replace = TRUE))
X <- X %>% group_by(X) %>% summarise(n = n())

hei <- length(X$X) + 1
len <- max(X$n) + 2

```
Another plot
```{r, fig.height=hei, fig.width=len, echo=FALSE}

ggplot(X, aes(y = X, x = n))+
  geom_barh(stat = "identity")+
  coord_fixed(ratio = 1)+
  ggtitle("blub") +
  theme(plot.background = element_rect(fill = 'red'))

```

结果:

【讨论】:

    【解决方案2】:

    我认为,您需要找到高度和宽度之间的良好比例。但这有时并不容易做到。
    前段时间,我写了一个函数来删除PNG图像的白边。如果你没有找到好的比例,你可以尝试使用这个。这需要使用函数 ggsave 将您的图形保存为 png,然后使用 knitr::include_graphics() 在后续块中调用它。
    函数如下:

    #' A function to crop white margins of a PNG image
    #'
    #' @param x path to the PNG image
    #' @param pixel number of white pixels lines to keep
    #' @export
    
    Rm_WhiteMargins <- function(x, pixel = 2)
    {
      # Cut the output image to remove dirty white margins from corrplot
      img <- png::readPNG(x)
    
      img.test.row <- apply(img, 3, function(layer) {
        apply(layer, 1, function(i) {(sum(i != 1) > 0)})
      }) %>%
        apply(., 1, function(i) {(sum(i) > 0)})
      rowMin <- max(min(which(img.test.row[1:round(length(img.test.row) / 2)])) - (1 + pixel), 1)
      rowMax <- min(max(c(1:length(img.test.row))[
        round(length(img.test.row) / 2) : length(img.test.row)][
          which(img.test.row[(length(img.test.row) / 2) : length(img.test.row)])]) + 1 + pixel,
        length(img.test.row))
    
      img.test.col <- apply(img, 3, function(layer) {
        apply(layer, 2, function(i) {(sum(i != 1) > 0)})
      }) %>%
        apply(., 1, function(i) {(sum(i) > 0)})
      colMin <- max(min(which(img.test.col[1:round(length(img.test.col) / 2)])) - (1 + pixel), 1)
      colMax <- min(max(c(1:length(img.test.col))[
        round(length(img.test.col) / 2) : length(img.test.col)][
          which(img.test.col[(length(img.test.col) / 2) : length(img.test.col)])]) + 1 + pixel,
        length(img.test.col))
    
      # Remove rows and cols with white pixels from the original image
      img <- img[rowMin:rowMax, colMin:colMax,]
      png::writePNG(img, target = paste0(gsub(".png", "", x), "_crop.png"))
      rm(img)
    }
    

    如果这可以帮助...

    【讨论】:

    • 感谢您的帮助,但我更喜欢一个不绕道保存和包含数字的解决方案
    • 我试过你的代码,它说以下错误 Sebastien: Error in apply(img, 3, function(layer) { : could not find function "%>%" Calls: Rm_WhiteMargins 执行停止
    • 您需要安装和加载软件包 dplyr 或至少为这个名为 pipe %>% 的函数的 magrittr