Как назначить даты на оси абсцисс барплоту в R? - PullRequest
1 голос
/ 12 июля 2019

У меня есть набор данных с несколькими датами, который я хотел бы построить с использованием функций барплотта в R. Данные представлены для двух разных периодов, поэтому я хочу, чтобы их соответствующие даты были расположены на оси x для удобства сравнения. Вот мой код до сих пор. A_Date для набора данных в A, а B_Date для набора данных, содержащегося в B.

A= runif(24, min = 25, max = 45)
B=runif(24, min = 35, max = 100)
DF=rbind(A,B)

A_Date= as.data.frame(seq(as.Date("1987-01-01"), to= as.Date("1988-12-31"),by="months"))
names(A_Date)= "Dates"
A_Date$year=as.numeric(format(A_Date$Dates, "%Y"))
A_Date$month=as.numeric(format(A_Date$Dates, "%m"))
A_Date=A_Date[,-1]
A_Date = as.character(paste(month.abb[A_Date$month], A_Date$year, sep = "_" ))

B_Date= as.data.frame(seq(as.Date("2010-01-01"), to= as.Date("2011-12-31"),by="months"))
names(B_Date)= "Dates"
B_Date$year=as.numeric(format(B_Date$Dates, "%Y"))
B_Date$month=as.numeric(format(B_Date$Dates, "%m"))
B_Date=B_Date[,-1]
B_Date = as.character(paste(month.abb[B_Date$month], B_Date$year, sep = "_" ))

barplot(DF, beside = T, col = c("red","darkblue"), legend.text =c("1987-88", "2010-11"), args.legend =list(x="topleft", cex = 1.2, bty="n", x.intersp=0.2),
        ylab = "Precipitation (mm)", cex.axis = 1.2, cex.lab=1.5)

Кроме того, я хотел бы иметь линию оси x (точно так же, как линия на оси y. Спасибо

Ответы [ 2 ]

2 голосов
/ 12 июля 2019

barplot также выбрасывает координатную матрицу, которую мы можем поймать по присваиванию, здесь b <-. Теперь мы можем сделать axis с галочками в нужных местах. Чтобы избежать переполнения графика, мы могли бы объединить избыточную информацию о месяце и просто разбить разные годы на mtext строки. Я использовал здесь встроенный month.abb с.

b <- barplot(DF, beside=T, col=c("red","darkblue"), 
             legend.text=c("1987-88", "2010-11"), 
             args.legend=list(x="topleft", cex=1.2, bty="n", x.intersp=0.2),
             ylab="Precipitation (mm)", cex.axis=1.2, cex.lab=1.5, ylim=c(0, 130))
axis(1, at=b[1, ], labels=FALSE)
axis(1, at=b[2, ], labels=FALSE)
mtext(rep(c(1987, 1988), each=12), 1, 1, at=b[1, ], cex=.8, las=2)
mtext(rep(c(2010, 2011), each=12), 1, 1, at=b[2, ], cex=.8, las=2)
mtext(rep(month.abb, 2), 1, 3, at=colMeans(b), las=2)

Результат

enter image description here

Если вы также хотите сократить разрыв между осями y и x, вы можете добавить эту строку:

abline(h=0, cex=1.3)
1 голос
/ 12 июля 2019

Я чувствую, что будет трудно уместить все 4 даты в одном месте на оси. Вот лучшее, что я мог придумать. Я также переставил ваши данные, чтобы они уместились в одном кадре, и использовал ggplot2.

library(tidyverse)

new_df <- tibble(precip = runif(48, c(25, 25), c(45,100)),
                 dates = c(seq(as.Date("1987-01-01"), as.Date("1988-12-31"), by = "months"),
                           seq(as.Date("2010-01-01"), as.Date("2011-12-31"), by = "months")),
                 group = ifelse(lubridate::year(dates) %in% c(1987,1988), "1987-88", "2010-11"), 
                 month = lubridate::month(dates)) 

ggplot(new_df, aes(x = month, y = precip, fill = group)) + 
    geom_bar(stat = 'identity', position = position_dodge()) +
    scale_x_continuous(labels = paste0(1:12, "/1987 - 1988", "\n", 1:12, "/2010 - 2011"), 
                       breaks = 1:12) + 
    scale_fill_manual(values = c("red", "navy")) + 
    theme_classic() + 
    theme(legend.title = element_blank(), 
          axis.text = element_text(size = 10))

enter image description here

...