Довольно часто мне встречаются графики с затухающей тенью. И захотелось мне научиться делать такие же в R.
Поискал немного — ничего в базовых функциях и пакетах не нашел. Значит придется делать самому.
Рецептом сим и хочу поделиться.
Используем подсистему графики ggplot2.
Идея состоит в следующем — нарисовать «тень» под графиком рядом элементов geom_ribbon, с постепенно снижающимся параметром прозрачности (alpha). Если таких элементов будет много — то собственно линии видны не будут и будет достигнут как раз нужный эффект.
Подключим пакеты и сгенерим данные (будем рисовать сразу два линейных графика):
library(ggplot2)
set.seed(123)
d1 <- data.frame(x=seq(1,10), y=10+rnorm(10)) d2 <- data.frame(x=seq(1,10), y=11+sin(seq(1,10)))
Нарисуем базовый график:
g <- ggplot()+
geom_line(data=d1, aes(x=x, y=y), color='darkgreen')+
geom_line(data=d2, aes(x=x, y=y), color='red')+
scale_y_continuous(limits=c(5,NA))+
theme_void()
Пока все хорошо. А вот дальше случился "затык". Нарисовать одиночный "риббон" под графиком труда не составляло, а вот прогнать в цикле никак не получалось. Долго размышлял - ничего не смог придумать. Создал тему на тему на RU.STACKOVERFLOW, где и получил качественный и подробный ответ. Использовать вместо AES() - AES_STRING().
Ну а дальше особого труда не было. Получилась параметризованная тень. Какие параметры и их значения - видно из текста программы:
in_count <- 30 # количество полос имитации тени
in_start_alpha <- 0.2 # начальная прозрачность сводимая к 0
in_color <- 'green' # цвет
in_m <- 300 # "обратная ширина" полосы
# Добавляем тень к первому графику
for (i in 0:(in_count-1))
{
g <- g+
geom_ribbon(data = d1,
aes_string(x=d1$x,
ymin=d1$y-(d1$y/in_m)*i,
ymax=d1$y-(d1$y/in_m)*(i+1)),
alpha=in_start_alpha-(in_start_alpha/in_count)*i,
fill=in_color)
}
Теперь рисуем тень ко второму графику и любуемся результатом:
in_count <- 30 # количество полос имитации тени
in_start_alpha <- 0.2 # начальная прозрачность сводимая к 0
in_color <- 'red' # цвет
in_m <- 300 # "обратная ширина" полосы
# Добавляем тень ко второму графику
for (i in 0:(in_count-1))
{
g <- g+
geom_ribbon(data = d2,
aes_string(x=d2$x,
ymin=d2$y-(d2$y/in_m)i,
ymax=d2$y-(d2$y/in_m)(i+1)),
alpha=in_start_alpha-(in_start_alpha/in_count)*i,
fill=in_color)
}
print(g)
Следующий логичный шаг - сделать из этих циклов функцию, и впоследствии пользоваться ей. Но это уже не входит в рамки этого поста 🙂