ggplot2 показывает другой результат с тем же кодом - PullRequest
0 голосов
/ 26 мая 2020

Я использую ggplot2 для построения графика, но тот же код отличается от графика,

fig1

fed <- tibble(
  start = c(ymd("1982-09-27"),ymd("1987-08-11"),ymd("2006-02-01"),
            ymd("2014-02-04"),ymd("2018-02-04")),
  end = c(ymd("1987-08-10"),ymd("2006-01-31"),ymd("2014-02-03"),
          ymd("2018-02-03"),ymd("2020-05-12")),
  pd = c("Paul Volker","Alan Greenspan","Ben Bernanke",
         "Janet Yellen","Jerome Powell")
)

ggplot(fed_d) + 
  geom_line(aes(x = date,y = rate/100,linetype = "solid"),
            size = 1.1) + 
  geom_rect(data = fed,
            aes(xmin = start,
                xmax = end,
                ymin = -Inf,ymax = Inf,
                fill = pd),alpha = 0.4) 

fig1

для создания теневого фона, я делаю набор дат и использую функцию geom_rect

fig2

piie_china <- tibble(
  xstart = c(as.Date("2018-01-01"),as.Date("2018-04-02"),as.Date("2018-05-01"),
             as.Date("2018-07-01"),as.Date("2018-07-06"),as.Date("2018-08-23"),
             as.Date("2018-09-24"),as.Date("2018-11-01"),as.Date("2019-01-01"),
             as.Date("2019-06-01"),as.Date("2019-07-01"),as.Date("2019-09-01"),
             as.Date("2019-09-17"),as.Date("2019-12-26"),as.Date("2020-02-14")),
  xend   = c(as.Date("2018-04-01"),as.Date("2018-04-30"),as.Date("2018-06-30"),
             as.Date("2018-07-05"),as.Date("2018-08-22"),as.Date("2018-09-23"),
             as.Date("2018-10-31"),as.Date("2018-12-31"),as.Date("2019-05-31"),
             as.Date("2019-06-30"),as.Date("2019-08-31"),as.Date("2019-09-16"),
             as.Date("2019-12-25"),as.Date("2020-02-13"),as.Date("2020-04-30")),
  ystart = c(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0),
  yend   = c(8.0,8.4,8.3,7.2,10.1,14.4,18.3,18.2,16.5,
             20.7,20.7,21.8,21.1,20.9,20.3),
  pd_china = c("CA","CB","CC","CD","CE","CF","CG",
               "CH","CI","CJ","CK","CL","CM","CN","CO")

  )


ggplot(d_tar) + 
  geom_rect(data = piie_china,
            aes(xmin = xstart,
                xmax = xend,
                ymin = -Inf,
                ymax = Inf,
                fill = pd_china)) + 
  geom_line(data = d_tar,
            aes(x = date,y = china),
            size = 1) + 
  geom_line(data = d_tar,
            aes(x = date,y = us),
            size = 1)

fig2 Я также использую geom_rect для создаю теневой фон, и я также делаю набор данных, как показано на рис. 1

Почему один и тот же код и та же структура набора данных дали другой результат? На фиг.2 есть пустая белая линия в некоторой дате, но на фиг2 теневой фон сплошной

1 Ответ

3 голосов
/ 26 мая 2020

На самом деле, это далеко не «тот же код и та же структура»!

1: ggplot2 работает послойно

Прежде всего, помните, что ggplot работает послойно. Если вы укажете сначала geom rect, а затем geom_line, он не будет таким же, как geom_line first и geom_rect.

Это приведет к рисованию geom_line перед geom_rect:

ggplot(fed_d) + 
geom_rect(data = fed,
          aes(xmin = start,
              xmax = end,
              ymin = -Inf,
              ymax = Inf, 
              fill = pd)) +
geom_line(aes(x = date, 
              y = rate/100, 
              linetype = "solid"),
          size = 1.1)

FIG : geom_line after geom_rect

Это приведет к тому, что geom_line будет нарисован позади geom_rect:

ggplot(fed_d) + 
geom_line(aes(x = date, 
              y = rate/100, 
              linetype = "solid"),
          size = 1.1) +
geom_rect(data = fed,
          aes(xmin = start,
              xmax = end,
              ymin = -Inf,
              ymax = Inf, 
              fill = pd)) 

FIG : geom_line before geom_rect

2: geom_rect (alpha) контролирует прозрачность фона

Затем, если я хорошо понимаю, вы хотели бы иметь «светлый» фон, как в Рис.1 . Это указывается аргументом "alpha = 0.4" , переданным в geom_rect. Вы должны записать это снова в рис.2 .

