ggplot2 несколько графиков stat_binhex() с разными градиентами цвета на одном изображении
Я хотел бы использовать функцию ggplot2 stat_binhex() для одновременного построения двух независимых переменных на одном графике, каждая из которых имеет свой собственный градиент цвета с помощью scale_colour_gradientn().
Если мы игнорируем тот факт, что единицы измерения по оси x не совпадают, воспроизводимым примером будет построение следующего графика на одном и том же изображении при сохранении отдельных градиентов заполнения.
d <- ggplot(diamonds, aes(x=carat,y=price))+
stat_binhex(colour="white",na.rm=TRUE)+
scale_fill_gradientn(colours=c("white","blue"),name = "Frequency",na.value=NA)
try(ggsave(plot=d,filename=<some file>,height=6,width=8))
d <- ggplot(diamonds, aes(x=depth,y=price))+
stat_binhex(colour="white",na.rm=TRUE)+
scale_fill_gradientn(colours=c("yellow","black"),name = "Frequency",na.value=NA)
try(ggsave(plot=d,filename=<some other file>,height=6,width=8))
Я нашел некоторый разговор о связанной проблеме в ggplot2 группах Google здесь.
2 ответа
Вот еще одно возможное решение: я перенял идею @mnel по отображению количества бинов в альфа-прозрачность, и я преобразовал переменные x, чтобы они могли отображаться на одной оси.
library(ggplot2)
# Transforms range of data to 0, 1.
rangeTransform = function(x) (x - min(x)) / (max(x) - min(x))
dat = diamonds
dat$norm_carat = rangeTransform(dat$carat)
dat$norm_depth = rangeTransform(dat$depth)
p1 = ggplot(data=dat) +
theme_bw() +
stat_binhex(aes(x=norm_carat, y=price, alpha=..count..), fill="#002BFF") +
stat_binhex(aes(x=norm_depth, y=price, alpha=..count..), fill="#FFD500") +
guides(fill=FALSE, alpha=FALSE) +
xlab("Range Transformed Units")
ggsave(plot=p1, filename="plot_1.png", height=5, width=5)
Мысли:
Я попытался (и не смог) отобразить разумную цветовую / альфа-легенду. Кажется хитрым, но должно быть возможно, учитывая все возможности настройки легенды ggplot2.
Для маркировки по оси Х необходимо какое-то решение. Многочисленное наложение двух наборов единиц на одной оси неодобрительно, и ggplot2 не имеет такой возможности.
Интерпретация ячеек с перекрывающимися цветами кажется достаточно ясной в этом примере, но может стать очень запутанной в зависимости от используемых наборов данных и выбранных цветов.
Если два цвета являются аддитивными дополнениями, то везде, где они в равной степени перекрываются, вы увидите нейтральный серый. Там, где перекрытие неравномерно, серый цвет станет более желтым или более синим. Мои цвета не совсем дополняют друг друга, судя по слегка розовому оттенку серых ячеек перекрытия.
Я думаю, что вы хотите идти вразрез с принципами ggplot2
и грамматика графики подходит в целом. Пока проблема не будет решена (из-за которой я не задерживаю дыхание), у вас есть пара вариантов
использование facet_wrap
а также alpha
Это не создаст хорошую легенду, но приведет вас к тому, что вы хотите.
Вы можете установить alpha
значение для масштабирования по вычисленному Frequency
Доступ к ..Frequency..
Я не думаю, что вы можете объединить легенды хорошо, хотя.
library(reshape2)
# in long format
dm <- melt(diamonds, measure.var = c('depth','carat'))
ggplot(dm, aes(y = price, fill = variable, x = value)) +
facet_wrap(~variable, ncol = 1, scales = 'free_x') +
stat_binhex(aes(alpha = ..count..), colour = 'grey80') +
scale_alpha(name = 'Frequency', range = c(0,1)) +
theme_bw() +
scale_fill_manual('Variable', values = setNames(c('darkblue','yellow4'), c('depth','carat')))
использование gridExtra
с grid.arrange
или же arrangeGrob
Вы можете создавать отдельные участки и использовать gridExtra::grid.arrange
расположить на одном изображении.
d_carat <- ggplot(diamonds, aes(x=carat,y=price))+
stat_binhex(colour="white",na.rm=TRUE)+
scale_fill_gradientn(colours=c("white","blue"),name = "Frequency",na.value=NA)
d_depth <- ggplot(diamonds, aes(x=depth,y=price))+
stat_binhex(colour="white",na.rm=TRUE)+
scale_fill_gradientn(colours=c("yellow","black"),name = "Frequency",na.value=NA)
library(gridExtra)
grid.arrange(d_carat, d_depth, ncol =1)
Если вы хотите, чтобы это работало с ggsave
(благодаря комментарию @bdemarest ниже и @baptiste)
замещать grid.arrange
с arrangeGrob
что-то вроде.
ggsave(plot=arrangeGrob(d_carat, d_depth, ncol=1), filename="plot_2.pdf", height=12, width=8)