zhangnan
zhangnan

Reputation: 11

ggplot2 show different outcome with same code

I use ggplot2 to make plot, but the same code different plot,

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

to make shadow backgroud,I make a dateset fed and use geom_rect function

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 I also use geom_rect to make shadow background, and I also make a dataset like fed using in the fig1

Why the same code and same structure of dataset made the different outcome? In the fig2,there blank white line in some date but in the fig2,the shadow background is contiuous

Upvotes: 0

Views: 81

Answers (1)

Romu. P
Romu. P

Reputation: 31

Actually, it is far from "same code and same structure" !

1 : ggplot2 works layer by layer

First of all, remember that ggplot works layer by layer. If you specify first geom rect and then geom_line it won't be the same as geom_line first and geom_rect.

This will result in geom_line being drawn in front of 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

This will result in geom_line being drawn behind of 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) controls background transparency

Then, if I understand well, you'd like to have a "light" background like in Fig.1. This is specified with the "alpha = 0.4" argument passed in geom_rect. You should write it again in fig.2.

3 : pay attention to the structure of your data

Finally, concerning the "white lines" in Fig.2 : this is only due to the structure of your tibbles. In Fig.1 you can't see any white space between your rectangles because the range is broader (1982 to 2020) than in Fig.2 (2018 to 2020). Even if those white space exist, one day is way much thiner on Fig.1 than in Fig.2.
==> To solve this, I just change xstart, making it start at the same date as the previous xend so they overlap.

Bonus : have a tidy data_frame

In your piie_china, instead of having one rate column for china and one for us, gruop them into one, and create a new column where you specify the country. It allows you to use this new column to separate your country with the linetype in the same geom_line. It is way more clear like that :)

Here is my code :

(I had to randomly generate your fed_d and d_tar, next time, think to provide a reprocudible exemple by providing those tables and some dummy tables)

#############
### 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

Upvotes: 3

Related Questions