ggplot2时间序列图表与背景阴影

时间:2016-04-16 18:31:59

标签: r charts ggplot2

我想在R中创建一个excel图。

Excel Chart

我尝试用一​​些虚拟数据重新创建它

a<-rnorm(12)
a_ts<-ts(a, start=c(2015, 1), frequency=12)
a_time<-time(a_ts)
a_series<-ts.union(ret=a_ts, date=a_time)
a_series_df<-as.data.frame(a_series)

ggplot() +
geom_rect(data=data.frame(xmin=decimal_date(as.Date(c("2015-01-01"))),
xmax=decimal_date(as.Date(c("2015-05-31"))), ymin=-Inf, ymax=Inf),
aes(xmin=xmin,xmax=xmax,ymin=ymin,ymax=ymax), fill="pink", alpha=0.5) +
geom_line(data = a_series_df, aes(x=date,y=ret, color='blue')) +
theme(axis.text.x=element_text(angle=90,hjust=1,vjust=0.5)) 
#this does not work
#scale_x_date(breaks = "1 month", minor_breaks = "1 month",   labels=date_format("%B-%d")) +
#scale_y_continuous(labels = scales::percent)

看起来像这样

R version

我正在努力进行日期转换,并将x和y原点设置为零并使轴标签正确,最后两行代码适用于非日期数据点。我还希望在图表下面有一个图例,用于series1,series2和阴影区域的条目。

任何帮助都将不胜感激。

应用建议后更新:

X axis should be at y = 0 everything else should stay as it is, as in the excel

3 个答案:

答案 0 :(得分:3)

下面是一个应该让你最好的方式的例子。这使用lubridate包来处理日期和时间(在本例中为Dates)。这向您展示了一种方法,您可以使用大多数请求的修改在同一绘图上绘制两条单独的线。在此示例中,使用了alpha 0.05

library(lubridate)
library(ggplot2)

### Set up dummy data.
dayVec     <- seq(ymd('2016-01-01'), ymd('2016-01-10'), by = '1 day')
set.seed(1234)
dayCount   <- length(dayVec)
dayValVec1 <- rnorm(dayCount)
dayValVec2 <- rnorm(dayCount)
dayDF      <- data.frame(Date = rep(dayVec, 2),
                         DataType = factor(c(rep('A', dayCount), rep('B', dayCount))),
              Value = c(dayValVec1, dayValVec2))

### Dummy data in data frame (DataType is a factor)
dayDF
##          Date DataType       Value
## 1  2016-01-01        A -1.20706575
## 2  2016-01-02        A  0.27742924
## 3  2016-01-03        A  1.08444118
## 4  2016-01-04        A -2.34569770
## 5  2016-01-05        A  0.42912469
## 6  2016-01-06        A  0.50605589
## 7  2016-01-07        A -0.57473996
## 8  2016-01-08        A -0.54663186
## 9  2016-01-09        A -0.56445200
## 10 2016-01-10        A -0.89003783
## 11 2016-01-01        B -0.47719270
## 12 2016-01-02        B -0.99838644
## 13 2016-01-03        B -0.77625389
## 14 2016-01-04        B  0.06445882
## 15 2016-01-05        B  0.95949406
## 16 2016-01-06        B -0.11028549
## 17 2016-01-07        B -0.51100951
## 18 2016-01-08        B -0.91119542
## 19 2016-01-09        B -0.83717168
## 20 2016-01-10        B  2.41583518

ggplot(dayDF, aes(Date, Value, colour = DataType)) +
    geom_line() +
    geom_rect(aes(xmin=ymd('2016-01-02'),
                  xmax = ymd('2016-01-06'),
                  ymin = -Inf,
                  ymax = Inf), fill = 'pink', alpha = 0.05) +
    scale_x_datetime(labels = date_format('%b-%d'), breaks = date_breaks('1 day'), expand=c(0,0)) +
    theme(axis.text.x     = element_text(angle=90),
          legend.position = 'bottom')

enter image description here

修改

注意,如果您想按月绘制,date_breaks值可以更改为1 month。这个例子就是每天。

答案 1 :(得分:2)

#Make data
a_time <- time(ts(rnorm(12), start=c(2015, 1), frequency=12))
a_series <-ts.union(ret=a_ts, date=a_time)
a_series_df <-as.data.frame(a_series)
a_series_df$date <- as.Date(format(date_decimal(a_series_df$date), 
                                   "%d-%m-%Y"), format="%d-%m-%Y")

dat_rect <- data.frame(
                    xmin = as.Date(c("2015-01-01")),
                    xmax = as.Date(c("2015-05-31")),
                    ymin = -Inf,
                    ymax = Inf
)

#Next time, if using functions not in base R, indicate what packages they are from
#decimal_date for example is from lubridate, which in this solution it is not needed.
ggplot() +
        geom_rect(data=dat_rect,
                  aes(xmin=xmin,xmax=xmax,ymin=ymin,ymax=ymax),
                  fill="pink", alpha=0.5) +
        geom_line(data=a_series_df, aes(x=date,y=ret, color='blue')) +

        theme(axis.text.x=element_text(angle=90,hjust=1,vjust=0.5)) +

#Set date
scale_x_date(date_breaks='1 month',
             date_minor_breaks='1 month',
             labels=date_format("%B-%d"),
             expand=c(0,0)) +
scale_y_continuous(labels = scales::percent)

答案 2 :(得分:1)

确保值是实际的Date个对象:

library(lubridate)
library(ggplot2)
library(scales)

set.seed(1492)
a <- rnorm(12)

a_ts <- ts(a, start=c(2015, 1), frequency=12)
a_time <- time(a_ts)

a_series <- ts.union(ret=a_ts, date=a_time)
a_series_df <- as.data.frame(a_series)
a_series_df$date <- as.Date(as.character(a_series_df$date), "%Y.%j")

rect_df <- data.frame(xmin=as.Date(c("2015-01-01")),
                      xmax=as.Date(c("2015-05-31")))

ggplot() +
  geom_rect(data=rect_df,
            aes(xmin=xmin, xmax=xmax, ymin=-Inf, ymax=Inf), 
            fill="pink", alpha=0.5) +
  geom_line(data = a_series_df, aes(x=date, y=ret), color='blue') +
  scale_x_date(expand=c(0,0), labels=date_format("%b-%d"), 
               date_breaks="1 month") +
  scale_y_continuous(expand=c(0,0), labels=percent) +
  labs(x=NULL, y=NULL) +
  theme_bw() +
  theme(axis.text.x=element_text(angle=90, hjust=1, vjust=0.5)) +
  theme(panel.grid.minor=element_blank()) +
  theme(panel.grid.major.x=element_blank()) +
  theme(axis.ticks=element_blank())

enter image description here