GGPLOT2: избавление от «скачков» между фасетными сетками - PullRequest
1 голос
/ 29 мая 2019

Я использую 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 Ответ

3 голосов
/ 29 мая 2019

Мое понимание этого заключается в том, что нет чистого способа сделать это с помощью фасетов, поскольку 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)?это можно сделать красиво и красиво, используя другие форматы.постройте и просто отформатируйте даты, чтобы они были немного более приятными для глаз в виде Mon Year с использованием format().Я считаю, что это более правильно, а также проще сформулировать.Используя plotly, вы можете делать такие вещи, используя группы и подгруппы, как показано в примере здесь .

# 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, но это можно просто изменить, как вы считаете нужным.После того, как метки отсортированы в правильном порядке, вы можете делать с ними все, что захотите, просто удалите вызов на 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"))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...