具有 2 个 y 轴(辅助 y 轴)的 2 个 ts 对象(时间序列)的 ggplot

Posted

技术标签:

【中文标题】具有 2 个 y 轴(辅助 y 轴)的 2 个 ts 对象(时间序列)的 ggplot【英文标题】:ggplot of 2 ts-objects (time series) with 2 y axes (secondary y-axis) 【发布时间】:2019-11-25 08:46:51 【问题描述】:

我想使用 2 个 y 轴将 2 个 ts 对象分别绘制为条形和线。我怎样才能在 ggplot 中做到这一点?

我有 2 个 ts-objects:一个是变量的值,另一个是年变化。数据为月度数据。我想将两个 ts 对象绘制成一个图形,值作为线,增长率作为条形。为此,我需要一个辅助 y 轴,因为这两个变量的比例非常不同。

我通常使用 ts.plot 绘制 ts 对象,它可以轻松容纳辅助 y 轴,但我无法绘制条形图,只能绘制线条。

使用 ggplot,我在纠结如何使用 ts-object... 使用 autoplot,我可以生成绘图和辅助轴,但后者似乎真的独立于我的数据。在下面的示例中,如何让线条和条形重叠?

# REPRODUCIBLE EXAMPLE
library(ggplot2)
library(ggfortify)  # to use autoplot
library(seasonal)  # to get the example ts data AirPassengers
library(dplyr)  # to use the pipe-operator

# Genereate year-on-year change
YearOverYear <- function (x,periodsPerYear)
if(NROW(x)<=periodsPerYear)
stop("too few rows")
 
 else
 indexes<-1:(NROW(x) - periodsPerYear)
return(c(rep(NA,periodsPerYear), (x[indexes+periodsPerYear]- x[indexes]) / x[indexes]))
  


AirPassengers.gr <- YearOverYear(AirPassengers, 12) %>%
              ts(., start = start(AirPassengers), frequency = 12)

p <- autoplot(AirPassengers, ts.geom = 'line', ts.colour = 'dodgerblue') 
autoplot(AirPassengers.gr*100, ts.geom = 'bar', ts.colour = 'red', p=p) +
  scale_y_continuous(sec.axis = sec_axis(~./1))

【问题讨论】:

【参考方案1】:

很高兴认识你,伊莎贝尔

我只是将ts.object 更改为data.table,然后使用基本的ggplot 方法。此外,您可以应用任何棘手的技能。

库加载

library(ggplot2)
library(ggfortify)  # to use autoplot
library(seasonal)  # to get the example ts data AirPassengers
library(dplyr)  # to use the pipe-operator
library(zoo);library(data.table)

数据处理

YearOverYear <- function (x,periodsPerYear)
  if(NROW(x)<=periodsPerYear)
    stop("too few rows")
  
  else
    indexes<-1:(NROW(x) - periodsPerYear)
    return(c(rep(NA,periodsPerYear), (x[indexes+periodsPerYear]- x[indexes]) / x[indexes]))
  


AirPassengers.gr <- YearOverYear(AirPassengers, 12) %>%
  ts(., start = start(AirPassengers), frequency = 12)
lubridate::as_date(time(AirPassengers))

DF = data.frame(Passengers = as.matrix(AirPassengers),
                date = zoo::as.Date(time(AirPassengers)))
DF.gr = data.frame(value = as.matrix(AirPassengers.gr),
                date = zoo::as.Date(time(AirPassengers.gr)))
DF = merge(DF,DF.gr, by = 'date')
setDT(DF)

绘制代码

scale_value = max(DF$Passengers, na.rm = TRUE)/ max(DF$value, na.rm = TRUE)

ggplot(DF) + 
  geom_line(aes(x= date, y= Passengers), color = 'dodgerblue') +
  geom_bar(aes(x= date, y = value*scale_value), stat = 'identity') + 
  scale_y_continuous(sec.axis = sec_axis(~./scale_value, name = 'NEW'))

如果您有任何问题,请随时提出。

【讨论】:

以上是关于具有 2 个 y 轴(辅助 y 轴)的 2 个 ts 对象(时间序列)的 ggplot的主要内容,如果未能解决你的问题,请参考以下文章

2 个 y 轴不同但 x 轴相同但范围不同的核心图

条形图,y 轴计数,x 轴年份,2 个颜色组

具有不同 y 轴的同一可视化中的 2 个线图

echarts实现动态y轴范围且平均等分辅助线

highchart应用示例1--2个不同类型变量2个y轴

求助excel制作图表高手 怎么制作双Y轴 也就是左边是百分比值 右边是数值?