ОсновнаяРецепты

Графики с «затухающей» тенью

Posted

Довольно часто мне встречаются графики с затухающей тенью. И захотелось мне научиться делать такие же в 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()

shadow1

Пока все хорошо. А вот дальше случился "затык". Нарисовать одиночный "риббон" под графиком труда не составляло, а вот прогнать в цикле никак не получалось. Долго размышлял - ничего не смог придумать. Создал тему на тему на 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) }

shadow2

Теперь рисуем тень ко второму графику и любуемся результатом:

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)

shadow3

Следующий логичный шаг - сделать из этих циклов функцию, и впоследствии пользоваться ей. Но это уже не входит в рамки этого поста 🙂

Добавить комментарий