我的问题与:Axis labels on two lines with nested x variables (year below months)
但是,我的数据看起来有些不同。
library(dplyr)
set.seed(122)
df <- as_tibble(rlnorm(1260, meanlog = 0.06, sdlog = 0.20))
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)
我希望折线图也看起来像这样,但是如果可能的话,也不要垂直线:
答案 0 :(得分:1)
library(tidyverse)
#data:
set.seed(122)
df <- as_tibble(rlnorm(1260, meanlog = 0.06, sdlog = 0.20))
#> Warning: Calling `as_tibble()` on a vector is discouraged,
#> because the behavior is likely to change in the future.
#> Use `tibble::enframe(name = NULL)` instead.
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"))
由reprex package(v0.3.0)于2019-05-28创建
答案 1 :(得分:0)
我可以想到两种方法,每种方法各有利弊:
library(dplyr)
library(tibble)
library(lubridate)
library(scales)
library(ggplot2)
set.seed(122)
df <- as_tibble(rlnorm(1260, meanlog = 0.06, sdlog = 0.20))
df$month <- rep(month.abb, 5, each=21)
df$year <- rep(c("Year 1", "Year 2", "Year 3", "Year 4", "Year 5"), 1, each=252)
# We first create a "real" date variable with year, month and day. I've chosen to add
# "201" in from of your year, but it really doesn't matter in our case.
df <- df %>%
group_by(year, month) %>%
mutate(Date = as.Date(paste0("201", sub("^.+(\\d+)$", "\\1", year),
"-", month, "-", row_number()),
format = "%Y-%b-%d"))
# Since OP's daily values don't make up full months of data,
# we need this step to show missing data correctly.
df <- expand.grid(Date = seq.Date(from = min(df$Date), to = max(df$Date), by = "days")) %>%
mutate(year = paste("Year", sub("^\\d{3}(\\d)", "\\1", format(Date, "%Y"))),
month = format(Date, "%b")) %>%
left_join(df)
请注意,我已经使用month.abb
代替了OP提供的月份,因为看起来他们使用的是非英语语言环境。
facet_grid
:ggplot(df, aes(x = Date, y = value, group = year)) +
geom_line() +
facet_grid(. ~ year, scale = "free_x") +
scale_x_date(labels = date_format("%b"), expand = c(0, 0)) +
theme(panel.spacing.x = unit(0, "lines")) +
ylim(c(0, 2.5))
我使用了expand
中的scale_x_date
来防止ggplot在每个构面的两端都添加空格,并使用panel.spacing.x
来减小构面之间的间距。两者的结合给我们一种错觉,即面板已连接,但面板却没有连接(即使没有缺失值,每个构面的末端也不会连接到下一个面的开始)
geom_rect
+ geom_text
:# Create labels
label_range <- df %>%
group_by(year) %>%
summarize(xmin = min(Date),
xmax = max(Date),
ymin = -0.5,
ymax = ymin + 0.15)
ggplot(df) +
geom_line(aes(x = Date, y = value)) +
geom_rect(data = label_range, fill = "lightcoral", color = "#f2f2f2",
aes(xmin = xmin, xmax = xmax,
ymin = ymin, ymax = ymax,
group = year)) +
geom_text(data = label_range,
aes(x = xmin + 365/2, y = ymin + 0.1,
group = year, label = year)) +
coord_cartesian(ylim = c(0, 2.5), clip = "off") +
scale_x_date(labels = date_format("%b"),
date_breaks = "1 month",
expand = c(0.01, 0.01)) +
theme_bw() +
theme(plot.margin = unit(c(1,1,3,1), "lines"))
第二种方法比较繁琐,但是我们的数据将被视为一个连续序列。
创建label_range
,以确定每个geom_rect
四个角的坐标。
使用此数据集,我使用geom_rect
绘制了“小平面框”,并使用了geom_text
分组的year
绘制了它们的标签。
我们希望矩形位于x轴下方,因此我使用coord_cartesian
将图设置为特定的缩放比例,这样可以防止在将其设置在图外时将矩形剪裁掉。
plot.margin
在x轴下方为我们的构面标签添加了一些空间
注意Dec
和Jan
之间的差距。它们是由缺失值引起的,这与第一种方法中的Dec
和Jan
之间的差距不同。