【问题标题】:Getting rid of "jumps" between facet grids摆脱分面网格之间的“跳跃”
【发布时间】:2019-05-29 00:14:10
【问题描述】:

我使用 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"))

我几乎得到了我所追求的东西,除了图中标记的年份之间的跳跃:

有没有办法让线路连续?

【问题讨论】:

  • 数据生成出错。可以查一下吗?
  • @RonakShah 改变了它。现在可以用了吗?

标签: r ggplot2 time-series


【解决方案1】:

我对此的理解是没有干净的方法可以使用构面来做到这一点,因为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 很好地完成,您可以旋转标签以保持整洁等。

另一种方法是创建普通的日期标签,将它们全部放在同一个图上,并使用format()Mon Year 的形式简单地将日期格式化为更悦目。我发现这更正确,也更容易制定。使用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"))

作为对评论的回应,您可以通过使用已排序的 Date_lab 变量并用您需要的字符串替换年份来做到这一点。一种快速的方法可能是使用 gsub,但随后您也会遇到Year 0 的问题,但可以根据您认为合适的方式进行更改。一旦标签以正确的顺序排序,您就可以对它们做任何您想做的事情,只需在ggplot 部分中删除对format 的调用。即

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"))

【讨论】:

  • 我害怕这个答案! :( 你能举一个例子来说明它在月-年标签上的样子吗?
  • 我添加了一个替代方案,只使用法线轴并使标签不那么混乱。如果这太难看,那么plotly 是一个不错的选择。
  • 有没有办法将年份称为“第 1 年”、“第 2 年”等而不是 2001-2004 年?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-01-31
  • 2015-02-05
  • 2015-01-08
  • 2023-03-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多