【问题标题】:Layering ggplot分层ggplot
【发布时间】:2026-02-13 09:40:02
【问题描述】:

我需要将 3 条数据分层到一个图上。第一个时间序列层编码:

p<-ggplot(MI_FL_Data, aes(realdate, FLday))+geom_line()

下一层分别在 yintercept=15000 和 17000 处添加两条 geom_hlines。该层编码:

q<-ggplot(MI_FL_Data, aes( realdate, FL_Actions))+geom_point(na.rm = TRUE)

最后一层根据第二个代码中生成的 yintercept 处的分类变量 FL_Actions 绘制点。这段代码是:

r<-ggplot(MI_FL_Data, aes(realdate, FLday))+
  geom_hline(data = MI_FL_Data %>% filter(FL_Actions == 1), aes(yintercept = 15000), linetype=5, na.rm=TRUE)+ 
  geom_hline(data = MI_FL_Data %>% filter(FL_Actions == 2), aes(yintercept = 17000), linetype=1, na.rm=TRUE))

现在我需要将这些保存的向量中的每一个叠加在一个图中。当我使用代码时:

ggplot(MI_FL_Data, aes(realdate, FLday))+
  geom_hline(data=r)+
  geom_point(data=r)

我收到一个错误:data 必须是一个数据框,或者是由fortify() 强制转换的其他对象,而不是具有 gg/ggplot 类的 S3 对象。我认为通过保存每一层,将它们添加在一起会相当简单。有什么建议吗?我对 ggplot 有点陌生,但我想做的事情看起来相当直观,所以我很难过。

我已经添加了每一层的图像以防万一。

# data
structure(list(Date = c("1/22/20", "1/23/20", "1/24/20", "1/25/20", 
"1/26/20", "1/27/20", "1/28/20", "1/29/20", "1/30/20", "1/31/20", 
"2/1/20", "2/2/20", "2/3/20", "2/4/20", "2/5/20", "2/6/20", "2/7/20", 
"2/8/20", "2/9/20", "2/10/20", "2/11/20", "2/12/20", "2/13/20", 
"2/14/20", "2/15/20", "2/16/20", "2/17/20", "2/18/20", "2/19/20", 
"2/20/20"), Date2 = c("1/22/20", "1/23/20", "1/24/20", "1/25/20", 
"1/26/20", "1/27/20", "1/28/20", "1/29/20", "1/30/20", "1/31/20", 
"2/1/20", "2/2/20", "2/3/20", "2/4/20", "2/5/20", "2/6/20", "2/7/20", 
"2/8/20", "2/9/20", "2/10/20", "2/11/20", "2/12/20", "2/13/20", 
"2/14/20", "2/15/20", "2/16/20", "2/17/20", "2/18/20", "2/19/20", 
"2/20/20"), Date3 = c("1/22/20", "1/23/20", "1/24/20", "1/25/20", 
"1/26/20", "1/27/20", "1/28/20", "1/29/20", "1/30/20", "1/31/20", 
"2/1/20", "2/2/20", "2/3/20", "2/4/20", "2/5/20", "2/6/20", "2/7/20", 
"2/8/20", "2/9/20", "2/10/20", "2/11/20", "2/12/20", "2/13/20", 
"2/14/20", "2/15/20", "2/16/20", "2/17/20", "2/18/20", "2/19/20", 
"2/20/20"), FLORIDA = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), FLday = c(0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0), MICHIGAN = c(0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0), MIday = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), FL_Actions = c(NA_real_, 
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, 
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, 
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, 
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, 
NA_real_), MI_Actions = c(NA_real_, NA_real_, NA_real_, NA_real_, 
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, 
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, 
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, NA_real_, 
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_), realdate = structure(c(18283, 
18284, 18285, 18286, 18287, 18288, 18289, 18290, 18291, 18292, 
18293, 18294, 18295, 18296, 18297, 18298, 18299, 18300, 18301, 
18302, 18303, 18304, 18305, 18306, 18307, 18308, 18309, 18310, 
18311, 18312), class = "Date")), row.names = c(NA, -30L), class = c("tbl_df", 
"tbl", "data.frame"))

请注意,FL_Actions 在此数据集中显示为 NA。这是因为政策行动直到 3 月才发生并持续到 2020 年 11 月

这是使用建议代码创建的当前 ggplot:

ggplot(MI_FL_Data, aes(realdate, FLday)) + 
  geom_line()+ geom_label(data=MI_FL_Data, aes(label=FL_Actions), nudge_x = 0.50, nudge_y=.25, size=2, na.rm=TRUE)+
  geom_point(na.rm = TRUE) +
  geom_point(na.rm = TRUE) + 
  geom_hline(data = MI_FL_Data %>% filter(FL_Actions == 1),aes(yintercept = 15000), linetype=5, na.rm=TRUE) +
  geom_hline(data = MI_FL_Data %>% filter(FL_Actions == 2),aes(yintercept = 17000), linetype=1, na.rm=TRUE) +
  labs(x=NULL, y="Number of Reported Daily COVID Cases", title="State of Florida",caption="1= closing actions, 2= opening actions")+theme_classic()

