Как отобразить недостающие даты в данных временных рядов с помощью ggplot2? - PullRequest
0 голосов
/ 28 марта 2020

У меня есть данные временного ряда температуры (средняя, ​​максимальная, минимальная) с отсутствующими датами, и линейный график не продолжается, этот график выполняет переход с горизонтальной линией до следующей даты. Я хотел бы, чтобы линия продолжалась.

Мой набор данных следующий

Fecha      -- T      Tmin Tmax

1. Fecha      ---------- T   --   Tmin Tmax
2. 2015-07-01   - 11,16 - 7,3 -  17 
3. 2015-07-02    - 11,49 -   8   - 17,1
4. 2015-07-03   - 11,2 -    8,8 -     15,8
5. 2015-07-04 - 11,20 - 8,6  - 16
6. 2015-07-05    -11,23 -   8,9  - 15,7
7. 2015-07-06    -10,40  - 7,7  -  15,4
8. 2015-07-07 - 10,10 - 8,1 -  14,8
9. 2015-07-08 - 10,04 - 7,3 -  15,4
10. 2018-01-01   - 11,08 -  4,9 -  17,8
11. 2018-01-02   -11,40 -   4,2 -  16,3
12. 2018-01-03 -    9,000 - 5,5  - 13,5
13. 2018-01-04  - 8,584  - 6    -  12,8
14. 2018-01-05  - 8,679  - 7,3  -  11,9
15. 2018-01-06 -    8,75 -  6,8 -  13
16. 2018-01-07   - 9,33 - 6,4    - 15,2
17. 2018-01-08  - 9,63 -    6,3 -  13,9

Мой код:

setwd("C:/Users/2018/Documents/Belmira")
dir()
mmp1<-read.csv2("Temperatura.csv")
head(mmp1)
p<-as.Date(mmp1$Fecha)
mmp1$Fecha<-p
w<-ggplot() +
  geom_line(mapping = aes(x = mmp1$Fecha, y = mmp1$Tmin, colour="Min"), size=0.71) +
  geom_line(mapping = aes(x = mmp1$Fecha, y = mmp1$T, colour="P"), size=0.71) +
  geom_line(mapping = aes(x = mmp1$Fecha, y = mmp1$Tmax, colour="Max"), size=0.71) +
  ylim(c(1,18))+
  theme (text = element_text(size=11)) +
  ylab(expression("Temperatura (°C)"))+
  xlab(expression("Tiempo"))+
  scale_x_date(labels = date_format("%d/%m"))+
  theme(axis.text.x=element_text(angle=45, hjust=1))+
  scale_x_date(date_breaks = "30 day", date_labels = "%m-%y", limits = as.Date(c('2015-07-01','2019-01-01')), expand = (c(0.001,0.008)))+
  theme(plot.title = element_text(hjust = 0.5))+
  theme(panel.background = element_rect(fill = 'white', colour = 'white', size = 1.2, linetype = 7))+
  theme(text=element_text(family="arial", face="bold", size=12))+
  theme(axis.title.y = element_text(face="bold", family = "arial", vjust=1.5, colour="black", hjust = 0.5, size=rel(1.2)))+
  theme(axis.title.x = element_text(face="bold", family = "arial", vjust=0.5, colour="black", size=rel(1.2)))+
  theme(axis.text.x = element_text(family= "arial",face = "plain", colour="black", size=rel(1.1)))+
  theme(axis.text.y = element_text(family= "arial",face = "plain", colour="black", size=rel(1.1)))+
  theme(axis.line = element_line(size = 1, colour = "black"))+
  scale_y_continuous(breaks=seq(-4, 28, 2), limits = c(-4,28), expand=c(0,0))+
  scale_colour_manual(name="Leyenda",
                      values=c(Min="green", P="#56B4E9", Max="Red"))+
  theme(legend.title = element_text(colour="black", size=12, face="bold", family = "arial"))+
  theme(legend.key = element_rect(fill = "white"))+
  guides(colour=guide_legend(order = 2),
         shape=guide_legend(order = 2))
w

результат:

1 Ответ

2 голосов
/ 28 марта 2020

Если я правильно понял, вы хотите, чтобы пропуски в ваших данных не отображались как "длинная горизонтальная" линия? Это не простая задача. Возможно, предпочтительным и самым простым решением будет использование огранки, например, по годам. Если вы настаиваете на том, чтобы все данные были на одном графике, то вам нужно попробовать хакерский подход, избавившись от оси даты и установив метки вручную. Посмотрите на различные подходы:

