I need to visualize data of different character (temperature, light intensity, rel. humidity) for a kind of climate diagram. My problem, I believe, lies within the different ylims, which prevent an easy transformation to combine the graphs into one diagram. If I put in the temperature graph as in the code below, the fluctuation of the temperature becomes invisible due to the different scales of the diagram from plot_humidity.
Temperature graph inserted without transformation does not sufficiently show variation over time:
plot_humidity <- ggplot(df, aes(x = datetime, y = mean_humidity)) +
geom_line(aes(y = mean_humidity, color = "Rel. humidity", group = 1), linewidth = 1) +
geom_line(aes(y = mean_Light/100, color = "Light intensity", group = 2), linewidth = 1) +
geom_line(aes(y = mean_Temperature, color = "Temperature", group = 3), linewidth = 1) +
geom_ribbon(aes(ymin= mean_humidity - sd_humidity,
ymax= mean_humidity + sd_humidity,
fill = "Rel. humidity", color = "Rel. humidity"),
alpha=0.2, group = 1) +
geom_ribbon(aes(ymin= (mean_Light/100) - (sd_Light/100),
ymax= (mean_Light/100) + (sd_Light/100),
fill = "Light intensity", color = "Light intensity"),
alpha=0.2, group = 2) +
geom_ribbon(aes(ymin= mean_Temperature - sd_Temperature,
ymax= mean_Temperature + sd_Temperature,
fill = "Temperature", color = "Temperature"),
alpha=0.2, group = 3) +
labs( x = "time", y = "relative humidity (in %)", color = "Variable") +
scale_color_manual(values = c("Light intensity" = "green", "Temperature" = "red", "Rel. humidity" = "blue")) +
scale_fill_manual(values = c("Light intensity" = "green", "Temperature" = "red", "Rel. humidity" = "blue")) +
scale_x_datetime(breaks = "1 hour", date_labels = "%H",
limits = as.POSIXct(strptime(c("2022-12-23 01:00:00", "2022-12-24 01:00:00"),
format = "%Y-%m-%d %H:%M:%S")),
expand = c(0, 0)) +
theme(axis.line.y.left = element_line( color = "blue"),
axis.text.y.left = element_text(color = "blue"),
plot.margin = margin(10, 10, 10, 30)) +
guides(fill = "none") +
scale_y_continuous(limits = c(), sec.axis = sec_axis(~ . * 100, name = "light intensity (in lux)")) +
theme(axis.text.y.right = element_text(color = "green"),
axis.line.y.right = element_line(color = "green"))
plot <- wrap_elements(get_plot_component(plot_temperature, "ylab-l")) +
wrap_elements(get_y_axis(plot_temperature)) +
plot_humidity +
plot_layout(widths = c( 3, 1, 40))
Instead of the red graph in the diagram above, I want to have it look like below and overlap with the other graphs.
plot_temperature <- ggplot(df, aes(x = datetime, y = mean_Temperature)) +
geom_line(aes(y= mean_Temperature, color = "Temperature"), linewidth = 1) +
geom_ribbon(aes(ymin= mean_Temperature - sd_Temperature,
ymax= mean_Temperature + sd_Temperature,
fill = "Temperature", color = "Temperature"), alpha = 0.2) +
labs(y = "mean temperature (in °C) +/- standard deviation") +
scale_color_manual(values = "red") +
theme(axis.line.y.left = element_line( color = "red"),
axis.text.y.left = element_text(color = "red"),) +
scale_x_datetime(breaks = "1 hour", date_labels = "%H",
limits = as.POSIXct(strptime(c("2022-12-23 01:00:00", "2022-12-24 01:00:00"),
format = "%Y-%m-%d %H:%M:%S")),
expand = c(0, 0))
My original plan was to use ggplot and wrap_elements to fuse the different parts of the diagrams (y-axis, ylab, geom_line, geom_ribbon) into one diagram. This is not a problem for the light intensity graph, but the temperature graph is a problem. I can´t just transform the data, or can I? And I haven´t found a way to extract geom_line and geom_ribbon from the single temperature diagram to lay it over plot_humidity, but I would be fine with that as well, if there is no more elegant solution to it.
Is there anything obvious that I am missing? Since I am still learning about R and the work that includes this figure is my first big effort, I appreciate any tips you can give me!
EDIT: Here is my df
If you try transforming your values in plot 1 and back-transforming your scales in plot 2 (with same limits) then this should work:
library(tidyverse)
file_path <- "datalogger.csv"
df <- read_csv(file_path) |>
mutate(
mean_Temperature = Durchschnitt_Temperatur,
mean_Light = Durchschnitt_Licht,
mean_humidity = Durchschnitt_Feuchtigkeit,
sd_Temperature = sd_Temperatur,
sd_Light = sd_Licht,
sd_humidity = sd_Feuchtigkeit
)
g1 <- df |>
ggplot(aes(time)) +
geom_line(aes(y = mean_humidity, colour = "Rel. humidity")) +
geom_line(aes(y = mean_Light / 100, colour = "Light intensity")) +
geom_line(aes(y = (mean_Temperature - 27) * 40, colour = "Temperature")) +
geom_ribbon(aes(ymin= mean_humidity - sd_humidity,
ymax= mean_humidity + sd_humidity,
fill = "Rel. humidity", color = "Rel. humidity"),
alpha=0.2, group = 1) +
geom_ribbon(aes(ymin= (mean_Light/100) - (sd_Light/100),
ymax= (mean_Light/100) + (sd_Light/100),
fill = "Light intensity", color = "Light intensity"),
alpha=0.2, group = 2) +
geom_ribbon(aes(ymin= (mean_Temperature - 27 - sd_Temperature) * 40,
ymax= (mean_Temperature - 27 + sd_Temperature) * 40,
fill = "Temperature", color = "Temperature"),
alpha=0.2, group = 3) +
scale_y_continuous(
sec.axis = sec_axis(~ . * 100, name = "light intensity (in lux)"),
limits = c(-10, 120)
) +
scale_color_manual(values = c(
"Light intensity" = "green",
"Temperature" = "red",
"Rel. humidity" = "blue"
),
aesthetics = c("fill", "colour")) +
labs( x = "time", y = "relative humidity (in %)", color = "Variable") +
theme(
axis.line.y.left = element_line(color = "blue"),
axis.text.y.left = element_text(color = "blue"),
plot.margin = margin(10, 10, 10, 30),
axis.text.y.right = element_text(color = "green"),
axis.line.y.right = element_line(color = "green"),
text = element_text(size = 8)
) +
guides(fill = "none")
g2 <- df |>
ggplot(aes(time, mean_Temperature)) +
geom_line(aes(colour = "Temperature")) +
theme(
axis.line.y.left = element_line(color = "red"),
axis.text.y.left = element_text(color = "red"),
text = element_text(size = 8)
) +
scale_y_continuous(
sec.axis = sec_axis(~ (. / 40) +27 , name = "Temperature"),
position = "right",
limits = c(-10, 120)
)
library(patchwork)
library(cowplot)
wrap_elements(get_plot_component(g2, "ylab-l")) +
wrap_elements(get_y_axis(g2, position = "left")) +
g1 +
plot_layout(widths = c(3, 1, 40))