如何在一个 ggplot 上绘制两个不同的列?

How to graph two different columns on one ggplot?

我正在尝试通过 Date 绘制一列(每种动物类别的不同颜色点),并在同一图表上,也通过 Date 绘制第二列。第二列包含日期的条目,但仅针对某些类别,Large Dog。小型或中型犬没有 adoption_with_discount(请参阅可重现的示例数据集,example_data)。当我分别绘制它们时,它们的视觉效果很好,但绘制在一起时却不是。我以为我会覆盖一个单独的 geom 但这不起作用。

我想把两个地块合二为一。我的目标是让点图在其顶部有折线图。我试图将 adoption 可视化为由 animal 着色的点,并在 adoption_with_discount.

的同一张图上画一条线

感谢您的帮助!


# Make example  -----------------------------------------------------------
# Here is an example data set
# You can see in the `adoption_with_discount` the values I want to add as a line. 

library(lubridate)
library(tidyverse)

example_days <- data.frame(Date = c(seq.Date(from = as.Date('2022-03-01'), to = as.Date('2022-04-30'), by = 'days')))


example_small <-
  example_days %>%
  mutate(animal = "Small Dog")


a <-sample(100:150, nrow(example_small), rep = TRUE)

example_small <-
  example_small %>%
  mutate(adoption = a,
         adoption_with_discount = NA)

example_med <-
  example_days %>%
  mutate(animal = "Medium Dog")

b <-sample(150:180, nrow(example_med), rep = TRUE)

example_med <-
  example_med %>%
  mutate(adoption = b,
         adoption_with_discount = NA)


example_large <-
  example_days %>%
  mutate(animal = "Large Dog")


c <-sample(150:200, nrow(example_large), rep = TRUE)


example_large <-
  example_large %>%
  mutate(adoption = c)

example_large <-
  example_large %>%
  mutate(adoption_with_discount = adoption - 15)


example_data <- rbind(example_small, example_med, example_large)



# Plot --------------------------------------------------------------------

ggplot(data = example_data) +
  geom_point(mapping = aes(x = Date, 
             y = adoption,
             color = animal)) +
  ggtitle("Dog Adoption by Size") +
  labs(x = "Date", y = "Adoption Fee") +
  scale_y_continuous(labels = scales::dollar) +
  theme(axis.text.x = element_text(angle = 45))

# Plot with Fee -----------------------------------------------------------
# This is where the problem is occurring
# When I want to add a line that plots the adoption with discount by day
# on top of the points, it does not populate. 

ggplot(data = example_data) +
  geom_point(mapping = aes(x = Date, 
                           y = adoption,
                           color = animal)) +
  geom_line(mapping = aes(x = Date, 
                          y = adoption_with_discount), 
            color = "black") +
  ggtitle("Dog Adoption by Size with Discount Included") +
  labs(x = "Date", y = "Adoption Fee") +
  scale_y_continuous(labels = scales::dollar) +
  theme(axis.text.x = element_text(angle = 45))



# See if just Discount will Plot  -----------------------------------------
#This plots separately 
ggplot(data = example_large) +
  geom_line(mapping = aes(x = Date, 
                          y = adoption_with_discount), 
            color = "black") +
  ggtitle("Discount") +
  labs(x = "Date", y = "Adoption Fee") +
  scale_y_continuous(labels = scales::dollar) +
  theme(axis.text.x = element_text(angle = 45))


根据讨论 here,我发现您可以在 geom_lineaes 到 select 值中使用 subset 参数,这些值不是 [= adoption_with_discount 列中的 14=]s。

ggplot(data = example_data) +
  geom_point(mapping = aes(x = Date, 
                           y = adoption,
                           color = animal)) +
  geom_line(mapping = aes(x = Date, 
                          y = adoption_with_discount), 
            color = "black") +
  ggtitle("Dog Adoption by Size with Discount Included") +
  labs(x = "Date", y = "Adoption Fee") +
  scale_y_continuous(labels = scales::dollar) +
  theme(axis.text.x = element_text(angle = 45)) + 
  geom_line(mapping = aes(x = Date, 
                          y = adoption_with_discount, 
                          subset = !is.na(adoption_with_discount)), 
            color = "black") +
  ggtitle("Discount") +
  labs(x = "Date", y = "Adoption Fee") +
  scale_y_continuous(labels = scales::dollar) +
  theme(axis.text.x = element_text(angle = 45))

结果:

看起来是 geom_line 部分中包含的 NA 造成了问题,因此您可以在绘制线条之前将其过滤掉:

  geom_point(mapping = aes(x = Date, 
                           y = adoption,
                           color = animal)) +
  geom_line(data=example_data %>% filter(!is.na(adoption_with_discount)),
            mapping = aes(x = Date, 
                          y = adoption_with_discount), 
            color = "black") +
  ggtitle("Dog Adoption by Size with Discount Included") +
  labs(x = "Date", y = "Adoption Fee") +
  scale_y_continuous(labels = scales::dollar) +
  theme(axis.text.x = element_text(angle = 45))

虽然子集化是解决问题的一个选项,但没有绘制线条的原因仅仅是缺少分组,即在 geom_line 中,您试图将所有三种狗类型的观察结果绘制为一组或线。但是,由于 NA,不会显示任何行。解决这个问题的一个简单选择是在 group aes 上显式映射 animal。此外,我添加了 na.rm=TRUE 以消除有关已删除 NA 的警告。最后我通过添加 hjust=1:

右对齐你的轴标签
library(ggplot2)

ggplot(data = example_data) +
  geom_point(mapping = aes(
    x = Date,
    y = adoption,
    color = animal
  )) +
  geom_line(
    mapping = aes(
      x = Date,
      y = adoption_with_discount,
      group = animal
    ),
    color = "black",
    na.rm = TRUE
  ) +
  ggtitle("Dog Adoption by Size with Discount Included") +
  labs(x = "Date", y = "Adoption Fee") +
  scale_y_continuous(labels = scales::dollar) +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))