R ggplot2:添加辅助x标签(月份以下年份)

R ggplot2:添加辅助x标签(月份以下年份),r,ggplot2,timeserieschart,R,Ggplot2,Timeserieschart,我的问题涉及: 然而,我的数据看起来有点不同 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

我的问题涉及:

然而,我的数据看起来有点不同

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)
库(dplyr)
种子集(122)

df我可以想出两种方法来做到这一点,每种方法都有各自的优点和缺点:

数据准备:

我在
scale\u x\u date
中使用了
expand
,以防止ggplot在每个面两端添加空格,并使用
panel.spacing.x
减少面之间的间距。这两者的结合给我们一种错觉,即面板是连接的,但它们不是(即使没有缺失值,每个面的末端也不会连接到下一个面的开始)

2.使用
geom\u rect
+
geom\u text
#创建标签
标签范围%
组别(年份)%>%
汇总(xmin=min(日期),
xmax=最大值(日期),
ymin=-0.5,
ymax=ymin+0.15)
ggplot(df)+
geom_线(aes(x=日期,y=值))+
geom_rect(数据=标签范围,fill=“lightcoral”,color=“#f2f2”,
aes(xmin=xmin,xmax=xmax,
ymin=ymin,ymax=ymax,
组=年)+
几何图形文本(数据=标签范围,
aes(x=xmin+365/2,y=ymin+0.1,
组=年,标签=年)+
坐标笛卡尔(ylim=c(0,2.5),clip=“off”)+
比例x日期(标签=日期格式(“%b”),
date_breaks=“1个月”,
扩展=c(0.01,0.01))+
主题_bw()+
主题(plot.margin=单位(c(1,1,3,1),“线”))

第二种方法更繁琐,但我们的数据将被视为一个连续的序列

  • 创建
    label\u range
    以确定每个
    geom\u rect
    的四个角的坐标

  • 使用该数据集,我使用
    geom\u rect
    绘制了“刻面框”,并使用
    geom\u text
    年份分组绘制了它们的标签

  • 我们希望矩形位于x轴下方,因此我使用了
    coord_cartesian
    将绘图设置为特定的缩放,这可以防止在绘图外部设置矩形时将其剪裁掉

  • plot.margin
    在x轴下方为刻面标签添加一些空格

  • 注意
    Dec
    Jan
    之间的间隙。它们是由于缺少值造成的,这与第一种方法中
    Dec
    Jan
    之间的间隙不同

  • 库(tidyverse)
    #数据:
    种子集(122)
    df警告:不鼓励在向量上调用'as_tible()',
    #>因为这种行为将来可能会改变。
    #>使用'tibble::enframe(name=NULL)`代替。
    df$月百分比
    ggplot(aes(x=as.numeric(rnames),y=price,
    组=年)+
    geom_线()+
    实验室(title=“股价图”,y=“价格”,x=“日期”)+
    比例x连续(断开=顺序(11260,比=21),
    标签=月\实验室,扩展=c(0,0))+
    平面网格(~year,space=“free\ux”,scales=“free\ux”,switch=“x”)+
    主题(strip.placement=“外部”,
    strip.background=元素(fill=NA,color=“grey50”),
    面板间距=单位(0,“cm”))
    


    由(v0.3.0)于2019年5月28日创建。

    请看这里的答案:@RAB我尝试过使用它,但无法将其重新编码到我的问题中。对我来说,问题是我不能使用带有月份和年份的行
    lex.order=TRUE
    。然后拿出那行,看看它是什么样子like@RAB这很难描述,但它看起来不像我想要的。然后告诉我们它是什么样子,给我们你使用的代码,告诉我们哪一位看起来不像你想要的。你需要帮我们一点忙,伙计,由于“日期”列中的NAs,我们无法读取你的想法。我得到以下错误:
    seq.int(0,to0-from,by)中的错误:'to'必须是一个有限的数字
    发生这种情况in@JjBlevins你指的是哪一行?你是指我创建日期序列的
    expand.grid
    吗?没错。如果我浏览数据,我可以看到例如df$Date[43]=NA@JjBlevins我不能重现你的错误。如果您运行我发布的代码时没有任何更改,
    df$Date[43]
    返回
    “2011-02-12”
    any(is.na(df$Date))
    返回
    FALSE
    @JjBlevins我怀疑您仍在使用非英语月份,这将导致
    as.Date
    返回
    na
    。请注意,我使用的是
    month.abb
    而不是您的月份列表。如果您想使用
    theme\u bw()
    并且有边框,但没有切面之间的边框(问题中的垂直线),请查看此线程。。。但是,您可以通过将
    panel.border=element\u blank()
    添加到
    主题中来去除所有边框。再次感谢您。我根据我上一篇文章中的数据调整了这个答案,但我在第一年和第二年之间的折线图上有一个中断。你知道这是从哪里来的吗?@JjBlevins你做了这个
    rbind(df[0,],c(1,“1”,“1”,“1年”),df[1:nrow(df),])
    ?如果你像以前一样调整它(我在评论中概述了它),那么上面的代码对我适用。我只需要在
    aes
    中将
    y=Price
    更改为
    y=as.numeric(Price)
    ,因为添加一行会将该列的类更改为character.yes,但现在我再次删除了第一行。因此,我有1260行,如上面的示例所示。然而,在第1年和第2年之间,这条线还是有一个转折点。
    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)
    
    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))
    
    # 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"))