0

I'm trying to draw a custom plot with ggplot2. It is a barplot with dates in the X-axis and the variable_1 in the Y-axis. Additionally, the bars are filled according to the value of the variable_2. Up to this point everything looks correct, as I show below with some dummy data:

set.seed(1234)

# Dummy data.frame
df <- data.frame(
  date = seq(as.Date("2023/01/01"), by="day", length.out=10),
  var1 = c(5.6, 5.4, 6.7, 7.3, 6.8, 7.9, 8.5, 9.0, 7.8, 7.1),
  var2 = runif(10, min = 0, max = 1),
  var3 = runif(10, min = 10, max = 160)
)

library(ggplot2)

ggplot(df, aes(x = date, y = var1, fill = var2)) +
  geom_bar(stat = 'identity') +
  scale_fill_gradient2(mid='blue4', high="darkgoldenrod1", name="Var 2") +
  scale_x_date(date_breaks = "1 day") +
  ylim(0,10) +
  theme_grey() +
  labs(title = paste0("Plot title")) +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  labs(x = "Date") + labs(y = "Var 1")

enter image description here

However, I need to add a line with another variable (variable_3) on a secondary Y-axis, with different scale than the main Y-axis. I am trying to do the following according to this post but without success:

ggplot(df, aes(x = date, y = var1, fill = var2)) +
  geom_bar(stat = 'identity') +
  scale_fill_gradient2(mid='blue4', high="darkgoldenrod1", name="Var 2") +
  scale_x_date(date_breaks = "1 day") +
  ylim(0,10) +
  theme_grey() +
  labs(title = paste0("Plot title")) +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  labs(x = "Date") + labs(y = "Var 1") +
  geom_point(data=df, aes(x = date, y = var3 * 2000)) +
  geom_line(data=df, aes(x = date, y = var3 * 2000, group=1), col = 'black') +
  scale_y_continuous(sec.axis = sec_axis(~. / 2000, name = 'Var 3'))

I obtain the following message and the plot looks like this:

Scale for 'y' is already present. Adding another scale for 'y', which will replace the existing scale.

enter image description here

What am I missing? My plot should look like this:

enter image description here

sermomon
  • 254
  • 1
  • 11
  • 1
    As an FYI, your code was working but displaying your lines outside the plot because you defined y limits as 0:10 and your conversion was displaying your lines way too high. – Yacine Hajji Aug 29 '23 at 09:53

1 Answers1

2

You need to remove ylim(0, 10) and put it into scale_y_limits() as limits=c(0, 10) because it is a doubloon of code. ggplot doesn't like when you have both scale_y_limits and ylim, you should go for scale_y_limits.

Then your variable conversion was not correct. To convert 10 into 150, you need to multiply by 15.

Please find a proposition below.

ggplot(df, aes(x = date, y = var1, fill = var2)) +
  geom_bar(stat = 'identity') +
  scale_fill_gradient2(mid='blue4', high="darkgoldenrod1", name="Var 2") +
  scale_x_date(date_breaks = "1 day") +
  theme_grey() +
  labs(title = paste0("Plot title")) +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  labs(x = "Date") + labs(y = "Var 1") +
  geom_point(data=df, aes(x = date, y = var3/15 )) +
  geom_line(data=df, aes(x = date, y = var3/15 , group=1), col = 'black') +
  scale_y_continuous(sec.axis = sec_axis(~. * 15, name = 'Var 3'), limits=c(0, 10))

enter image description here

Yacine Hajji
  • 1,124
  • 1
  • 3
  • 20