Reputation: 1024
I'm plotting some temperature data as a function of depth. But I want it to be more friendly to non-scientists, and make it clear that at the top is the water surface. Any ideas for how to do this? (Bonus for artistic waves!)
Here are some options so far:
library(dplyr); library(ggplot2); library(magrittr);
temperature <- rnorm(30, mean = 20)
depth <- seq(0:29)
df <- data.frame(temperature, depth)
no_surface <- df %>%
ggplot(aes(y = depth, x = temperature, colour = temperature)) +
geom_path(size = 2) +
scale_y_reverse() +
scale_colour_gradient(low = "blue", high = "red")+
theme_classic() +
theme(legend.position = "none")
flat_surface <- no_surface + geom_hline(yintercept = 0)
wavy_surface <- no_surface + stat_function(fun = function(x)sin(x^1.5),
size = 1)
Upvotes: 1
Views: 178
Reputation: 54237
This one is so beautiful, I got tears in my eyes:
ggplot(df, aes(xmin=1, xmax=10, ymin=-depth+1, ymax=-depth, fill=temperature)) +
annotate("text", x=7, y=1.5, label="\u2600", size = 60, color = "orange") +
geom_rect() +
geom_area(
aes(x), data.frame(x=c(1,10)), inherit.aes=F, stat="function",
fun = function(x)abs(sin(2*x))+.2, fill="blue"
) + coord_cartesian(ylim=c(-30, 10)) +
theme_minimal() + theme(axis.text.x=element_blank(), axis.ticks.x=element_blank()) +
labs(x=NULL, y="level")
Upvotes: 7
Reputation: 10761
We can first create a water_dat
that uses your sine idea for the waves:
water_dat <- data.frame(
x = seq(min(df$temperature), max(df$temperature), length.out = 1000)
) %>%
mutate(y = sin(x^1.5))
Then we'll use the data in water_dat
and the geom_ribbon
and geom_line
functions to add some water.
df %>%
ggplot(aes(y = depth, x = temperature, colour = temperature)) +
geom_ribbon(data = water_dat, aes(x = x, ymax = Inf, ymin = y),
fill = 'blue', inherit.aes = FALSE, alpha = .3)+
geom_line(data = water_dat, aes(x = x, y = y),
inherit.aes = FALSE)+
geom_path(size = 2) +
scale_y_reverse() +
scale_colour_gradient(low = "blue", high = "red")+
theme_classic() +
theme(legend.position = "none")
Upvotes: 1