Rmarkdown在ggplots

时间:2017-05-31 08:34:56

标签: r ggplot2 r-markdown

虽然我在这里使用水平条形图作为例子,但这本身并不是问题。一般问题是如何处理使用

后在rmarkdown中围绕ggplots创建的空白区域
  

+ coord_fixed(比率= ...)

为了减少条形图所使用的空间,特别是几个因素,我更喜欢水平条纹,我使用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

enter image description here

fig.height = 1

enter image description here

fig.height = 0.5

enter image description here

我希望它能做什么:

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

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

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

2 个答案:

答案 0 :(得分:2)

您可以将参数传递给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'))

```

结果: enter image description here

答案 1 :(得分:0)

我认为,您需要找到高度和宽度之间的良好比例。但这有时候并不容易 前段时间,我写了一个函数来删除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)
}

如果这可以帮助......