有没有办法用ggplot2在条形图中用线图绘制每个时期的变化?

时间:2021-01-20 18:27:43

标签: r ggplot2 bar-chart

我有以下代码打印 bar plot,显示 2000 年到 2019 年德国风能和光伏的累计装机容量。我想知道是否有办法在图中添加一条线显示每种技术在每个时期的差异?

library(ggplot2)

wind <- c(6095, 8754, 12001, 14609, 16629,
          18428, 20621, 22247, 23903, 25777,
          27190, 29060, 30989, 33729, 38115,
          41651, 45910, 50777, 52931, 53912)

pv <- c(110, 180, 324, 435, 1105, 2056, 2899,
        4170, 5120, 10566, 18006, 25916, 34077,
        36710, 37900, 39224, 40716, 42492, 45452, 49395)

year <- c(2000, 2001, 2002, 2003, 2004, 2005,
          2006, 2007, 2008, 2009, 2010, 2011,
          2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019)

df <- data.frame(year, wind, pv) %>%
  pivot_longer(cols = 2:3)

p1 <- ggplot(df, aes(fill=name, y=value, x=year)) + 
  geom_bar(position="stack", stat = "identity") +
  ylab("MW") + theme(axis.text.x = element_text(angle = 45, vjust = .6)) +
  scale_fill_discrete(name = "Technology", labels = c("wind", "pv"))

p1

1 个答案:

答案 0 :(得分:1)

首先按列或按技术计算滞后差异。以下两种方法中的任何一种都可以,第二种可能更具可读性。

df <- data.frame(year, wind, pv) %>%
  mutate(across(wind:pv, function(.x) {.x - lag(.x)})) %>%
  pivot_longer(-1)

df <- data.frame(year, wind, pv) %>%
  pivot_longer(-1) %>%
  group_by(name) %>%
  mutate(value = value - lag(value))

现在完全按照问题进行绘制。

p1 <- ggplot(df, aes(fill=name, y=value, x=year)) + 
  geom_bar(position="stack", stat = "identity") +
  scale_fill_discrete(name = "Technology", labels = c("wind", "pv")) +
  ylab("MW") + 
  theme(axis.text.x = element_text(angle = 45, vjust = .6))

p1

enter image description here


对于原始数据条和差异绘制为叠加线的图形,这里有一个解决方案。 data.frame df 首先创建,转换并通过管道传输到 ggplot。线条以不同深浅的红色和蓝色绘制。
另外,我颠倒了图例标签的顺序。

df <- data.frame(year, wind, pv)

df %>%
  pivot_longer(-1) %>%
  group_by(name) %>%
  mutate(value_diff = value - lag(value)) %>%
  ggplot(aes(x = year, fill = name)) +
  geom_bar(aes(y = value), position="stack", stat = "identity") +
  geom_line(aes(y = value_diff, color = name)) +
  scale_color_manual(name = "Technology", 
                     breaks = c("pv", "wind"), 
                     values = c("red", "blue")) +
  scale_fill_discrete(name = "Technology", labels = c("pv", "wind")) +
  ylab("MW") +
  theme(axis.text.x = element_text(angle = 45, vjust = .6))

enter image description here