Наложение двух графиков ggplot2 stat_density2d с альфа-каналами
Я хочу наложить два ggplot2
строит графики с альфа-каналами таким образом, чтобы полученное изображение показывало оба набора данных. Это мои тестовые данные:
data = read.table(text="P1 -1 0 4\nP2 0 0 2\nP3 2 1 8\nP4 -2 -2 6\nP5 0.5 2 12")
data2 = read.table(text="Q1 1 1 3\nQ2 1 -1 2\nQ3 -1 1 8")
colnames(data) = c("name","x","y","score")
colnames(data2) = c("name","x","y","score")
И вот как я строю эти данные:
ggplot(data, aes(x=x,y=y)) +
stat_density2d(data=data,geom="tile", aes(fill = ..density..,alpha=..density..), contour=FALSE) +
theme(legend.position="none") + scale_fill_gradient (low = "#FFFFFF", high = "#FF0000") +
xlim(-3,3) + ylim(-3,3) +
geom_point()
ggplot(data2, aes(x=x,y=y)) +
stat_density2d(data=data2,geom="tile", aes(fill = ..density..,alpha=..density..), contour=FALSE) +
theme(legend.position="none") +
scale_fill_gradient (low = "#FFFFFF", high = "#00FF00") +
xlim(-3,3) + ylim(-3,3) +
geom_point()
Первый график показывает данные, второй график данные2:
Теперь я хочу комбинацию обоих участков. Следующее изображение - это то, что я хочу получить. Я создал его с помощью программы редактирования изображений на рабочем столе, умножив оба изображения на слои.
Я попытался нанести один набор данных поверх другого, но это не умножает оба слоя, и второй цвет перезаписывает первый.
ggplot(data, aes(x=x,y=y)) +
stat_density2d(data=data,geom="tile", aes(fill = ..density..,alpha=..density..), contour=FALSE) +
theme(legend.position="none") + scale_fill_gradient (low = "#FFFFFF", high = "#FF0000") +
xlim(-3,3) + ylim(-3,3) +
stat_density2d(data=data2,geom="tile", aes(fill = ..density..,alpha=..density..), contour=FALSE) +
scale_fill_gradient (low = "#FFFFFF", high = "#00FF00")
Дополнительно я получаю это предупреждение: шкала для "заполнения" уже присутствует. Добавление еще одной шкалы для "заливки", которая заменит существующую шкалу.
Есть ли способ сделать это в R? Или есть другой способ (с использованием других функций, таких как, например, smoothScatter), чтобы получить этот или аналогичный результат? В качестве своего рода обходного пути, я думаю, я получу аналогичный результат, используя ImageMagick на сервере, но я бы предпочел сделать все это в R.
Обновление 1
Умножение двух слоев выполняется в ImageMagick таким образом;
composite -compose multiply data-red.png data-green.png im-multiply.png
Это дает тот же результат, как показано выше.
Обновление 2
@Roland научил меня в своем ответе, как построить два набора данных на одном графике. Хотя это здорово, остается одна проблема: изображение зависит от порядка подачи данных на график.
ggplot(rbind(data.frame(data, group="a"), data.frame(data2, group="b")), aes(x=x,y=y)) +
stat_density2d(geom="tile", aes(fill = group, alpha=..density..), contour=FALSE) +
scale_fill_manual(values=c("a"="#FF0000", "b"="#00FF00")) +
geom_point() +
theme_minimal() +
xlim(-3.3, 3.3) + ylim(-3.3, 3.3) +
coord_cartesian(xlim = c(-3.2, 3.2), ylim = c(-3.2, 3.2))
дает такой результат:
Если поменять местами порядок обоих наборов данных (теперь сначала идет набор данных "b", то есть data2, а затем набор данных "a"), вы получите похожий результат, но теперь преобладает красный цвет, потому что он отображается позже и, таким образом, перезаписывается. зеленые данные.
ggplot(rbind(data.frame(data2, group="a"), data.frame(data, group="b")), aes(x=x,y=y)) +
stat_density2d(geom="tile", aes(fill = group, alpha=..density..), contour=FALSE) +
scale_fill_manual(values=c("b"="#FF0000", "a"="#00FF00")) +
geom_point() + theme_minimal() +
xlim(-3.3, 3.3) + ylim(-3.3, 3.3) +
coord_cartesian(xlim = c(-3.2, 3.2), ylim = c(-3.2, 3.2))
Мне нужны решения, которые не зависят от порядка наборов данных.
2 ответа
Здесь точно такое же решение, как у @Roland, за исключением того, что я предлагаю контурную линию. Это позволит вам оценить перекрытие. Я не понимаю, как geom_tile и ваша идея "умножения" могут помочь вам это оценить. Может быть, если вы используете синий и красный для неперекрывающихся областей, и "взвешенный" фиолетовый цвет для перекрывающихся областей. Но я думаю, что вам придется вычислить это на предыдущем шаге, прежде чем строить, я думаю.
ggplot(rbind(data.frame(data, group="a"), data.frame(data2, group="b")),
aes(x=x,y=y)) +
stat_density2d(geom="density2d", aes(color = group,alpha=..level..),
size=2,
contour=TRUE) +
#scale_color_manual(values=c("a"="#FF0000", "b"="#00FF00")) +
geom_point() +
theme_minimal() +
xlim(-3.3, 3.3) + ylim(-3.3, 3.3) +
coord_cartesian(xlim = c(-3.2, 3.2), ylim = c(-3.2, 3.2))
Вы должны построить обе плотности в одном масштабе:
ggplot(rbind(data.frame(data, group="a"), data.frame(data2, group="b")),
aes(x=x,y=y)) +
stat_density2d(geom="tile", aes(fill = group, alpha=..density..),
contour=FALSE) +
scale_fill_manual(values=c("a"="#FF0000", "b"="#00FF00")) +
geom_point() +
theme_minimal() +
xlim(-3.3, 3.3) + ylim(-3.3, 3.3) +
coord_cartesian(xlim = c(-3.2, 3.2), ylim = c(-3.2, 3.2))
В противном случае вы отобразите искаженное изображение ваших данных.