1

I have three variables (x, y1, y2) with y1 and y2 having different scale. Kindly help me how to do the plot in ggplot2 with x on x axis, y1 and y2 on left and right y axis respectively. The data is shown below.

 x         y1            y2 
2017      0.2555        655 
2018      0.461926745   566 
2019      0.594491867   363 
2020      0.679623819   233 
2021      0.734294679   140
Uwe
  • 41,420
  • 11
  • 90
  • 134
user1641478
  • 41
  • 2
  • 4
  • 1
    Have you looked at these similar posts, [1](https://stackoverflow.com/questions/3099219/plot-with-2-y-axes-one-y-axis-on-the-left-and-another-y-axis-on-the-right?noredirect=1&lq=1), [2](https://stackoverflow.com/questions/6142944/how-can-i-plot-with-2-different-y-axes)? – mnm Aug 24 '17 at 11:47
  • Did you have a look at the [solution](https://stackoverflow.com/a/45855454/4836511) ? – Prradep Sep 19 '17 at 09:47

1 Answers1

0

You can do like this:

#Reading the data you have provided
df <- read.table(text = "x         y1            y2 
2017      0.2555        655 
2018      0.461926745   566 
2019      0.594491867   363 
2020      0.679623819   233 
2021      0.734294679   140", header=T)

# Loading required packages
library(ggplot2)
library(gtable)
library(grid)

AFAIK, there is no function available which produce a nice plot with the dual axis. First starting by creating two plots separately:

grid.newpage()

# creating two separate plots
plot1 <- ggplot(df, aes(x, y1)) + geom_line(colour = "blue") + theme_bw()
plot2 <- ggplot(df, aes(x, y2)) + geom_line(colour = "red") + theme_bw()

# extract gtables for each plot
gtable1 <- ggplot_gtable(ggplot_build(plot1))
gtable2 <- ggplot_gtable(ggplot_build(plot2))

Adjusting the two plots by overlapping on onto the other, followed by tweaking the axis.

# overlap the panel of second plot on the first plot
pp <- c(subset(gtable1$layout, name == "panel", se = t:r))
gtable <- gtable_add_grob(gtable1, gtable2$grobs[[which(gtable2$layout$name == "panel")]], 
                          pp$t, pp$l, pp$b, pp$l)

# axis tweaks
ia <- which(gtable2$layout$name == "axis-l")
ga <- gtable2$grobs[[ia]]
ax <- ga$children[[2]]
ax$widths <- rev(ax$widths)
ax$grobs <- rev(ax$grobs)
ax$grobs[[1]]$x <- ax$grobs[[1]]$x - unit(1, "npc") + unit(0.15, "cm")
gtable <- gtable_add_cols(gtable, gtable2$widths[gtable2$layout[ia, ]$l], 
                          length(gtable$widths) - 1)
gtable <- gtable_add_grob(gtable, ax, pp$t, length(gtable$widths) - 1, pp$b)

# drawing the plot with two y-axis
grid.draw(gtable)

enter image description here

Using Hadley's idea, I think on Github issues. Will update the link, once I find it.

Prradep
  • 5,506
  • 5
  • 43
  • 84