3: обратите внимание на структуру ваших данных

Наконец, что касается «белых линий» в Рис.2 : это только из-за строения ваших тубов. В Рис.1 вы не можете видеть пустое пространство между вашими прямоугольниками, потому что диапазон шире (с 1982 по 2020 год), чем в Рис.2 (с 2018 по 2020). Даже если эти пробелы существуют, один день будет намного тоньше на Рис.1 , чем на Рис.2 .
==> Чтобы решить эту проблему, я просто меняю xstart, заставляя его начинаться с той же даты, что и предыдущий xend, чтобы они перекрывались.

Бонус: иметь аккуратный data_frame

В вашем piie_china вместо одного столбца ставок для Китая и одного для нас, объедините их в один и создайте новый столбец, в котором вы указываете страну. Это позволяет вам использовать этот новый столбец для разделения вашей страны с типом линии в той же geom_line. Это намного яснее :)

Вот мой код:

(мне пришлось случайным образом сгенерировать ваши fed_d и d_tar, в следующий раз подумайте о том, чтобы предоставить воспроизводимый пример с помощью предоставляя эти таблицы и некоторые фиктивные таблицы)

#############
### Fig.1 ###
#############

fed <- tibble(
  start = c(ymd("1982-09-27"),ymd("1987-08-11"),ymd("2006-02-01"),
            ymd("2014-02-04"),ymd("2018-02-04")),
  end = c(ymd("1987-08-10"),ymd("2006-01-31"),ymd("2014-02-03"),
          ymd("2018-02-03"),ymd("2020-05-12")),
  pd = c("Paul Volker","Alan Greenspan","Ben Bernanke",
         "Janet Yellen","Jerome Powell")
)

### Randomly generate dates and rate
set.seed(1984)
date = sample(seq(as.Date('1982-09-27'), as.Date('2020-05-12'), by = "month"), 50, replace = TRUE)
rate = sample(seq(25,75,by = 1),50,replace = TRUE)

### Store them in  tibble
fed_d = tibble(date = date,
          rate = rate)

### Draw plot
  ggplot(fed_d) + 
      geom_rect(data = fed,
              aes(xmin = start, xmax = end,
                  ymin = -Inf,ymax = Inf,
                  fill = pd),
              alpha = 0.4) + # outsite aes() because it is not supposed to change
    geom_line(aes(x = date,y = rate/100, linetype = "solid"),
              size = 1.1) +
    scale_y_continuous(limits = c(0,1))

#############
### Fig.2 ###
#############

piie_china <- tibble(
  xstart = c(as.Date("2018-01-01"),as.Date("2018-04-01"),as.Date("2018-04-30"),
             as.Date("2018-07-01"),as.Date("2018-07-06"),as.Date("2018-08-23"),
             as.Date("2018-09-24"),as.Date("2018-11-01"),as.Date("2019-01-01"),
             as.Date("2019-06-01"),as.Date("2019-07-01"),as.Date("2019-09-01"),
             as.Date("2019-09-17"),as.Date("2019-12-26"),as.Date("2020-02-14")),
  xend   = c(as.Date("2018-04-01"),as.Date("2018-04-30"),as.Date("2018-07-01"),
             as.Date("2018-07-06"),as.Date("2018-08-23"),as.Date("2018-09-24"),
             as.Date("2018-11-01"),as.Date("2019-01-01"),as.Date("2019-06-01"),
             as.Date("2019-07-01"),as.Date("2019-09-01"),as.Date("2019-09-17"),
             as.Date("2019-12-26"),as.Date("2020-02-14"),as.Date("2020-04-30")),
  pd_china = c("CA","CB","CC","CD","CE","CF","CG",
               "CH","CI","CJ","CK","CL","CM","CN","CO")

  )

### Randomly generate dates and rate
set.seed(1984)
date = sample(seq(as.Date('2018-01-01'), as.Date('2020-04-30'), by = "month"), 50, replace = TRUE)
rate = sample(seq(25,75,by = 1),50,replace = TRUE)

d_tar = tibble(date = date,
               rate = rate,
               country = rep(c("china","us"), 25)) # Create a new column with country

ggplot() + 
  geom_rect(data = piie_china,
            aes(xmin = xstart,
                xmax = xend,
                ymin = -Inf,
                ymax = Inf,
                fill = pd_china),
            alpha = 0.4) + # outsite aes() because it is not supposed to change
  geom_line(data = d_tar,
            aes(x = date, y = rate, linetype = country),
            size = 1) + # outsite aes() because it is not supposed to change
  scale_y_continuous(limits = c(0,100))

FIG : New_fig_1
FIG : New_fig_2

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