You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用grid.arrange堆叠含数据缺口的时间序列图?

Hey there! The issue you're running into is that base R's plot() function doesn't return a usable graphic object for grid.arrange()—it draws directly to the plotting device instead, so your plot1 and plot2 variables are actually NULL under the hood. Let's fix this with two solid approaches, depending on whether you want to stick with base R plotting or switch to a more flexible ggplot2 workflow:

Approach 1: Stack Plots with Base R (No Extra Packages Needed)

Base R has built-in layout tools that work perfectly for this. We'll use par(mfrow) to split the plotting area into 2 rows and 1 column, then draw each plot sequentially. We'll also tweak margins to prevent overlapping text and align the x-axes for clearer comparison:

# Set up 2-row, 1-column layout + adjust margins
par(mfrow = c(2, 1), mar = c(4, 4, 2, 1)) # mar = bottom, left, top, right margins

# Plot Cyber Attacks (leave x-label blank to avoid redundancy)
plot(allmerged$yearinitiated, allmerged$cyberattacks, 
     col = "black", xlab = "", ylab = "# of Cyber Attacks", 
     main = "Cyber Attacks over Time", type = "l",
     xlim = c(1992, 2016)) # Force x-axis to cover your full date range

# Plot MID Attacks (add x-label here for the bottom plot)
plot(allmerged$yearinitiated, allmerged$midaction, 
     col = "black", xlab = "Year", ylab = "# of MIDs", 
     main = "MIDs Attacks over Time", type = "l",
     xlim = c(1992, 2016)) # Match x-axis to first plot for alignment

# Reset layout to default for future plots
par(mfrow = c(1, 1))

Why this works:

  • par(mfrow=c(2,1)) tells R to render plots in a vertical 2-row grid.
  • Setting xlim = c(1992, 2016) ensures both plots share the same x-axis range, making it far easier to compare trends across years.
  • The mar parameter adjusts margins so your titles and axis labels don't overlap.

Approach 2: Use ggplot2 + gridExtra (Cleaner, More Customizable)

If you're open to using ggplot2, this method gives you more control over styling, and grid.arrange() works seamlessly with ggplot objects. Plus, ggplot automatically handles NA values by breaking the line where data is missing—perfect for highlighting those gaps in your dataset.

First, install and load the required packages:

install.packages(c("ggplot2", "gridExtra"))
library(ggplot2)
library(gridExtra)

Then create your plots and stack them:

# Cyber Attacks plot
plot1 <- ggplot(allmerged, aes(x = yearinitiated, y = cyberattacks)) +
  geom_line(color = "black") +
  labs(title = "Cyber Attacks over Time",
       x = "", y = "# of Cyber Attacks") +
  xlim(1992, 2016) +
  theme_minimal()

# MID Attacks plot
plot2 <- ggplot(allmerged, aes(x = yearinitiated, y = midaction)) +
  geom_line(color = "black") +
  labs(title = "MIDs Attacks over Time",
       x = "Year", y = "# of MIDs") +
  xlim(1992, 2016) +
  theme_minimal()

# Stack the two plots vertically
grid.arrange(plot1, plot2, nrow = 2)

Bonus: Even Simpler with Patchwork

For an even more intuitive syntax, swap gridExtra for the patchwork package—it's designed specifically for combining ggplot plots:

install.packages("patchwork")
library(patchwork)

# Stack plots with a single line of code
plot1 + plot2 + plot_layout(nrow = 2)

Key Notes:

  • ggplot ignores NA values in geom_line(), so the line will automatically stop/start where your data has gaps—exactly what you need to show when each dataset begins and ends.
  • Using xlim(1992, 2016) ensures both plots align perfectly along the year axis, making trend comparison straightforward.

内容的提问来源于stack exchange,提问作者newtoR

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:34:27