更新建议。这是代码:ggplot(MI_FL_Data, aes(realdate, FLday)) + geom_line()+ geom_label(data=MI_FL_Data, aes(label=FL_Actions), nudge_x = 0.50, nudge_y=.25, size=2, na.rm=TRUE, y=15000)+geom_point(aes(realdate, 17000),na.rm = TRUE) + geom_point(aes(realdate, 15000), na.rm = TRUE) + geom_hline(data = MI_FL_Data %&gt;% filter(FL_Actions == 1),aes(yintercept = 15000), linetype=5, na.rm=TRUE) +geom_hline(data = MI_FL_Data %&gt;% filter(FL_Actions == 2),aes(yintercept = 17000), linetype=1, na.rm=TRUE)+labs(x=NULL, y="Number of Reported Daily COVID Cases", title="State of Florida",caption="1= closing actions, 2= opening actions")+theme_classic() 这是结果图:

【问题讨论】:

  • “FL_Actions 的标签显示在时间序列线上而不是水平线上” 它们从原始 ggplot() 继承 y = FLday。如果您希望它们具有其他 y 值,则需要在该层中指定它。也许geom_label(..., y = 15000)(保留你在该层中的所有其他东西)。
  • 这就是我想要的,但是...我看不到 y=15000 上的信息,因为上面有一些东西。我已将代码和生成的图像添加到原始问题中。只要标签可读,我个人就可以只使用一条线。

标签: r ggplot2


【解决方案1】:

您有 3 个地块,而不是 3 个图层。每次你使用ggplot(),你都在创建一个新的情节。图层只是几何图形。您只需将图层添加在一起,而不是完整的图:

ggplot(MI_FL_Data, aes(realdate, FL_Actions)) +
  geom_point(na.rm = TRUE) +
  geom_point(na.rm = TRUE) +
  geom_hline(
    data = MI_FL_Data %>% filter(FL_Actions == 1),
    aes(yintercept = 15000), linetype=5, na.rm=TRUE
  ) +
  geom_hline(
    data = MI_FL_Data %>% filter(FL_Actions == 2),
    aes(yintercept = 17000), linetype=1, na.rm=TRUE)
  )

我认为以上应该可行。如果它给您带来麻烦,请发布一个可重现的示例 - 例如与 dput 共享的 10 行数据,例如 dput(MI_FL_Data[1:10, ])

【讨论】:

  • 我认为geom_hlines 上的数据过滤是不必要的,因为它们只是静态水平线。
  • 这有点接近,但是正如您在生成的图表中看到的那样,FL_Actions 的标签显示在时间序列线上,而不是它们需要的水平线上。
  • 使用的代码是:ggplot(MI_FL_Data, aes(realdate, FLday)) + geom_line()+ geom_label(data=MI_FL_Data, aes(label=FL_Actions), nudge_x = 0.50, nudge_y=.25, size=2, na.rm=TRUE)+geom_point(na.rm = TRUE) + geom_point(na.rm = TRUE) + geom_hline(data = MI_FL_Data %&gt;% filter(FL_Actions == 1),aes(yintercept = 15000), linetype=5, na.rm=TRUE) +geom_hline(data = MI_FL_Data %&gt;% filter(FL_Actions == 2),aes(yintercept = 17000), linetype=1, na.rm=TRUE)+labs(x=NULL, y="Number of Reported Daily COVID Cases", title="State of Florida",caption="1= closing actions, 2= opening actions")+theme_classic()
  • 示例:# A tibble: 22 x 10 Date Date2 Date3 FLORIDA FLday MICHIGAN MIday FL_Actions MI_Actions realdate &lt;chr&gt; &lt;chr&gt; &lt;chr&gt; &lt;dbl&gt; &lt;dbl&gt; &lt;dbl&gt; &lt;dbl&gt; &lt;dbl&gt; &lt;dbl&gt; &lt;date&gt; 1 3/6/20 3/6/20 3/6/20 3 0 0 0 NA NA 2020-03-06 2 3/7/20 3/7/20 3/7/20 7 4 0 0 NA NA 2020-03-07 3 3/8/20 3/8/20 3/8/20 10 3 0 0 NA NA 2020-03-08 4 3/9/20 3/9/20 3/9/20 13 3 0 0 1 NA 2020-03-09
【解决方案2】:

用于生成下图的代码是:gplot(MI_FL_Data, aes(realdate, FLday)) + geom_line()+ geom_label(data=MI_FL_Data, aes(label=FL_Actions), na.rm=TRUE, y=15500)+ geom_point(aes(realdate, 15000), na.rm = TRUE) + geom_hline(data = MI_FL_Data %&gt;% filter(FL_Actions &gt;= 1),aes(yintercept = 15000), linetype=5, na.rm=TRUE)+labs(x=NULL, y="Number of Reported Daily COVID Cases", title="State of Florida",caption="1= closing actions, 2= opening actions")+theme_classic()

但是,hline 的大小仍然令人担忧,我不确定如何让粗体叠加层消失。欢迎对此提出任何建议。

【讨论】: