Reputation: 33
I want to merge two plots in R to create one plot with a secondary Y axis for my Tides data. The problem is that I have Temperature data for every hour, but the Tide data is only for time points at low and high tide, so there are missing values in the dataset. In the individuals plots I have overcome this problem using
geom_line(data=m_tide[!is.na(m_tide$Tides),]
for Tides data. However when I want to plot the two in one graph with a secondary axis this causes problems. This is a subset of my data:
The values for the different y-axis are different. Temperature ranges from ~23 to 45 and Tidal height ranges from ~ 0.4 to 2.55. My x-axis is a asPOSIXct Datetime object.
To make two separate plots I used:
ylab <- expression("Temperature " ( degree*C))
(mtide_temp <- ggplot(m_tide, aes(x=Date_Time, y=Temperature)) +
geom_line(color="#33A02C") +
labs(x="", y=ylab) +
scale_x_datetime(date_breaks="1 day", date_labels = "%d %b %y") +
theme_bw() +
theme(axis.text.x=element_text(angle=60, hjust=1)) +
scale_y_continuous(limits = c(20, 45), breaks = seq(20, 45, by = 5)))
My Tidal data:
ylab <- "Tide height (m)"
ggplot(m_tide, aes(x=Date_Time, y=Tides)) +
geom_line(data=m_tide[!is.na(m_tide$Tides),], color="steelblue") +
geom_point(na.rm=TRUE, color=“steel blue”) +
scale_x_datetime(date_breaks="1 day", date_labels = "%d %b %y") +
labs(x="", y=ylab, title="Mangrove Tides") +
theme_bw() +
theme(axis.text.x=element_text(angle=60, hjust=1))
I have tried using scale_y_continuous(sec.axis = sec_axis(~ ., name = ylab, breaks = seq(0, 2.5, by = 0.5))) to create a second y-axis, but I haven’t been able to incorporate this successfully in my ggplot code.
This is what I got so far but the secondary scale isn’t correct and Tide data isn’t plotted correctly either
scale=18
(temp_tide <- ggplot(m_tide, aes(x=Date_Time, y=Temperature)) +
geom_line(aes(color="Temperature")) +
geom_line(data=m_tide[!is.na(m_tide$Tides),]) + #doesn't plot Tide at correct y-axis values
labs(x="", y="Temperature", color="") +
scale_color_manual(values=c("#33A02C", "grey50")) +
scale_y_continuous(sec.axis = sec_axis(~ ./scale, name = "Tidal height (m)", breaks = seq(0, 2.5, by = 0.5))))
Any suggestions on how I can plot these two graphs in one plot with a secondary y-axis for Tide height (m)? Any help would be greatly appreciated! Many thanks!
Upvotes: 1
Views: 414
Reputation: 1430
First of all, in order to get really useful answers you should post your data (dput()
is fine). From the spec of data from the picture, I could only reproduce a tiny portion of the plot.
Anyway, sec.axis()
does nothing to your data. It only affects your secundary axis labels. So dividing by scale
only changed secundary axis labels.
For your data to be plotted together, you should bring Tidal
data up to the same level as Temperature
(or vice-versa), thus multiplying it by your scale
.
Another option is to plot them side by side, fixing only x axis (I like this one way better).
library(ggplot2)
# data
data = structure(list(V1 = c(7038, 7039, 7040, 7041, 7042, 7043,
7044, 7045, 7046, 7047, 7048, 7049, 7050, 7051, 7052, 7053, 7054,
7055, 7056, 7057), Date_Time = structure(c(1669421760, 1669425360,
1669428960, 1669432560, 1669436160, 1669439760, 1669443360, 1669446960,
1669450560, 1669454160, 1669457760, 1669461360, 1669464960, 1669468560,
1669472160, 1669475760, 1669479360, 1669482960, 1669486560, 1669490160
), class = c("POSIXct", "POSIXt"), tzone = "UTC"), Temperature = c("28.53",
"28.18", "26.63", "26.07", "25.90", "26.15", "26.39", "27.57",
"29.00", "29.33", "29.70", "29.68", "29.73", "30.06", "29.95",
"29.48", "29.13", "28.93", "27.10", "28.21"), mV = c("-51.85",
"-44.47", "-62.28", "-64.02", "-64.36", "-64.25", "-64.13", "-60.67",
"-73.30", "-77.77", "-79.58", "-78.24", "-76.88", "-79.11", "-82.63",
"-77.89", "-58.67", "-49.36", "-65.89", "-55.66"), pH = c("7.74",
"7.61", "7.92", "7.95", "7.96", "7.96", "7.95", "7.89", "8.10",
"8.18", "8.21", "8.18", "8.16", "8.20", "8.26", "8.18", "7.85",
"7.69", "7.98", "7.80"), Tides = c(NA, NA, NA, NA, "0.40", NA,
NA, NA, NA, NA, NA, "2.60", NA, NA, NA, NA, NA, "1.22", NA, NA
)), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA,
-20L))
# scale
scale = 18
# format
m_tide = within(data, {
Temperature = as.numeric(Temperature)
mV = as.numeric(mV)
pH = as.numeric(pH)
Tides_2 = as.numeric(Tides)
Tides = as.numeric(Tides) * scale
})
tidyr::pivot_longer(m_tide, cols = c(-V1, -Date_Time)) |>
subset(name %in% c("Temperature", "Tides")) |>
na.omit() |>
ggplot(aes(x = Date_Time, group = name, y = value, color = name)) +
geom_line() +
labs(x = "", y = "Temperature", color = "") +
scale_y_continuous(
sec.axis = sec_axis(
~ . / scale,
name = "Tidal height (m)",
breaks = seq(0, 2.5, by = 0.5)
)
)
tidyr::pivot_longer(m_tide, cols = c(-V1, -Date_Time)) |>
subset(name %in% c("Temperature", "Tides_2")) |>
na.omit() |>
ggplot(aes(x = Date_Time, y = value, color = name)) +
geom_line() +
labs(x = "", y = "Temperature", color = "") +
facet_grid(vars(name), scales = "free_y")
Created on 2023-03-28 with reprex v2.0.2
Upvotes: 0