I have a data frame with 3 columns:
- A date time column
- water level of a pond over 2 years (hourly)
- daily precipitation over 2 years (daily)
I want to plot the date time on the x axis and the other two as two separate y axis.
I've tried with ggplot2
, but this seems like quite a tricky thing to do. Does anyone know of any solutions or of any other methods.
Thankyou.
This is my current code. I don't know how to add in the data for a second axis however. (It is in a for loop as I have multiple locations within the pond. They all have the same data layout.)
scaleFUN <- function(x) sprintf("%.2f", x)
plotlist_mAODdate <- list()
j = 1 # counter for plot title and index
for (datTime in mAODdata){
plotName <- names(mAODdata)[j]
j = j 1
plot <-
datTime %>%
ggplot()
geom_point(aes_string(x='DateTime', y='Rel_mAOD'), col='grey')
geom_smooth(aes_string(x='DateTime', y='Rel_mAOD'))
theme_classic()
labs(y='Water Depth (mAOD)', x=NULL)
ggtitle(plotTitles[[plotName]][1])
scale_x_datetime(
breaks=seq(min(datTime$DateTime), max(datTime$DateTime),
by= "6 months"), date_labels="%b-%y")
scale_y_continuous(labels=scaleFUN)
geom_vline(xintercept=as.POSIXct('2020-11-03 01:00:00'), col='red')
geom_vline(xintercept=as.POSIXct('2021-11-01 01:00:00'), col='red', linetype='dashed')
theme(text=element_text(size=20, family='Calibri Light'))
theme(plot.margin = unit(c(1, 1, 1, 1), 'cm'))
theme(axis.title.y=element_text(margin=margin(t=0, r=20, b=0, l=0)))
theme(axis.title.x=element_text(margin=margin(t=20, r=0, b=0, l=0)))
plotlist_mAODdate[[plotName]] <- plot
}
CodePudding user response:
Since you mentioned other methods, you can do this in base R by:
Data
df <- data.frame(date = seq(as.Date('2021-01-01'),as.Date('2022-12-31'), by = 1),
water = 250 1:730*2,
precipitation = 0 (1:730)^2)
Code
par(mar = c(5.1, 4.1, 4.1, 4.1))
plot(x = df$date, y = df$water, type = "l", col = "red", bty = "n", ylab = "", xlab = "")
par(new = TRUE)
plot(x = df$date, y = df$precipitation, type = "l", col = "blue", axes = FALSE, xlab = "", ylab = "")
axis(side = 4)
mtext("Year", side = 1, padj = 4)
mtext("Water", side = 2, padj = -4)
mtext("Precipitation", side = 4,, padj = 4, srt = -90)
legend("topleft", c("Water","Precipitation"), lty = 1, col = c("red","blue"), bty = "n")
Multiple locations
If you have multiple locations, you can do:
Data
set.seed(123)
df2 <- data.frame(date = seq(as.Date('2021-01-01'),as.Date('2022-12-31'), by = 1),
water = 250 1:730*2,
precipitation = 0 (1:730)^2,
location = sample(LETTERS[1:4], 730, replace = TRUE))
Code
par(mfrow = c(floor(length(unique(df2$location))/2), 2), mar = c(5.1, 4.1, 4.1, 4.1))
for(i in sort(unique(df2$location))){
plot(x = df2[df2$location == i, "date"], y = df2[df2$location == i, "water"], type = "l", col = "red", bty = "n", ylab = "", xlab = "")
par(new = TRUE)
plot(x = df2[df2$location == i, "date"], y = df2[df2$location == i, "precipitation"], type = "l", col = "blue", axes = FALSE, xlab = "", ylab = "")
axis(side = 4)
mtext(paste0("Location: ", i), side = 3, adj = 0)
mtext("Year", side = 1, padj = 4)
mtext("Water", side = 2, padj = -4)
mtext("Precipitation", side = 4,, padj = 4, srt = -90)
legend("topleft", c("Water","Precipitation"), lty = 1, col = c("red","blue"), bty = "n")
}
CodePudding user response:
I used the sec.axis method with
geom_point(aes(y=(prcp_amt/150) 72), col='blue')
and
scale_y_continuous(sec.axis = sec_axis(~(.-72)*150, name='Precipitation (mm)')
and rescaling the data, so they both fit on the same scale. I know this isn't the best method, but I needed the rest of the ggplot2 to make the appearance of the graphs. This is how it's incorporated into the full code.
scaleFUN <- function(x) sprintf("%.2f", x)
plotlist_mAODdate <- list()
j = 1 # counter for plot title and index
for (datTime in mAODdata){
plotName <- names(mAODdata)[j]
j = j 1
plot <-
datTime %>%
ggplot(aes(x=DateTime))
geom_point(aes(y=Rel_mAOD), col='grey')
geom_smooth(aes(y=Rel_mAOD), col='black')
geom_point(aes(y=(prcp_amt/150) 72), col='blue')
theme_classic()
labs(y='Water Depth (mAOD)', x=NULL)
ggtitle(plotTitles[[plotName]][1])
scale_x_datetime(
breaks=seq(min(datTime$DateTime), max(datTime$DateTime),
by= "6 months"), date_labels="%b-%y")
scale_y_continuous(labels=scaleFUN, sec.axis = sec_axis(~(.-72)*150, name='Precipitation (mm)'))
geom_vline(xintercept=as.POSIXct('2020-11-03 01:00:00'), col='red')
geom_vline(xintercept=as.POSIXct('2021-11-01 01:00:00'), col='red', linetype='dashed')
theme(text=element_text(size=20, family='Calibri Light'))
theme(plot.margin = unit(c(1, 1, 1, 1), 'cm'))
theme(axis.title.y=element_text(margin=margin(t=0, r=20, b=0, l=0)))
theme(axis.title.x=element_text(margin=margin(t=20, r=0, b=0, l=0)))
plotlist_mAODdate[[plotName]] <- plot
}