如何旋转ggplot中的刻度标签并注释缺少的日期?

时间:2018-12-23 07:44:02

标签: r ggplot2

我正在尝试在R中创建条形图,但是在创建它们时遇到两个问题。我想以垂直角度更改x轴上的日期。我尝试过:

plot <- plot + theme(axis.text.x = element_text(angle = 90, hjust = 1, vjust = 0.5))

但这不起作用。 我的第二个问题是我想在图的部分添加一个矩形,其中数字为零。我创建了一个定义了xmin和xmax的数据框,然后尝试了函数geom_rect。 当矩形超过一天(xmin和xmax不同)时,此方法有效。但是,如果我只想创建一个矩形,例如30.07.2018,它不起作用,因为xmin和xmax相同。 有谁知道我如何解决这些问题? 首先十分感谢!这是我的脚本:

library(lubridate)
library(ggplot2)
library(scales)

number_sightings<-structure(list(date = c("31.07.2018", "01.08.2018", "02.08.2018", "03.08.2018", "06.08.2018", "07.08.2018", "08.08.2018", "09.08.2018", "13.08.2018", "15.08.2018", "17.08.2018", "22.08.2018", "23.08.2018", "24.08.2018", "25.08.2018"), number = c(2.7, 0.99, 2.11, 1.63, 1.16, 1, 3.57, 1, 1.84, 3.25, 2.25, 2, 1.88, 2.67, 3.04)), class = "data.frame", row.names = c(NA, -15L))
number_sightings$date = as.Date(number_sightings$date, format = "%d.%m.%Y")

p1 <- data.frame (xmin="04.08.2018", xmax="05.08.2018", ymin=0, ymax=4.0)
p1$xmin<-as.Date(p1$xmin,"%d.%m.%Y")
p1$xmax<-as.Date(p1$xmax,"%d.%m.%Y")
p2 <- data.frame (xmin="10.08.2018", xmax="12.08.2018", ymin=0, ymax=4.0)
p2$xmin<-as.Date(p2$xmin,"%d.%m.%Y")
p2$xmax<-as.Date(p2$xmax,"%d.%m.%Y")
p3 <- data.frame (xmin="14.08.2018", xmax="14.08.2018", ymin=0, ymax=4.0)
p3$xmin<-as.Date(p3$xmin,"%d.%m.%Y")
p3$xmax<-as.Date(p3$xmax,"%d.%m.%Y")
p4 <- data.frame (xmin="16.08.2018", xmax="16.08.2018", ymin=0, ymax=4.0)
p4$xmin<-as.Date(p4$xmin,"%d.%m.%Y")
p4$xmax<-as.Date(p4$xmax,"%d.%m.%Y")
p5 <- data.frame (xmin="18.08.2018", xmax="21.08.2018", ymin=0, ymax=4.0)
p5$xmin<-as.Date(p5$xmin,"%d.%m.%Y")
p5$xmax<-as.Date(p5$xmax,"%d.%m.%Y")
p6 <- data.frame (xmin="26.08.2018", xmax="03.09.2018", ymin=0, ymax=4.0)
p6$xmin<-as.Date(p6$xmin,"%d.%m.%Y")
p6$xmax<-as.Date(p6$xmax,"%d.%m.%Y")
p7 <- data.frame (xmin="29.07.2018", xmax="30.07.2018", ymin=0, ymax=4.0)
p7$xmin<-as.Date(p7$xmin,"%d.%m.%Y") 
p7$xmax<-as.Date(p7$xmax,"%d.%m.%Y")

plot <- ggplot(number_sightings, aes(x=date, y=number)) + geom_bar(stat="identity")
plot <- plot + scale_x_date(breaks=seq("30.07.18, 02.09.18"),expand=c(0,0), date_labels=("%d.%m.%y"), date_breaks = "2 day")
plot <- plot + theme(axis.text.x = element_text(angle=90, hjust=1, vjust=0.5))
plot <- plot + theme(panel.background = element_rect(fill = "white"))
plot <- plot + theme(panel.grid.minor=element_blank())
plot <- plot + ggtitle("")+(ylab("number of harbour porpoise sightings/hour"))
plot <- plot + scale_y_continuous(limits=c(0,4), breaks=seq(0.5, 4, 0.5), expand=c(0,0))
plot <- plot + geom_rect(data=p1, inherit.aes=FALSE,fill="grey", linetype="dashed",aes(xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax))
plot <- plot + geom_rect(data=p2, inherit.aes=FALSE,fill="grey", linetype="dashed",aes(xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax))
plot <- plot + geom_rect(data=p3, inherit.aes=FALSE,fill="grey", linetype="dashed",aes(xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax))
plot <- plot + geom_rect(data=p4, inherit.aes=FALSE,fill="grey", linetype="dashed",aes(xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax))
plot <- plot + geom_rect(data=p5, inherit.aes=FALSE,fill="grey", linetype="dashed",aes(xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax))
plot <- plot + geom_rect(data=p6, inherit.aes=FALSE,fill="grey", linetype="dashed",aes(xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax))
plot <- plot + geom_rect(data=p7, inherit.aes=FALSE,fill="grey", linetype="dashed",aes(xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax))
print(plot)

