I want to perform a chart that involves two variables (weight - kg) and (rain - mm) through the years (1991 - 2021). BOTH VARIABLES ARE NOT RELATED!
Everything goes ok when plotting the graphs separated one from each other:
library(ggplot2)
ggplot(data2, aes(x=ano_dtt)) +
geom_col(aes(y=PesoAj220_d), fill="lightblue2") +
ylim(0,300)
ggplot(data2, aes(x=ano_dtt)) +
geom_point(aes(y=ppt)) +
geom_path(aes(y=ppt)) +
ylim(0,1700)
But, when I try to add the second axis everything goes wrong!!!
scaleRight <- 0.75
ggplot(data2, aes(x=ano_dtt)) +
geom_col(aes(y=PesoAj220_d), fill="lightblue2") +
ylim(0,300) +
geom_point(aes(y=ppt)) +
geom_path(aes(y=ppt), colour="red", size=0.9) +
ylim(0,1700)+
scale_y_continuous(sec.axis = sec_axis(~.*scaleRight, name="precipitacion (mm)")) +
labs(title = "", x="año", y="peso")
I also try this:
scaleRight <- 0.75
ggplot(data2, aes(x=ano_dtt)) +
geom_col(aes(y=PesoAj220_d), fill="lightblue2") +
ylim(0,300) +
geom_point(aes(y=ppt)) +
geom_path(aes(y=ppt), size=0.9) +
ylim(c(0,1700))
But there is something wrong with the only axis present in the plot.
I think that the problem is with the
scaleRight <- 0.75
Can someone help to solve this problem? I'm pretty sure that is very very easy!
The issue you face is that you have to scale your secondary y-axis values to fall within the range of the primary x-axis. As you guessed, multiplying the secondary y-axis values by a set value (scaleRight) is not how to achieve your goal.
I struggle with scaling within a sec_axis()
function, so I prefer to scale the secondary y-axis values prior to plotting. The approach outlined below creates the same number of axis breaks on both y-axes, comment if you prefer a different number of breaks each side and I'll update the code.
library(ggplot2)
# Example data
set.seed(1)
data2 <- data.frame(ano_dtt = 1991:2021,
PesoAj220_d = sample(250:300, 31),
ppt = sample(750:1550, 31))
# Set y-axes limits, must exceed or equal min/max data values
# Set min and max limits for primary (left) y-axis
l.y.min <- 0
l.y.max <- 300
# Set min and max limits for secondary (right) y-axis
r.y.min <- 0
r.y.max <- 1700
# Function to scale secondary y-axis values
axis_scaled <- function(x, y, z, max.var) {
y <- ifelse(is.na(x), NA, ((x - y) / (z - y)) * max.var)
y <- y[2:(length(y)-1)]
}
# Add scaled secondary y-axis values to data2
data2$scaled_ppt <- axis_scaled(c(r.y.min, data2$ppt, r.y.max),
r.y.min, r.y.max, l.y.max)
# Create breaks for primary y-axis and labels for secondary y-axis
l.y.breaks <- seq(l.y.min, l.y.max, length.out = 5)
r.y.labels <- seq(r.y.min, r.y.max, length.out = length(l.y.breaks))
# Plot
ggplot(data2, aes(x = ano_dtt)) +
geom_col(aes(y = PesoAj220_d), fill = "lightblue2") +
geom_point(aes(y = scaled_ppt)) +
geom_path(aes(y = scaled_ppt), colour = "red", linewidth = 0.9) +
scale_x_continuous(breaks = 1991:2021) +
scale_y_continuous(breaks = l.y.breaks,
sec.axis = sec_axis(~ .,
breaks = l.y.breaks,
labels = r.y.labels,
name = "precipitacion (mm)")) +
labs(title = "", x = "año", y = "peso") +
theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1))