2016-05-17 4 views
8

Я пытаюсь покрасить ленты в ggplot2. При использовании geom_ribbon я могу указать ymin и ymax и цвет заливки. Теперь он окрашивает все, что находится между ymin и ymax, независимо от верхнего предела или нижнего предела.ggplot2: поведение цвета цвета geom_ribbon

Пример (модифицированный из Интернета):

library("ggplot2") 
# Generate data (level2 == level1) 
huron <- data.frame(year = 1875:1972, level = as.vector(LakeHuron), level2 = as.vector(LakeHuron)) 

# Change Level2 
huron[1:50,2] <- huron[1:50,2]+100 
huron[50:90,2] <- huron[50:90,2]-100 

h <- ggplot(huron, aes(year)) 

h + 
    geom_ribbon(aes(ymin = level, ymax = level2), fill = "grey80") + 
    geom_line(aes(y = level)) + geom_line(aes(y=level2)) 

приведет к этой диаграмме: enter image description here

Я хотел бы, чтобы заполнить область, где (Ymin> YMAX), с другим цветом чем где (ymin < ymax). В моих реальных данных у меня есть значения экспорта и импорта. Там, я хотел бы покрасить область, где экспорт выше, чем импорт зеленый, где импорт больше, чем экспорт. Я хочу, чтобы лента была красной.

Альтернатива: Я бы хотел, чтобы geom_ribbon заполнил область, где ymax> ymin.

Кто-нибудь знает, как это делается?

Благодарим за помощь.

ответ

7

Опция, которая не требует ручного создания другого столбца, заключается в том, чтобы выполнить логику в пределах aes(fill =;

## fill dependent on level > level2 
h + 
    geom_ribbon(aes(ymin = level, ymax = level2, fill = level > level2)) + 
    geom_line(aes(y = level)) + geom_line(aes(y=level2)) + 
    scale_fill_manual(values=c("red", "green"), name="fill") 

filled conditional on level > level2

Или, если вы хотите, чтобы заполнить на основе этого условия истинности,

## fill dependent on level > level2, no fill otherwise 
h + 
    geom_ribbon(aes(ymin = level, ymax = level2, fill = ifelse(level > level2, TRUE, NA))) + 
    geom_line(aes(y = level)) + geom_line(aes(y=level2)) + 
    scale_fill_manual(values=c("green"), name="fill") 

filled conditional on level > level2, not otherwise

Я предполагаю отсутствие интерполированной заливки, кажется, есть что-то делать с версией ggplot2, так как я получаю то же самое, что и код @ beetroot

## @beetroot's answer 
huron$id <- 1:nrow(huron) 
huron$group <- ifelse(huron$id <= 50, "A", "B") 

h <- ggplot(huron, aes(year)) 
h + 
    geom_ribbon(aes(ymin = level, ymax = level2, fill = group)) + 
    geom_line(aes(y = level)) + geom_line(aes(y = level2))  

@beetroot's answer

Я получаю @ вывод изображения Манука, когда работает этот код без логики в aes(fill =.

+0

Ничего себе это здорово, спасибо вам большое! Это именно то, что я хотел, поскольку я могу в принципе поставить условие в «fill =». Однако я оставлю запрос на изменение открытым, поскольку он не идеален: заливка не может быть применена идеально к точке пересечения. (На этот раз для меня не проблема). Кроме того, я все еще думаю, что логика заполнения в ggplot2 нуждается в изменении. – ManuK

+0

Супер полезно! Есть ли способ добиться того же результата с данными в длинном формате? Так, например, с вашими данными, настроенными как: Год, Уровень (1 или 2), Значение. Я могу дойти до: h + geom_line (aes (y = Value, group = Level), но я не могу понять, как добавить слой geom_ribbon() с этой структурой. –

+1

Не легко, я не думаю . 'ggplot2' ожидает столбцы, поэтому вам нужно иметь столбец для использования в качестве значений' ymin' и 'ymax'. Это довольно просто для' tidyr :: spread() 'ваши длинные данные в требуемый формат. –

5

Вы можете добавить переменную группировки к данным, которые вы можете использовать, чтобы указать цвет заливки. Однако проблема заключается в том, что две линии пересекаются, поскольку их необходимо включить в обе группы для предотвращения любых пробелов.

Так сначала найти эту строку ..

huron[huron$level == huron$level2,] 

> huron[huron$level == huron$level2,] 
    year level level2 
50 1924 577.79 577.79 
... 

И добавить к данным еще раз:

huron <- rbind(huron, huron[huron$year == 1924,]) 
huron <- huron[order(huron$year),] 

Затем добавить столбец ID на основе индекса строки, и установить группы на основе на номер строки в 1924 году:

huron$id <- 1:nrow(huron) 
huron$group <- ifelse(huron$id <= 50, "A", "B") 

h <- ggplot(huron, aes(year)) 
h + 
    geom_ribbon(aes(ymin = level, ymax = level2, fill = group)) + 
    geom_line(aes(y = level)) + geom_line(aes(y = level2)) 

enter image description here

+0

Большое спасибо за ваш ответ, это работает. В моей утилите, однако, она не очень удобна из-за следующих проблем: 1. Я хотел бы добавить несколько лент, поэтому мне нужно будет добавить несколько «обходных» столбцов. 2. Точки, где встречаются линии, на самом деле не видны в данных, поэтому мне нужно будет вычислить эти точки и добавить их в базу данных (дважды). Я надеялся на простое решение, но, похоже, это сложнее, чем простое условное заполнение. :-) – ManuK

+0

@ManuK да, особенно 2. проблема трудно решить, насколько я знаю, и, к сожалению, я пока не могу вам помочь. Но может быть, кто-то еще придумает другой ответ? Может быть, [это] (https://learnr.wordpress.com/2009/10/22/ggplot2-two-color-xy-area-combo-chart/) сообщение в блоге дает вам некоторые идеи – beetroot

+0

Я отправил проблему как функцию запросить ggplot2 github. Я надеюсь, что он будет реализован в будущей версии ggplot2 [ссылка на запрос] (https://github.com/hadley/ggplot2/issues/1642) – ManuK

1

Передвижение по вопросу я имел с не интерполированное fill, вы можете использовать два (или n) ленты

h <- ggplot() + 
    geom_ribbon(data = huron[huron$level >= huron$level2, ], aes(x = year, ymin = level, ymax = level2), fill="green") + 
    geom_ribbon(data = huron[huron$level <= huron$level2, ], aes(x = year, ymin = level, ymax = level2), fill="red") + 
    geom_line(data = huron, aes(x = year, y = level)) + 
    geom_line(data = huron, aes(x = year, y = level2)) 
h 

Fill is interpolated now

Любое условие, которое вы используете в aes(fill = собирается принуждать его к фактор, поэтому он, похоже, применяется только там, где данные фактически есть. Я не думаю, что это ошибка ggplot2, я думаю, что это ожидаемое поведение.

Смежные вопросы