Низкие, средние высокие цвета для децилей в ggplot

Я хочу иметь полигональный тип пространственных графиков, используя ggplot. В котором строятся полигоны и цвет полигонов определяется их весом.

Пример фрейма данных выглядит так - (вот файл данных CompleteDataFile)

    polyNr   x   y   centroidX   centroidY   weight
1   4459425.25  5328202.595264193   4459675.25  5328202.595264193   -13.055709633886783
1   4459550.25  5328419.101615138   4459675.25  5328202.595264193   -13.055709633886783
1   4459800.25  5328419.101615138   4459675.25  5328202.595264193   -13.055709633886783
1   4459925.25  5328202.595264193   4459675.25  5328202.595264193   -13.055709633886783
1   4459800.25  5327986.088913247   4459675.25  5328202.595264193   -13.055709633886783
1   4459550.25  5327986.088913247   4459675.25  5328202.595264193   -13.055709633886783
2   4457550.25  5337512.3683548765  4457800.25  5337512.3683548765  -118.36760699572329
2   4457675.25  5337728.874705822   4457800.25  5337512.3683548765  -118.36760699572329
2   4457925.25  5337728.874705822   4457800.25  5337512.3683548765  -118.36760699572329
2   4458050.25  5337512.3683548765  4457800.25  5337512.3683548765  -118.36760699572329
2   4457925.25  5337295.862003931   4457800.25  5337512.3683548765  -118.36760699572329
2   4457675.25  5337295.862003931   4457800.25  5337512.3683548765  -118.36760699572329
3   4475175.25  5336862.849302039   4475425.25  5336862.849302039   -3.397375074455629
3   4475300.25  5337079.355652984   4475425.25  5336862.849302039   -3.397375074455629
3   4475550.25  5337079.355652984   4475425.25  5336862.849302039   -3.397375074455629
3   4475675.25  5336862.849302039   4475425.25  5336862.849302039   -3.397375074455629
3   4475550.25  5336646.342951093   4475425.25  5336862.849302039   -3.397375074455629
3   4475300.25  5336646.342951093   4475425.25  5336862.849302039   -3.397375074455629
4   4464675.25  5343358.039830423   4464925.25  5343358.039830423   -51.57522722796112
4   4464800.25  5343574.546181369   4464925.25  5343358.039830423   -51.57522722796112
4   4465050.25  5343574.546181369   4464925.25  5343358.039830423   -51.57522722796112
4   4465175.25  5343358.039830423   4464925.25  5343358.039830423   -51.57522722796112
4   4465050.25  5343141.533479477   4464925.25  5343358.039830423   -51.57522722796112
4   4464800.25  5343141.533479477   4464925.25  5343358.039830423   -51.57522722796112
3438    4459050.25  5338378.393758661   4459300.25  5338378.393758661   1.066256760712294
3438    4459175.25  5338594.900109607   4459300.25  5338378.393758661   1.066256760712294
3438    4459425.25  5338594.900109607   4459300.25  5338378.393758661   1.066256760712294
3438    4459550.25  5338378.393758661   4459300.25  5338378.393758661   1.066256760712294
3438    4459425.25  5338161.887407715   4459300.25  5338378.393758661   1.066256760712294
3438    4459175.25  5338161.887407715   4459300.25  5338378.393758661   1.066256760712294

Мои шаги -

  1. Разделите весь набор данных на децили как

    breaks=unique(quantile(df$weight,probs=seq(0,1,by=0.1))) df$deciles = cut(df$weight,breaks=breaks,include.lowest=TRUE)

  2. цветовая шкала (я хочу, чтобы положительные числа были красными, а отрицательные - зелеными)

    library(RColorBrewer) colours=brewer.pal(name="RdYlGn", n=nlevels(df$deciles)) names(colours)=rev(levels(df$deciles))

  3. сюжет

    library(ggplot2) ggplot(df,aes(x=x,y=y)) + geom_polygon(aes(group=polyNr,fill=factor(deciles))) + scale_fill_manual(values=colours)

Это дает мне сюжет - похоже -

initialPlot

Но мое другое требование - я хочу, чтобы белый был нулем. В общем, я могу сделать это с помощью

scale_fill_gradient2(low = muted("green"), mid = "white", high = muted("red"), midpoint = 0,)

Но я не могу не использовать это с моей дискретной шкалой.

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

PS - Я использую один и тот же код для разных наборов данных, поэтому настройка ручной цветовой шкалы не является предпочтительной.

РЕДАКТИРОВАТЬ -

Для настройки цвета (красный, белый, зеленый) я также попробовал colorRampPalette. (Спасибо @ Pewi за указание)

colours = colorRampPalette(c("red", "white", "green"))(11)

Это дает мне следующий сюжет.

второй пробный участок

Тем не менее, установка белого цвета для нулевого веса является серьезной проблемой. Я столкнулся с той же проблемой в базовом пакете также.

2 ответа

Решение

Я интерпретирую ваш вопрос как "как мне создать n цветов в диапазоне от x до y, проходящих через белый". Одним из ответов на этот вопрос будет использование функции colorRampPaletteиз пакета grDevices

library(grDevices)

colours <- colorRampPalette(c("red", "white", "green"))(n = 21)

plot(1:21, col=colours,pch=18,cex=4)

Если вы замените свою часть 2 чем-то похожим, вы, вероятно, сможете получить желаемый результат.

Редактировать:

Боюсь, это будет не очень элегантно, но терпите меня.

#sim data
dat = data.frame(x =-3:9)

#cut into deciles
dat$y = cut(dat$x,breaks=quantile(dat$x,seq(0,1,0.1)),include.lowest = T)

#Find in wich decile the value closest to zero is
dat$part = as.numeric(dat$y) <= as.numeric(dat$y[which(abs(0-dat$x)==min(abs(dat$x-0)))])

#split color range into two parts
highcolours <- colorRampPalette(c("red","white"))(n = sum(dat$part==TRUE))
lowcolours <- colorRampPalette(c("white","green"))(n = sum(dat$part==FALSE)+1)

#combine colors
cols = c(highcolours,lowcolours)

#both high and low contain midpoint (white) remove one of them
cols = cols[!duplicated(cols)]

#Example 
plot(1:nrow(dat), col=cols ,pch=18,cex=4)

Смещенная от центра шкала цветов

Вот наконец то, что я сделал.

df = read.table("sampleData.txt",header=T) breaks=unique(quantile(df$weight,probs=seq(0,1,by=0.1))) df$deciles = cut(df$weight,breaks=breaks,include.lowest=TRUE) df$part = as.numeric(df$deciles) <= as.numeric(df$deciles[which(abs(0-df$weight)==min(abs(df$weight-0)))])

После этого шага у меня не может быть столько цветов, сколько точек данных. Таким образом я разделил на цветовую гамму в соотношении df $ part

highCols = round (sum(df$part==FALSE)*10/(sum(df$part==FALSE)+sum(df$part==TRUE)))
lowCols = 10 - highCols
highColours = colorRampPalette(c("red","darkred"))(n = highCols)
lowColours = colorRampPalette(c("darkgreen","green","white"))(n=lowCols)
cols = c(lowColours,highColours)
cols = cols[!duplicated(cols)]
ggplot(df,aes(x=x,y=y)) + geom_polygon(aes(group=polyNr,fill=factor(deciles))) + scale_fill_manual(values=cols)

Это даст мне сюжет -

Окончательный желаемый сюжет

Хотя сюжет все еще хорош, в долгосрочной перспективе я предпочитаю использовать более прямой метод, если это возможно. Благодарю.

Другие вопросы по тегам