df <- read.table(text="
    Fecha - T - Tmin - Tmax
    2015-07-01 - 11,16 - 7,3 - 17
    2015-07-02 - 11,49 - 8 - 17,1
    2015-07-03 - 11,2 - 8,8 - 15,8
    2015-07-04 - 11,20 - 8,6 - 16
    2015-07-05 - 11,23 - 8,9 - 15,7
    2015-07-06 - 10,40 - 7,7 - 15,4
    2015-07-07 - 10,10 - 8,1 - 14,8
    2015-07-08 - 10,04 - 7,3 - 15,4
    2018-01-01 - 11,08 - 4,9 - 17,8
    2018-01-02 - 11,40 - 4,2 - 16,3
    2018-01-03 - 9,000 - 5,5 - 13,5
    2018-01-04 - 8,584 - 6 - 12,8
    2018-01-05 - 8,679 - 7,3 - 11,9
    2018-01-06 - 8,75 - 6,8 - 13
    2018-01-07 - 9,33 - 6,4 - 15,2
    2018-01-08 - 9,63 - 6,3 - 13,9
", header = TRUE, dec = ",")

mmp1 <- df[,!grepl("^X", names(df))]
mmp1$Fecha <- as.Date(mmp1$Fecha)

library(ggplot2)
library(scales)
library(dplyr)
library(tibble)

mmp2 <- mmp1 %>% 
  mutate(
    year_fecha = as.character(lubridate::year(Fecha)),
    Fecha2 = format(Fecha, "%d-%m"),
    Fecha2 = forcats::fct_reorder(Fecha2, Fecha)) %>% 
  arrange(Fecha) %>% 
  rowid_to_column(var = "Fecha3")

# Put the theme code aside
polish <- theme(text = element_text(size=11)) +
  theme(axis.text.x=element_text(angle=45, hjust=1))+
  theme(plot.title = element_text(hjust = 0.5))+
  theme(panel.background = element_rect(fill = 'white', colour = 'white', size = 1.2, linetype = 7))+
  theme(text=element_text(family="arial", face="bold", size=12))+
  theme(axis.title.y = element_text(face="bold", family = "arial", vjust=1.5, colour="black", hjust = 0.5, size=rel(1.2)))+
  theme(axis.title.x = element_text(face="bold", family = "arial", vjust=0.5, colour="black", size=rel(1.2)))+
  theme(axis.text.x = element_text(family= "sans",face = "plain", colour="black", size=rel(1.1)))+
  theme(axis.text.y = element_text(family= "sans",face = "plain", colour="black", size=rel(1.1)))+
  theme(axis.line = element_line(size = 1, colour = "black"))+
  theme(legend.title = element_text(colour="black", size=12, face="bold", family = "arial"))+
  theme(legend.key = element_rect(fill = "white"))

# Simple and prefered solution: Facet by e.g. by year
w1 <- ggplot(data = mmp2) +
  geom_line(mapping = aes(x = Fecha, y = Tmin, colour="Min"), size=0.71) +
  geom_line(mapping = aes(x = Fecha, y = T, colour="P"), size=0.71) +
  geom_line(mapping = aes(x = Fecha, y = Tmax, colour="Max"), size=0.71) +
  scale_x_date(date_breaks = "1 day", date_labels = "%d-%m", expand = (c(0.001,0.008)))+
  scale_y_continuous(breaks=seq(-4, 28, 2), limits = c(1,18), expand=c(0,0)) +
  scale_colour_manual(name="Leyenda",
                      values=c(Min="green", P="#56B4E9", Max="Red")) +
  ylab("Temperatura (C)")+
  xlab("Tiempo") +
  guides(colour=guide_legend(order = 2),
         shape=guide_legend(order = 2)) +
  facet_wrap(~year_fecha, scales = "free_x") +
  polish

w1  

# Hacky solutions with some manual labelling
labs <- select(mmp2, Fecha3, Fecha2) %>% 
  tibble::deframe()

date_lab <- function(x) {
  labs[as.character(x)]
}

# Draw the data as one continuous line
w2 <- ggplot(data = mmp2) +
  geom_line(mapping = aes(x = Fecha3, y = Tmin, colour="Min"), size=0.71) +
  geom_line(mapping = aes(x = Fecha3, y = T, colour="P"), size=0.71) +
  geom_line(mapping = aes(x = Fecha3, y = Tmax, colour="Max"), size=0.71) +
  scale_x_continuous(breaks = as.integer(names(labs)), labels = date_lab, expand = (c(0.001,0.008))) +
  scale_y_continuous(breaks=seq(-4, 28, 2), limits = c(1,18), expand=c(0,0)) +
  scale_colour_manual(name="Leyenda",
                      values=c(Min="green", P="#56B4E9", Max="Red")) +
  ylab("Temperatura (C)")+
  xlab("Tiempo") +
  guides(colour=guide_legend(order = 2),
         shape=guide_legend(order = 2)) +
  polish
w2

# Separate lines for years by using different linetypes 
w3 <- ggplot(data = mmp2) +
  geom_line(mapping = aes(x = Fecha3, y = Tmin, colour="Min", linetype = year_fecha), size=0.71) +
  geom_line(mapping = aes(x = Fecha3, y = T, colour="P", linetype = year_fecha), size=0.71) +
  geom_line(mapping = aes(x = Fecha3, y = Tmax, colour="Max", linetype = year_fecha), size=0.71) +
  scale_x_continuous(breaks = as.integer(names(labs)), labels = date_lab, expand = (c(0.001,0.008))) +
  scale_y_continuous(breaks=seq(-4, 28, 2), limits = c(1,18), expand=c(0,0)) +
  scale_colour_manual(name="Leyenda",
                      values=c(Min="green", P="#56B4E9", Max="Red")) +
  ylab("Temperatura (C)")+
  xlab("Tiempo") +
  guides(colour=guide_legend(order = 2),
         shape=guide_legend(order = 2)) +
  polish
w3

Создано в 2020-03- 28 * представительный пакет (v0.3.0)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...