将不同年份的时间序列绘制在一起

Posted

技术标签:

【中文标题】将不同年份的时间序列绘制在一起【英文标题】:Plot time series of different years together 【发布时间】:2021-12-07 23:41:08 【问题描述】:

我正在尝试比较不同年份的变量,但无法将它们绘制在一起。 时间序列是一个温度序列,可以在 https://github.com/gonzalodqa/timeseries 中找到 temp.csv 我想绘制类似图像的东西,但我发现很难对年份之间的月份进行子集化,然后在相同月份下将同一图中的线条组合起来

如果有人能给我一些建议或指出正确的方向,我将不胜感激

【问题讨论】:

你已经尝试了什么? 鉴于您的数据非常干净,您只需学习正确的 ggplot 术语即可解决此问题。例如,您可以参考rpubs.com/Mentors_Ubiqum/ggplot_geom_line_1。如果您仍有疑问,请编辑问题 我试图绘制 ```` ggplot(temp,aes(date,t42,color=year)+geom_line```` 认为它可能每年单独绘制,但它没有。我认为我会检查链接。我对时间序列很陌生 问题是您不希望在 x 轴上使用 date,因为它希望将 1-2020 绘制在与 1-2021 不同的点上。如果您参考您在问题中发布的图片,您可以找出需要在 x 轴上的列 所以您希望图表从 7 月开始? 【参考方案1】:

你可以试试这个方法。

第一个图表显示所有可用温度,第二个图表按月汇总。

在第一个图表中,我们强制使用同一年份,以便ggplot 将它们对齐,但我们按颜色分隔线条。

对于第二个,我们只使用month 作为x 变量和year 作为colour 变量。

注意:

使用scale_x_datetime,我们可以隐藏年份,这样任何人都无法看到我们将 2020 年强制添加到每个观察值中 scale_x_continous 我们可以显示月份的名称而不是数字

[只需尝试在有和没有scale_x_... 的情况下运行图表,以了解我在说什么]

month.abb 是月份名称的有用默认变量。

# read data
df <- readr::read_csv2("https://raw.githubusercontent.com/gonzalodqa/timeseries/main/temp.csv")


# libraries
library(ggplot2)
library(dplyr)


# line chart by datetime
df %>% 
  # make datetime: force unique year
  mutate(datetime = lubridate::make_datetime(2020, month, day, hour, minute, second)) %>% 
  
  ggplot() +
  geom_line(aes(x = datetime, y = T42, colour = factor(year))) +
  scale_x_datetime(breaks = lubridate::make_datetime(2020,1:12), labels = month.abb) +
  labs(title = "Temperature by Datetime", colour = "Year")

# line chart by month
df %>% 
  
  # average by year-month
  group_by(year, month) %>% 
  summarise(T42 = mean(T42, na.rm = TRUE), .groups = "drop") %>% 
  
  ggplot() +
  geom_line(aes(x = month, y = T42, colour = factor(year))) +
  scale_x_continuous(breaks = 1:12, labels = month.abb, minor_breaks = NULL) +
  labs(title = "Average Temperature by Month", colour = "Year")


如果您希望图表从 7 月开始,您可以改用以下代码:

months_order <- c(7:12,1:6)

# line chart by month
df %>% 
  
  # average by year-month
  group_by(year, month) %>% 
  summarise(T42 = mean(T42, na.rm = TRUE), .groups = "drop") %>% 
    
  # create new groups starting from each July
  group_by(neworder = cumsum(month == 7)) %>% 
    
  # keep only complete years
  filter(n() == 12) %>% 
    
  # give new names to groups
  mutate(years = paste(unique(year), collapse = " / ")) %>% 
  ungroup() %>% 
  
  # reorder months
  mutate(month = factor(month, levels = months_order, labels = month.abb[months_order], ordered = TRUE)) %>% 
      
  # plot
  ggplot() +
  geom_line(aes(x = month, y = T42, colour = years, group = years)) +
  labs(title = "Average Temperature by Month", colour = "Year")


编辑

要获得与第一个情节类似但从 7 月开始的内容,您可以使用以下代码:

# libraries
library(ggplot2)
library(dplyr)
library(lubridate)


# custom months order
months_order <- c(7:12,1:6)

# fake dates for plot
# note: choose 4 to include 29 Feb which exist only in leap years
dates <- make_datetime(c(rep(3,6), rep(4,6)), months_order)

# line chart by datetime
df %>%
  
  # create date time
  mutate(datetime = make_datetime(year, month, day, hour, minute, second)) %>%
  
  # filter years of interest
  filter(datetime >= make_datetime(2018,7), datetime < make_datetime(2020,7)) %>%
  
  # create increasing group after each july
  group_by(year, month) %>%
  mutate(dummy = month(datetime) == 7 & datetime == min(datetime)) %>%
  ungroup() %>%
  mutate(dummy = cumsum(dummy)) %>%
  
  # force unique years and create custom name
  group_by(dummy) %>%
  mutate(datetime = datetime - years(year - 4) - years(month>=7),
         years = paste(unique(year), collapse = " / ")) %>%
  ungroup() %>%
  
  # plot
  ggplot() +
  geom_line(aes(x = datetime, y = T42, colour = years)) +
  scale_x_datetime(breaks = dates, labels = month.abb[months_order]) +
  labs(title = "Temperature by Datetime", colour = "Year")

【讨论】:

谢谢,这正是我所需要的。我正在查看提供的链接,但它对数据进行了平均,您提供的第一个数字显示了我正在寻找的内容 我尝试以 7-6 月格式绘制时间序列的第一次,但我得到的数字看起来很奇怪。我应该使用其他变异吗? 嗯,是的.. 等一下 好的,我对我的答案进行了新的编辑 那是亚马逊!非常感谢,这对我处理其他数据集有很大帮助【参考方案2】:

要以不同的方式对月份进行排序并总结几年内的值,您必须在绘制数据之前对数据进行一些处理:

library(dplyr)     # work data
library(ggplot2)   # plots
library(lubridate) # date
library(readr)     # fetch data

# your data
df <- read_csv2("https://raw.githubusercontent.com/gonzalodqa/timeseries/main/temp.csv")


  df %>%
  mutate(date = make_date(year, month,day)) %>%
  # reorder month
  group_by(month_2 = factor(as.character(month(date, label = T, locale = Sys.setlocale("LC_TIME", "English"))),
                            levels = c('Jul','Aug','Sep','Oct','Nov','Dec','Jan','Feb','Mar','Apr','May','Jun')),
           # group years as you like
           year_2   = ifelse( year(date) %in% (2018:2019), '2018/2019', '2020/2021')) %>%
  # you can put whatever aggregation function you need
  summarise(val = mean(T42, na.rm = T)) %>%
  # plot it!
  ggplot(aes(x = month_2, y = val, color = year_2, group = year_2)) + 
  geom_line()   + 
  ylab('T42')   +
  xlab('month') + 
  theme_light()

【讨论】:

谢谢,这正是我所需要的

以上是关于将不同年份的时间序列绘制在一起的主要内容,如果未能解决你的问题,请参考以下文章

添加多层刻度标签以绘制时间序列的 x 轴

按年份将数据汇总为每月计数

绘制两行,按年份统计发生的次数* Python *

我如何按时间顺序绘制 R 中年份变化的周?

用熊猫在列中绘制带有年份的数据框

在同一个条形图中按年份绘制多个变量