引言
与 ChatGPT 在有限轮数的提问内(ChatGPT-4o 只能有限免费使用),让它使用 R 语言中的 ggplot2 包,重现给定的统计图。最后,让 ChatGPT 整理整个对话。
用户提问 ChatGPT-4o
请仔细观察这张统计图*。然后,使用 R 语言的 ggplot2 包复现这张图。
*该图来自以下论文图 6,
Soil nitrogen and phosphorus regulate decomposition of organic nitrogen compounds in the rothamsted experiment
助手回答
好的,我将帮助你使用 ggplot2 包复现这张图。首先,我们需要创建一个数据框来表示图中的数据,然后使用 ggplot2 来绘制图形。
# 加载必要的包
library(ggplot2)
# 创建数据框
data <- data.frame(
Category = factor(rep(c("Protein", "Peptides", "Amino acids"), 2)),
Time = rep(c("0 - 6 h", "6 h - 15 d"), each = 3),
Increase = c(1, 10, 11, 1, 8, 5) # 根据图中的值进行调整
)
# 创建图形
ggplot(data, aes(x = Category, y = Increase, fill = "Microbial effects")) +
geom_bar(stat = "identity", position = "dodge", color = "black") +
facet_wrap(~Time, scales = "free") +
scale_y_continuous(name = "Increase in MSE (%)", limits = c(0, 12), breaks = seq(0, 12, 2)) +
scale_fill_manual(values = c("Microbial effects" = "orange")) +
theme_minimal() +
theme(
axis.title.x = element_blank(),
axis.text.x = element_text(angle = 0, hjust = 0.5),
strip.text = element_text(size = 12),
legend.position = "top",
legend.title = element_blank()
)
用户提问
请注意 x 轴因子的顺序。
助手回答
我们可以通过设置因子的水平来调整 x 轴因子的顺序。
修改 x 轴因子顺序后的代码
# 创建数据框并调整因子顺序
data <- data.frame(
Category = factor(rep(c("Protein", "Peptides", "Amino acids"), 2),
levels = c("Protein", "Peptides", "Amino acids")
),
Time = rep(c("0 - 6 h", "6 h - 15 d"), each = 3),
Increase = c(1, 10, 11, 1, 8, 5) # 根据图中的值进行调整
)
# 创建图形
ggplot(data, aes(x = Category, y = Increase, fill = "Microbial effects")) +
geom_bar(stat = "identity", position = "dodge", color = "black") +
facet_wrap(~Time, scales = "free") +
scale_y_continuous(name = "Increase in MSE (%)", limits = c(0, 12), breaks = seq(0, 12, 2)) +
scale_fill_manual(values = c("Microbial effects" = "orange")) +
theme_minimal() +
theme(
axis.title.x = element_blank(),
axis.text.x = element_text(angle = 0, hjust = 0.5),
strip.text = element_text(size = 12),
legend.position = "top",
legend.title = element_blank()
)
用户提问
很好。注意到 x 轴不同分类之间,每个 panel 有 4 条超出 panel 底部的竖直线段分隔,ggplot2 怎么实现这种区隔效果?这可能有点难,但是请你帮我思考解决方案。
助手回答
为了在 ggplot2 中实现这种效果,我们可以手动添加竖直线段。
添加竖直线段分隔
# 创建基础图形
p <- ggplot(data, aes(x = Category, y = Increase, fill = "Microbial effects")) +
geom_bar(stat = "identity", position = "dodge", color = "black") +
facet_wrap(~Time, scales = "free") +
scale_y_continuous(name = "Increase in MSE (%)", limits = c(0, 12), breaks = seq(0, 12, 2)) +
scale_fill_manual(values = c("Microbial effects" = "orange")) +
theme_minimal() +
theme(
axis.title.x = element_blank(),
axis.text.x = element_text(angle = 0, hjust = 0.5),
strip.text = element_text(size = 12),
legend.position = "top",
legend.title = element_blank(),
panel.grid.major.x = element_blank(),
panel.grid.minor.x = element_blank(),
plot.margin = unit(c(1, 1, 2, 1), "lines") # 增加底部边距
)
# 手动添加竖直线段分隔
p +
geom_segment(aes(x = 1.5, xend = 1.5, y = -0.5, yend = -0.05),
color = "black", size = 0.5, inherit.aes = FALSE
) +
geom_segment(aes(x = 2.5, xend = 2.5, y = -0.5, yend = -0.05),
color = "black", size = 0.5, inherit.aes = FALSE
) +
geom_segment(aes(x = 1.5 + 3, xend = 1.5 + 3, y = -0.5, yend = -0.05),
color = "black", size = 0.5, inherit.aes = FALSE
) +
geom_segment(aes(x = 2.5 + 3, xend = 2.5 + 3, y = -0.5, yend = -0.05),
color = "black", size = 0.5, inherit.aes = FALSE
) +
coord_cartesian(ylim = c(-0.5, 12)) # 扩展 y 轴以显示超出面板底部的线段
Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
ℹ Please use `linewidth` instead.
可以注意到,此处 ChatGPT 显然没实现任务,继续。
用户提问
注意,线段是超出 panel 底部,以区隔 x 轴标签,而不是在 panel 内部!
助手回答
为了在 panel 底部添加超出的竖直线段,我们需要调整 coord_cartesian()
以确保这些线段在绘图区域内可见。可以通过 annotate()
添加这些线段。
使用 annotate 添加竖直线段分隔
# 添加竖直线段分隔
p +
annotate("segment", x = 1.5, xend = 1.5, y = -2, yend = 0, color = "black", size = 0.5) +
annotate("segment", x = 2.5, xend = 2.5, y = -2, yend = 0, color = "black", size = 0.5) +
annotate("segment", x = 0.5, xend = 0.5, y = -2, yend = 0, color = "black", size = 0.5) +
annotate("segment", x = 3.5, xend = 3.5, y = -2, yend = 0, color = "black", size = 0.5) +
coord_cartesian(ylim = c(0, 12), clip = "off") # 扩展 y 轴并禁用裁剪
Warning: Removed 2 rows containing missing values or values outside the scale range
(`geom_segment()`).
用户介入
此时,又经过了几轮对话,ChatGPT-4o 没能在有限的免费对话中完成任务。不过,已经很接近了,只需要稍微人为介入即可完成。
# 创建基础图形
p0 <- ggplot(data, aes(x = Category, y = Increase, fill = "Microbial effects")) +
geom_bar(stat = "identity", position = "dodge", color = "black") +
facet_wrap(~ Time, switch = "x") +
scale_x_discrete(expand = c(0, 0)) +
scale_y_continuous(name = "Increase in MSE (%)", expand = c(0, 0)) +
scale_fill_manual(name = NULL, values = c("Microbial effects" = "orange")) +
theme_bw(
base_size = 16,
base_family = "Prompt"
) +
theme(
plot.margin = unit(c(1, 1, 2, 1), "lines"), # 增加底部边距
strip.background = element_blank(),
strip.placement = "outside",
panel.grid = element_blank(),
axis.title.x = element_blank(),
axis.text.x = element_text(angle = 0, hjust = 0.5),
legend.background = element_blank(),
legend.position = c(0, 1),
legend.justification = c(0, 1)
)
Warning: The `switch` argument of `facet_wrap()` is deprecated as of ggplot2 2.2.0.
ℹ Please use the `strip.position` argument instead.
Warning: A numeric `legend.position` argument in `theme()` was deprecated in ggplot2
3.5.0.
ℹ Please use the `legend.position.inside` argument of `theme()` instead.
# 添加竖直线段分隔
p1 <- p0 +
annotate("segment", x = 1.5, xend = 1.5, y = -0.9, yend = 0, color = "black", lwd = 0.7) +
annotate("segment", x = 2.5, xend = 2.5, y = -0.9, yend = 0, color = "black", lwd = 0.7) +
annotate("segment", x = 0.5, xend = 0.5, y = -1.5, yend = 0, color = "black", lwd = 0.7) +
annotate("segment", x = 3.5, xend = 3.5, y = -1.5, yend = 0, color = "black", lwd = 0.7) +
coord_cartesian(ylim = c(0, 12), clip = "off")
p1
ggsave("use-gpt-rep-fig.png", p1, width = 8.5, height = 5, dpi = 600)
用户提问
请将以上所有对话,整理为 Rmd(Quarto)文档:区分标题、正文、以及代码块。
助手回答
好的,以下**是整理后的 Rmd 文档内容:……
**这篇推文大部分来自 ChatGPT 整理。
结语
值得注意的是,提问的方式会决定回答质量。这里的对话可能不是最优的,如果要更高效地与 ChatGPT 对话,可以参考网络上的提问攻略。