GGPLOT2:摆脱刻面网格之间的“跳跃”

时间:2019-05-29 00:14:10

标签: r ggplot2 time-series

我正在使用facet_grid以便在x轴上具有两个标签。

我的数据如下:

library(dplyr)
library(tidyverse)
library(ggplot2)
set.seed(22)
df <- c(1:1260)
df <- as_tibble(c(1:1260))
colnames(df)[1] <- "price"
df$price[1] <- 100
for (i in seq(2,1260)){df$price[i]<- df$price[i-1]*0.8 + rlnorm(1, 2, 2)}
df$month <- rep(c("Jan", "Feb", "Mär", "Apr", "Mai", "Jun", 
                  "Jul", "Aug", "Sep", "Okt", "Nov", "Dez"), 5, each=21)

df$year <- rep(c("Year 1", "Year 2", "Year 3", "Year 4", "Year 5" ), 1, each=252)

用户M-M使用此代码:

df$month <- rep(c("Jan", "Feb", "Mär", "Apr", "Mai", "Jun", 
                  "Jul", "Aug", "Sep", "Okt", "Nov", "Dez"), 5, each=21)

df$year <- rep(c("Year 1", "Year 2", "Year 3", "Year 4", "Year 5" ), 1, each=252)

#solution:
month_lab <- rep(unique(df$month), length(unique(df$year)))

year_lab <- unique(df$year)

df %>%
  as.data.frame() %>%
  rename(price = 1) %>% 
  mutate(rnames = rownames(.)) %>% 
  ggplot(aes(x = as.numeric(rnames), y = price, 
             group = year)) +
  geom_line() +
  labs(title = "Stock Price Chart", y = "Price", x = "date") +
  scale_x_continuous(breaks = seq(1, 1260, by = 21), 
                     labels = month_lab, expand = c(0,0)) +
  facet_grid(~year, space="free_x", scales="free_x", switch="x") +
  theme(strip.placement = "outside",
        strip.background = element_rect(fill=NA,colour="grey50"),
        panel.spacing=unit(0,"cm"))

除了图中所示线在几年之间的跳跃之外,我几乎完全可以实现自己的目标:

graph

有没有办法使这条线连续?

1 个答案:

答案 0 :(得分:3)

我对此没有任何清晰的方法来做,因为ggplot不会连接点。解决此问题的一种方法可能是在每个year组的末尾添加一个等于每个year组的开始的额外数据点,

df %>% 
  as.data.frame() %>%
  rename(price = 1) %>% 
  split(.$year) %>% 
  lapply(., function(x) bind_rows(x, data.frame(price = NA, month = "Dez", year = unique(x$year)[[1]], stringsAsFactors = FALSE))) %>% 
  bind_rows() %>% 
  mutate(price = ifelse(is.na(price), lead(price), price)) %>% 
  mutate(rnames = rownames(.)) %>%
  ggplot(aes(x = as.numeric(rnames), y = price, 
             group = year)) +
  geom_line() +
  labs(title = "Stock Price Chart", y = "Price", x = "date") +
  scale_x_continuous(breaks = seq(1, 1260, by = 21), 
                     labels = month_lab, expand = c(0,0)) +
  facet_grid(~year,space="free_x", scales="free_x", switch="x") +
  theme(strip.placement = "outside",
        strip.background = element_rect(fill=NA,colour="grey50"),
        panel.spacing=unit(0,"cm"))

为什么不仅仅使用带有日期标签Month-Year的法线轴(如2001年1月)?使用其他格式的轮廓here可以很好地完成此操作,您可以旋转标签以保持整洁等。

一种替代方法是创建正常的日期标签,将它们全部放置在同一图上,并使用Mon Yearformat()的形式简单地格式化日期,以使其更令人愉悦。我发现这更正确,也更容易制定。使用plotly,您可以使用组和子组来进行此类操作,如示例here所示。

# Change to Numeric month
df$month <- rep(c("01", "02", "03", "04", "05", "06", 
                  "07", "08", "09", "10", "11", "12"), 5, each=21)

# Choose real time window in years I chose 2000-2004
df$year <- rep(c("2000", "2001", "2002", "2003", "2004" ), 1, each=252)
month_lab <- rep(unique(df$month), length(unique(df$year)))

# Construct a date label not just a month 
year_lab <- rep(unique(df$year), 12)
Date_lab <- sort(as.Date(paste0(year_lab, month_lab, "01"), "%Y%m%d"))


df %>% 
  as.data.frame() %>%
  rename(price = 1) %>% 
  mutate(rnames = rownames(.)) %>%
  ggplot(aes(x = as.numeric(rnames), y = price, 
             group = 1)) +
  geom_line() +
  labs(title = "Stock Price Chart", y = "Price", x = "date") +
  scale_x_continuous(breaks = seq(1, 1260, by = 21), 
                     labels = format(Date_lab, "%b %Y"), expand = c(0,0)) +
  theme(axis.text.x = element_text(angle = 60, hjust = 1),
        strip.background = element_rect(fill=NA,colour="grey50"))

作为对Comment的响应,您可以通过使用已排序的Date_lab变量并用所需的字符串替换年份来实现。 gsub可能是一种快速的方法,但是您也遇到了Year 0的问题,但是只要您认为合适就可以更改。按照正确的顺序对标签进行排序后,您可以对标签进行任何操作,只需在format部分中删除对ggplot的调用即可。即

Date_lab <- 
  gsub("(200)", "Year ", format(sort(as.Date(paste0(year_lab, month_lab, "01"), "%Y%m%d")), "%Y %b"))

df %>% 
  as.data.frame() %>%
  rename(price = 1) %>% 
  mutate(rnames = rownames(.)) %>%
  ggplot(aes(x = as.numeric(rnames), y = price, 
             group = 1)) +
  geom_line() +
  labs(title = "Stock Price Chart", y = "Price", x = "date") +
  scale_x_continuous(breaks = seq(1, 1260, by = 21), 
                     labels = Date_lab, expand = c(0,0)) +
  theme(axis.text.x = element_text(angle = 60, hjust = 1),
        strip.background = element_rect(fill=NA,colour="grey50"))