2

ggplot我正在努力构建基于对象的双轴图。在巴蒂斯特的建议下,我将问题分解为更小的部分。目前的问题是:

  1. 如何从 中删除所有数据grobs,同时保留轴、轴标签、轴刻度线和网格线?“数据”是指与geom_line()和相关联的数据geom_points()

想要这样做的原因是,在构建双轴绘图的过程中,我遇到了以下问题:一个 grob 的网格线会覆盖另一个 grob 的数据。通过删除数据线和点,不会有覆盖。

让我明确一点:我确实有解决方法,包括向 aes() 添加线型并设置 scale_linetype_manual(values = c("solid", "blank") 或者,将数据“脱离网格”发送,但是我想对一个没有被“修饰”太多以达到手头目的的绘图对象进行后期处理。

下面是一些代码和数字。

# Data
df <- structure(list(Year = c(1950, 2013, 1950, 2013), Country = structure(c(1L, 
1L, 2L, 2L), .Label = c("France", "United States"), class = "factor"), 
Category = c("Hourly minimum wage", "Hourly minimum wage", 
"Hourly minimum wage", "Hourly minimum wage"), value = c(2.14, 
9.43, 3.84, 7.25), variable = c("France (2013 euros)", 
"France (2013 euros)", "United States (2013 dollars)", "United States (2013 dollars)"
), Unit = c("2013 euros", "2013 euros", "2013 dollars", "2013 dollars"
)), .Names = c("Year", "Country", "Category", "value", "variable", 
"Unit"), row.names = c(NA, 4L), class = "data.frame")

# Plot data with ggplot
library(ggplot2)
p <- ggplot(data = df, aes(x = Year, y = value, group = variable, colour = variable, shape = variable)) + 
geom_line(size = 2) + 
geom_point(size = 4) +
theme(panel.grid.major = element_line(size = 1, colour = "darkgreen"), 
      panel.grid.minor = element_line(size = 1, colour = "darkgreen", linetype = "dotted"))

# Manipulate grobs with gtable
library(gtable)
g <- ggplot_gtable(ggplot_build(p))
## Here remove the geom_line() and geom_point()
## g <- stripdata(g)  # pseudo-code!
grid.newpage()
grid.draw(g)

在下面的情节中,我希望线条消失!

在此处输入图像描述

编辑:按照 baptiste 的建议,我尝试删除数据层。然而,正如 BondedDust 在评论部分指出的那样,这破坏了 ggplot 对象:

# Remove the two layers of data
p$layers[[1]] <- NULL
p$layers[[1]] <- NULL
g <- ggplot_gtable(ggplot_build(p))
## Error: No layers in plot

从 ggplot 对象中删除数据会破坏它。我在应用程序中使用的一种解决方法是“将数据发送到网格之外”,例如将每个单元格乘以 -999999 并用 切断显示+ scale_y_continuous(limits = c(1, 10)),但如果可行的话,我想避免这种丑陋的黑客攻击。我希望如果我用 NA 或 NULL 替换每个数据点,关联的 gtable 不会被破坏,所以这就是为什么我正在寻找一种从 g 对象内部而不是 p 对象中删除数据的方法。

在操纵 grobs 之后(而不是直接破解 ggplot 对象),结果grid.draw(g)将是:

在此处输入图像描述

仅供参考,第二个情节是通过以下解决方法获得的。

p <- ggplot(data = within(df, value <- -999999), aes(x = Year, y = value, group = variable, colour = variable, shape = variable)) + 
geom_line() + 
geom_point() +
theme(panel.grid.major = element_line(size = 1, colour = "darkgreen"), 
      panel.grid.minor = element_line(size = 1, colour = "darkgreen", linetype = "dotted")) +
scale_y_continuous(limits = c(1, 10))
4

1 回答 1

5

更自然的策略是使用不可见的geom_blank图层,这样 ggplot2 仍然可以训练比例等来构建绘图,但不显示任何数据。但是,由于您要处理已经格式化的图,您可能必须从图 gTree 中手动删除这些 grobs。这是一个尝试,

library(gtable)
g <- ggplotGrob(p)

stripdata <- function(g){
  keep <- grepl("border|grill", 
                names(g[["grobs"]][[4]][["children"]]))
  g[["grobs"]][[4]][["children"]][!keep] <- NULL
  g
}

grid.newpage()
grid.draw(stripdata(g))
于 2015-01-03T12:53:56.313 回答