用 grid 和 gtable 拆解 ggplot

2023-12-08

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

  1. 如何删除所有数据grobs,同时保留轴、轴标签、轴刻度线和网格线?我所说的“数据”是指与以下内容相关的数据geom_line() and 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)

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

enter image description here

Edit:按照巴蒂斯特的建议,我尝试删除数据层。然而,正如 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)将会:

enter image description here

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

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))

更自然的策略是使用隐形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))
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

用 grid 和 gtable 拆解 ggplot 的相关文章

  • R中按字母顺序对每一行字符串进行排序

    我环顾四周 似乎找不到解决这个问题的好方法 我有一个包含行名称的列 我想按字母顺序对每一行进行排序 以便稍后可以识别具有相同名称但顺序不同的行 数据如下 names lt c John D Josh C Karl H John D Bob
  • 在 R 中将列表列表转换为数据帧:Tidyverse 方式

    我正在寻找将列表列表转换为 R 中的数据帧的 Tidyverse 方法 Create a list of lists a lt seq 1 10 1 b lt seq 1 20 2 Function to calculate the sum
  • 在字符串中每个字母后面添加数字

    我有几个具有固定格式的字符串 格式为一个字母后跟一个数字 例如 A3B1C7D1 但是 如果字母后面的数字为 1 则字符串将写为 A3BC7D 我想做的是插入数字 1 然后将字符串转换为A3BC7D to A3B1C7D1 我的示例数据是
  • sapply 函数从命名向量中的值填充数据帧的列,需要很长时间。有更快的方法吗?

    这是我正在做的一个例子 x lt c a 2 b 4 c 2 d 9 df lt data frame names c d c a b x是一个命名向量 其值的顺序与它们在中出现的顺序不同df names 我需要在数据框中形成一个新列 该列
  • 在ggplot2中添加边框或背景以缩放图例guide_colorbar

    我在 ggplot 图中有一个从白色到红色的颜色条 并且白色边框在白色背景上不太明显 有没有办法对图例中的刻度线进行不同的着色或在渐变比例周围添加边框 这是一个最小的例子 df lt data frame x lt rnorm 10 y l
  • 使用 RSQLite 在 R 中加载 SQLite 表

    我有这个函数用来加载 SQLite 表 sqLiteConnect lt function database table library DBI library RSQLite con lt dbConnect SQLite dbname
  • rvest - 在 1 个标签中抓取 2 个类

    我是新来的 如何提取标签中具有 2 个类名或仅 1 个类名的元素 这是我的代码和问题 doc lt paste span class a1 b1 text1 span span class b1 text2 span library rve
  • 在 ggplot2 中,如何将堆叠直方图中的小值条形组合在一起?

    示例数据 tmp df lt data frame a rnorm 100 0 1 b rnorm 100 0 5 1 c rnorm 100 0 5 1 d rnorm 100 1 1 e rnorm 100 1 1 gt tidyr g
  • R闪亮的html小部件之间的交互

    我正在开发一个 R 闪亮应用程序 它使用多个 html 小部件 特别是网络D3 d3热图 and 和弦诊断 这些小部件单独工作正常 但是 在同一页面中使用它们会留下一个空格处他们应该在哪里 这是显示错误的可重现代码 在 UI 中注释绘图线
  • r : 直方图上的 ECDF

    在 R 中 与ecdf我可以绘制经验累积分布函数 plot ecdf mydata 与hist我可以绘制数据的直方图 hist mydata 如何在同一图中绘制直方图和 ecdf EDIT 我尝试做类似的东西 https mathemati
  • Shiny 中的模态对话框:可以调整宽度但不能调整高度

    在我的 Shiny 应用程序中 我有几个来自闪亮BS 包的模式窗口 我可以像这样调整这些模式窗口的宽度 tags head tags style HTML modal lg width 1200px abs 1 background col
  • R:错误消息---包错误:“functionName”未从当前命名空间解析

    我正在使用一个一直运行到 R3 0 的软件包 问题如上所述 当我们调用在 R 2 15 2 中工作的函数时 从 R 3 0 开始我们得到一个错误 Error in C solarspectrum3 as double lon as doub
  • 单击并按住 R 中的按钮闪亮?

    我希望能够通过单击 R 闪亮按钮来更改参数的值 所以我需要按钮 一个用于增加值 一个用于减少值 我想在按住按钮的同时保持值以一定的速度减少 增加 通过释放按钮的点击 动作应该停止 到目前为止我还没有找到这个选项actionButtons在
  • 在 for 循环中绘制的多个 ggplot2 绘图的网格

    作为一个新的 ggplot2 用户 我对可能性的数量感到有点迷失 并且很难在网上找到我认为简单问题的简单答案 我想在同一张纸上显示 ggplot2 的多个图 但知道这些图来自 for 循环 以下示例无法编译 仅用于说明 for i in c
  • R 中大型稀疏矩阵的聚类分析

    我有一个包含 250000 笔交易 行 和 2183 项 列 的交易数据集 我想将其转换为稀疏矩阵 然后对其进行分层聚类 我尝试了包 sparcl 但它似乎不适用于稀疏矩阵 关于如何解决这个问题有什么建议吗 或者我可以使用任何其他包对稀疏矩
  • 包检查时如何有效处理未压缩的保存?

    在最近开发一个包的过程中 我将数据集包含在data 我的包的文件夹 在我的具体情况下 我有 5 个数据集 所有这些数据集都位于data table格式 尽管我在下面描述的问题仍然存在 如果我将它们保留为data frame 我已将每个人单独
  • R比例置信区间因子

    我正在尝试总结家庭调查的数据 因此我的大部分数据都是分类 因子 数据 我想用对某些问题的回答频率图来总结它 例如 回答某些问题的家庭百分比的条形图 误差线显示置信区间 我发现了这个很棒的教程 我认为它是我祈祷的答案 http www coo
  • 正则表达式挑选括号之间的一些文本[重复]

    这个问题在这里已经有答案了 可能的重复 提取 R 中所有括号内的信息 正则表达式 https stackoverflow com questions 8613237 extract info inside all parenthesis i
  • 仅在具有重复块名称的另一个 Rmarkdown 文档中运行一个 Rmarkdown 文档中的代码

    我正在 Rmarkdown 中编写一系列相互补充的报告 我想将上一份报告的结果纳入我目前正在编写的报告中 我看到其他建议使用的问题purl从 Rmarkdown 文档中提取 R 代码然后运行它 所以我尝试了以下操作 r read previ
  • r Shiny 中的 fileInput 函数没有响应

    我是 R 和 R闪亮的新手 一直致力于构建一个统计应用程序 该应用程序将允许用户导入文件 然后对数据运行不同的统计程序 直到最近 fileData 函数一直对我来说运行良好 现在每当我尝试上传文件时 都不会打开任何内容 我已尝试了所有我能想

随机推荐