1 个答案:

答案 0 :(得分:0)

我认为您可以简单地尝试在“一天”的案例中添加和/或减去一小部分,以便强制geom_rect进行绘制。我也自由删除了代码中的冗余,希望可以。您也不需要为每个丢失的日期或期间创建数据框和geom_rect层。

您的数据

number_sightings <-
  structure(list(date = c("31.07.2018",
                          "01.08.2018",
                          "02.08.2018",
                          "03.08.2018",
                          "06.08.2018",
                          "07.08.2018",
                          "08.08.2018",
                          "09.08.2018",
                          "13.08.2018",
                          "15.08.2018",
                          "17.08.2018",
                          "22.08.2018",
                          "23.08.2018",
                          "24.08.2018",
                          "25.08.2018"),
                 number = c(2.7,
                            0.99,
                            2.11,
                            1.63,
                            1.16,
                            1,
                            3.57,
                            1,
                            1.84,
                            3.25,
                            2.25,
                            2,
                            1.88,
                            2.67,
                            3.04)),
            class = "data.frame",
            row.names = c(NA, -15L))
number_sightings$date <- as.Date(number_sightings$date, format = "%d.%m.%Y")

注释数据

我将所有数据框用例(p1-p7)放在一个数据框中。

df_annotation <- 
  data.frame(bar = paste0("bar-", 1:7),
             xmin = c("04.08.2018",
                      "10.08.2018",
                      "14.08.2018",
                      "16.08.2018",
                      "18.08.2018",
                      "26.08.2018",
                      "29.07.2018"), 
             xmax = c("05.08.2018",
                      "12.08.2018",
                      "14.08.2018",
                      "16.08.2018",
                      "21.08.2018",
                      "03.09.2018",
                      "30.07.2018"),
             ymin = 0,
             ymax = 4)

df_annotation$xmin <- as.Date(df_annotation$xmin,"%d.%m.%Y")
df_annotation$xmax <- as.Date(df_annotation$xmax,"%d.%m.%Y")

适合“一天”案例的黑客

我可以在这里自由使用data.table软件包。它只是通过添加和减去常数(一天0.25;可以尝试其他值)来修改“一日”情况下的xminxmax值。这会强制geom_rect绘制出您遇到问题的这两种情况的标尺。

library(data.table)

# Transform to data.table object by reference (use setDF revert to dta.frame)
setDT(df_annotation) 
df_annotation[xmax - xmin == 0,          # select "one" day cases, then
              ":=" (xmin = xmin - 0.25,  # modify xmin & xmax for these cases.
                    xmax = xmax + 0.25)]

情节更加简洁:

library(ggplot2)

plot <- 
  ggplot(data = number_sightings, 
         aes(x = date, 
             y = number)) + 
  geom_bar(stat = "identity") +
  # Annotating the missing days or periods with gray bars;
  # It uses the annotation data.frame. No need to have a data.frame for each case.
  geom_rect(data = df_annotation,
            aes(xmin = xmin,
                xmax = xmax,
                ymin = ymin,
                ymax = ymax),
            inherit.aes = FALSE,
            fill = "grey",
            linetype = "dashed") +
  scale_x_date(breaks = seq("30.07.18, 02.09.18"),
               expand = c(0, 0),
               date_labels = ("%d.%m.%y"),
               date_breaks = "2 day") +
  scale_y_continuous(limits = c(0, 4),
                     breaks = seq(0.5, 4, 0.5),
                     expand = c(0, 0)) +
  ylab("number of harbour porpoise sightings/hour") +
  # No need of a separate call for each theme component; 
  # they can be together in one theme() call.
  theme(panel.grid.minor = element_blank(),
        panel.background = element_rect(fill = "white"),
        # your code for vertical axis text is ok as it is
        axis.text.x = element_text(angle = 90, hjust = 1, vjust = 0.5))

plot

据我所知,关于使日期标签垂直的代码没有问题。

enter image description here