Низкие, средние высокие цвета для децилей в 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
Мои шаги -
Разделите весь набор данных на децили как
breaks=unique(quantile(df$weight,probs=seq(0,1,by=0.1))) df$deciles = cut(df$weight,breaks=breaks,include.lowest=TRUE)
цветовая шкала (я хочу, чтобы положительные числа были красными, а отрицательные - зелеными)
library(RColorBrewer) colours=brewer.pal(name="RdYlGn", n=nlevels(df$deciles)) names(colours)=rev(levels(df$deciles))
сюжет
library(ggplot2) ggplot(df,aes(x=x,y=y)) + geom_polygon(aes(group=polyNr,fill=factor(deciles))) + scale_fill_manual(values=colours)
Это дает мне сюжет - похоже -
Но мое другое требование - я хочу, чтобы белый был нулем. В общем, я могу сделать это с помощью
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)
Это даст мне сюжет -
Хотя сюжет все еще хорош, в долгосрочной перспективе я предпочитаю использовать более прямой метод, если это возможно. Благодарю.