Non-linear Color Pallette

59 views
Skip to first unread message

Zachary Johnson

unread,
Jun 20, 2017, 4:33:26 PM6/20/17
to ggplot2
Hello all,

I am trying to achieve a specific color palette and am having trouble doing so. Before I start, I should let you know I am new to R. The below code outputs the below plot (map - Image 1).

  palette <- c("#FFFCFF", "#FF8FFF", "#F200FF", "#8000FF", "#2635FF", "#389FFF", "#29FFC9",
               
"#FFFF00", "#FFBE00", "#FF8200", "#C24700", "#A12300", "#800000", "#300000")
 
  ggplot
() +
    theme_minimal
() +
    geom_tile
(data = idw.output, alpha = 1, aes(x = Longitude, y = Latitude, fill = round(Anomaly, 0.08))) +
    scale_fill_gradientn
(colors = palette,
                         values
= rescale(c(-15, -8, -5, -3, -2, -1, 0, 1, 2, 3, 5, 8, 15)),
                         name
= "°F",
                         limits
= c(-15,15),
                         breaks
= c(-15, -8, -5, -3, -2, -1, 0, 1, 2, 3, 5, 8, 15),
                         
#breaks = seq(-15, 15, 2),
                         guide
= guide_colorbar(nbin = 14,
                                                barwidth
= 27,
                                                title
.position = "bottom",
                                                raster
= FALSE,
                                                ticks
= FALSE)) +
    geom_polygon
(data = Mexico, aes(long, lat, group = group), color = "#606060", fill = "#606060") +
    geom_polygon
(data = Ocean, aes(long, lat, group = group), color = "#1A6088", fill = "#1A6088") +
    geom_path
(data = USA[SGreatPlains, ], aes(long, lat, group = group), color = "black", fill = "white") +
    geom_path
(data = Counties[TexasCounties, ], aes(long, lat, group = group), color = "grey40", size = 0.25) +
    geom_path
(data = USA[Texas, ], aes(long, lat, group = group), color = "black", size =1.25) +
    coord_equal
(xlim =c(-108,-92), ylim = c(25.25,37.5)) +
    scale_y_continuous
(expand = c(0,0)) +
    scale_x_continuous
(expand = c(0,0)) +
    labs
(title = paste("Maximum Temperature Anomaly in °F from", FromDate, "to", ToDate), x = "Longitude", y = "Latitude") +
    theme
(plot.title = element_text(face = "bold")) +
    theme
(legend.position = "bottom")

Example Output

(Image 1)



However, I am trying to achieve this color ramp.

(Image 2)

The palette variable in my code,

  palette <- c("#FFFCFF", "#FF8FFF", "#F200FF", "#8000FF", "#2635FF", "#389FFF", "#29FFC9",
               
"#FFFF00", "#FFBE00", "#FF8200", "#C24700", "#A12300", "#800000", "#300000")

represents the colors in the color palette that I am trying to achieve on Image 2. For example, #FFFCFF color represents -15 and less on Image 2. I cannot figure what I am doing wrong with my code? Any tips would be greatly appreciated.

Thanks!

Zach




Zachary Johnson

unread,
Jun 21, 2017, 1:58:28 PM6/21/17
to ggplot2
I guess I should mention what my idw.output looks like. Thanks.

 
   Longitude Latitude  Anomaly var1.var
1    -108.23    24.85 1.316596       NA
2    -108.22    24.85 1.316506       NA
3    -108.21    24.85 1.316417       NA
4    -108.20    24.85 1.316327       NA
5    -108.19    24.85 1.316238       NA
6    -108.18    24.85 1.316148       NA
7    -108.17    24.85 1.316059       NA
8    -108.16    24.85 1.315969       NA
9    -108.15    24.85 1.315880       NA
10   -108.14    24.85 1.315791       NA
11   -108.13    24.85 1.315701       NA
12   -108.12    24.85 1.315612       NA
13   -108.11    24.85 1.315523       NA
14   -108.10    24.85 1.315434       NA
15   -108.09    24.85 1.315345       NA
16   -108.08    24.85 1.315256       NA
17   -108.07    24.85 1.315167       NA
18   -108.06    24.85 1.315078       NA
19   -108.05    24.85 1.314989       NA
20   -108.04    24.85 1.314901       NA
21   -108.03    24.85 1.314812       NA
22   -108.02    24.85 1.314724       NA
23   -108.01    24.85 1.314635       NA
24   -108.00    24.85 1.314547       NA
25   -107.99    24.85 1.314458       NA
26   -107.98    24.85 1.314370       NA
27   -107.97    24.85 1.314282       NA
28   -107.96    24.85 1.314193       NA
29   -107.95    24.85 1.314105       NA
30   -107.94    24.85 1.314017       NA


Adriano Fantini

unread,
Jun 21, 2017, 2:24:06 PM6/21/17
to Zachary Johnson, ggplot2
I've had this problem before, I really feel that GGPLOT should add an option for shifted scaled. Anyhow, here is how I did it a few years back:
Basically my approach was to cut() data beforehand (using +Inf and -Inf too) and then use custom labels afterwards. That answer might not be complete, I'll try to see if I find a more recent example.

--
--
You received this message because you are subscribed to the ggplot2 mailing list.
Please provide a reproducible example: https://github.com/hadley/devtools/wiki/Reproducibility
 
To post: email ggp...@googlegroups.com
To unsubscribe: email ggplot2+unsubscribe@googlegroups.com
More options: http://groups.google.com/group/ggplot2

---
You received this message because you are subscribed to the Google Groups "ggplot2" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ggplot2+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Adriano Fantini

unread,
Jun 21, 2017, 2:27:24 PM6/21/17
to Zachary Johnson, ggplot2

zach...@comcast.net

unread,
Jun 21, 2017, 4:47:23 PM6/21/17
to Adriano Fantini, ggplot2
Hi Adriano,
 
Thanks for the response! I am familiar with GrADS and wish I had the programming skills to automate the processes within Fortran/GrADS. Anyway, when I cut() the data with -Inf and +Inf,
 
idw.output$cut <- cut(idw.output$Anomaly, breaks = c(-Inf, -15,-8,-5,-3,-2,-1,0,1,2,3,5,8,15, Inf)) 
 
how would I use scale_fill_manual() or scale_fill_gradientn() when the cut isn't a number? I don't seem to see it on your stackoverflow question. My cut looks like the below.
 
  Longitude Latitude  Anomaly var1.var   cut
1   -108.23    24.85 3.522920       NA (3,5]
2   -108.22    24.85 3.523250       NA (3,5]
3   -108.21    24.85 3.523580       NA (3,5]
4   -108.20    24.85 3.523909       NA (3,5]
5   -108.19    24.85 3.524239       NA (3,5]
6   -108.18    24.85 3.524569       NA (3,5]
 
Appreciate your help.
Best,
 
Zach Johnson

From: "Adriano Fantini" <adr.f...@gmail.com>
To: "Zachary Johnson" <zach...@comcast.net>
Cc: "ggplot2" <ggp...@googlegroups.com>
Sent: Wednesday, June 21, 2017 1:26:26 PM
Subject: Re: Non-linear Color Pallette
To unsubscribe: email ggplot2+u...@googlegroups.com

More options: http://groups.google.com/group/ggplot2

---
You received this message because you are subscribed to the Google Groups "ggplot2" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ggplot2+u...@googlegroups.com.

Brandon Hurr

unread,
Jun 21, 2017, 5:45:12 PM6/21/17
to zach...@comcast.net, Adriano Fantini, ggplot2
Cut returns a factor. See ?cut

You can apply labels to the groups:

set.seed(12345)
test <- runif(100, min = -20, max = 20)
testfactor <-cut(test, breaks = c(-Inf, -15,-8,-5,-3,-2,-1,1,2,3,5,8,15, Inf), labels = c("-15","-8","-5","-3","-2","-1","0","1","2","3","5","8","15") )
# convert back to numeric? 
as.numeric(as.character(testfactor))

#  [1]   8  15   8  15  -1  -8  -5   0   8  15 -15  -8   8 -15  -3  -1  -3  -3  -8  15  -1  -5  15
# [24]   8   5  -3   5   1  -8   0   8 -15  -8   5  -5  -5   8  15   3  -8   8  -2  15   8  -8  -5
# [47] -15 -15 -15   5  15   8  -5  -8   8   0   8 -15  -2  -8   8  -8  15   8  15  -8  15  -8   3
# [70]  15   5   0  -5  -5 -15   3  15   5   0  -8   8   0 -15 -15  -8  -5   8   0   8 -15  15   8
# [93] -15   3   8   0   8   8 -15  -3

After having done that, I'm not sure that's really what you need. I think you probably need an ordered factor to define your colors.

Could you supply a fully reproducible example? It would really help put all the pieces together. 

B


More options: http://groups.google.com/group/ggplot2

---
You received this message because you are subscribed to the Google Groups "ggplot2" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ggplot2+unsubscribe@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

--
--
You received this message because you are subscribed to the ggplot2 mailing list.
Please provide a reproducible example: https://github.com/hadley/devtools/wiki/Reproducibility
 
To post: email ggp...@googlegroups.com

More options: http://groups.google.com/group/ggplot2

---
You received this message because you are subscribed to the Google Groups "ggplot2" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ggplot2+unsubscribe@googlegroups.com.

Adriano Fantini

unread,
Jun 22, 2017, 7:57:14 AM6/22/17
to Brandon Hurr, Zachary Johnson, ggplot2
I usually do something along the lines of:

#Given bins a vector of bins to cut the data into
#Given cols a vector of colors of length (length(bins) + 1)
#Given dfr a data.frame with Lat, Lon and Value as columns
​ (or something similar...)​

bins <- unique(c(-Inf, bins, Inf))
​ #Make sure your bins extend to infinity​

dfr[,4] <- cut(dfr[,3], bins)
​ #Add a column with the factor values​

colnames(dfr) <- c("x", "y", "val", "factorval")
labels <- c(bins[-length(bins)][-1], "")
​ #Create the labels​

ggplot(dfr, aes(x=y, y=y, fill=factorval)) + 
        scale_fill_manual(values=cols, labels=labels, drop=FALSE) +
        theme(legend.key = element_rect(color="black"),
                    legend.key.width = unit(1, "cm"),
                    legend.key.height = unit(0.3, "cm") ) +
        guides(fill=guide_legend(label.position = "bottom", label.hjust = 1.2, title.position="top", title.hjust=0.5, nrow=1))

​Hope it helps.​

zach...@comcast.net

unread,
Jun 22, 2017, 8:51:14 AM6/22/17
to Brandon Hurr, Adriano Fantini, ggplot2
Hi Brandon,
 
I'll take a look and try to work mess with your examples to see if I can make it work. It will take me a bit since I am new to R (programming in general). I am attaching an reproducible example. I appreciate the help!
 
Thank you,
 
Zach
 
 


From: "Brandon Hurr" <brando...@gmail.com>
To: zach...@comcast.net
Cc: "Adriano Fantini" <adr.f...@gmail.com>, "ggplot2" <ggp...@googlegroups.com>
Sent: Wednesday, June 21, 2017 4:44:51 PM
To unsubscribe: email ggplot2+u...@googlegroups.com

More options: http://groups.google.com/group/ggplot2

---
You received this message because you are subscribed to the Google Groups "ggplot2" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ggplot2+u...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

--
--
You received this message because you are subscribed to the ggplot2 mailing list.
Please provide a reproducible example: https://github.com/hadley/devtools/wiki/Reproducibility
 
To post: email ggp...@googlegroups.com
To unsubscribe: email ggplot2+u...@googlegroups.com

More options: http://groups.google.com/group/ggplot2

---
You received this message because you are subscribed to the Google Groups "ggplot2" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ggplot2+u...@googlegroups.com.
example.r
idw.output.rds

Crump, Ron

unread,
Jun 22, 2017, 9:37:26 AM6/22/17
to zach...@comcast.net, Brandon Hurr, Adriano Fantini, ggplot2
>I'll take a look and try to work mess with your examples to see if I can
>make it work. It will take me a bit since I am new to R (programming in
>general). I am attaching an reproducible example. I appreciate the help!

library(ggplot2)
idw.output <- readRDS("idw.output.rds")
# I'm re-doing the factor to have required level labels, I'm sure there is
# a better way to do this though. NB you could have given them the labels
# you wanted when you first set it up.
idw.output$cut <- factor(as.integer(idw.output$cut),
levels=1:14,
labels=c(-15,-8,-5,-3,-2,-1,0,1,2,3,5,8,15,''))
# Ive used a different name as palette is a function name
my.palette <- c("#FFFCFF", "#FF8FFF", "#F200FF", "#8000FF", "#2635FF",
"#389FFF", "#29FFC9", "#FFFF00", "#FFBE00", "#FF8200", "#C24700",
"#A12300", "#800000", "#300000")
# Not using all the bits not related to your query:
ggplot(idw.output)+geom_tile(aes(x=Longitude,y=Latitude,fill=cut))+
scale_fill_manual(values=my.palette)

is a starting point. But in the data sent, only the middle values of the
range are represented. Not sure how you'd create a legend spanning all
values if that is the wish. I'd edit the palette to reflect the values
present (or do you have a bigger dataset with greater variation?).

I think some of the SO references in the thread used a vjust to shift the
labels a little in the legend too.

Ron.



Zachary Johnson

unread,
Jun 22, 2017, 4:23:55 PM6/22/17
to ggplot2, zach...@comcast.net, brando...@gmail.com, adr.f...@gmail.com, R.E....@warwick.ac.uk
Thank you so much for all the helpful solutions!

I imitated Ron's example with my code. I introduced some dummy anomaly values in my idw.output half way around the world (so they don't affect the idw). That allows for my color bar to be constant every time I run the script. I still can't figure out how to reduce the spacing of each color in the color bar. Ideally, I would like the color bar to look like it does in the first plot, however, this is a great start. I can work it from here. Appreciate you all going out of your way to help me.

# Interpolate surface and fix the output
  idw                      
<- idw(formula = ANOMALY ~ 1, locations = AnomalyTemp2, newdata = grd, idp=2.0)
  idw
.output1                <- as.data.frame(idw)
 
 
# Create dummy values half way around the earth so the color palette works. IDW wont be affected since values half way around planet
  idw
.output.dummyvar1      <- as.numeric(c("32.1", "32.2", "32.3", "32.4", "32.5", "32.6", "32.7", "32.8", "32.9", "33", "33.1", "33.2", "33.3", "33.4"))
  idw
.output.dummyvar2      <- as.numeric(c("-32.1", "-32.2", "-32.3", "-32.4", "-32.5", "-32.6", "-32.7", "-32.8", "-32.9", "-33", "-33.1", "-33.2", "-33.3", "-33.4"))
  idw
.output.dummyvar3      <- as.numeric(c("-16", "-13", "-7", "-4", "-2.5", "-1.5", "-0.5", "0.5", "1.5", "2.5", "4", "7", "13", "16"))
  idw
.output.dummyvar4      <- c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA)
  idw
.output.dummy          <- data.frame(idw.output.dummyvar1, idw.output.dummyvar2, idw.output.dummyvar3, idw.output.dummyvar4)
  idw
.output.dummy          <- setNames(idw.output.dummy, c("x", "y", "var1.pred", "var1.var"))
 
 
# rbind dummy values with actual values
  idw
.output                <- rbind(idw.output1, idw.output.dummy)
 
 
# Preparing the color palette
  idw
.output$var1.var       <- NULL
  names
(idw.output)[1:3]    <- c("Longitude", "Latitude", "Anomaly")

  idw
.output$cut            <- cut(idw.output$Anomaly, breaks = c(-Inf, -15,-8,-5,-3,-2,-1,0,1,2,3,5,8,15, Inf))

  idw
.output$cut            <- factor(as.integer(idw.output$cut),
                                 levels
=1:14,
                                 labels
=c(-15,-8,-5,-3,-2,-1,0,1,2,3,5,8,15, ''))

 
 
# The palette for the temp anomaly map
 
my.palette <- c("-15" = "#FFFCFF", "-8" = "#FF8FFF", "-5" = "#F200FF", "-3" = "#8000FF", "-2" = "#2635FF", "-1" = "#389FFF",
               
"0" = "#29FFC9", "1" = "#FFFF00", "2" = "#FFBE00", "3" = "#FF8200", "5" = "#C24700", "8" = "#A12300",
               
"15" = "#800000", "#300000")
 
 
#my.palette <- c("#FFFCFF", "#FF8FFF", "#F200FF", "#8000FF", "#2635FF", "#389FFF", "#29FFC9",
 
#             "#FFFF00", "#FFBE00", "#FF8200", "#C24700", "#A12300", "#800000", "#300000")
 
  ggplot
(idw.output) +
    theme_minimal
() +
    geom_tile
(aes(x = Longitude, y = Latitude, fill = cut)) +
    scale_fill_manual
(values=my.palette,
                      name
= "°F") +

    geom_polygon
(data = Mexico, aes(long, lat, group = group), color = "#606060", fill = "#606060") +
    geom_polygon
(data = Ocean, aes(long, lat, group = group), color = "#1A6088", fill = "#1A6088") +
    geom_path
(data = USA[SGreatPlains, ], aes(long, lat, group = group), color = "black", fill = "white") +
    geom_path
(data = Counties[TexasCounties, ], aes(long, lat, group = group), color = "grey40", size = 0.25) +
    geom_path
(data = USA[Texas, ], aes(long, lat, group = group), color = "black", size =1.25) +
    coord_equal
(xlim =c(-108,-92), ylim = c(25.25,37.5)) +
    scale_y_continuous
(expand = c(0,0)) +
    scale_x_continuous
(expand = c(0,0)) +
    labs
(title = paste("Maximum Temperature Anomaly in °F from", FromDate, "to", ToDate), x = "Longitude", y = "Latitude") +
    theme
(plot.title = element_text(face = "bold")) +

    theme
(legend.position = "bottom") +
    guides
(fill = guide_legend(nrow=1, keywidth=1, keyheight=1)) +
    theme
(panel.background = element_rect(fill = "grey", color = "grey"), legend.text=element_text(size=11))

Zachary Johnson

unread,
Jun 22, 2017, 4:25:46 PM6/22/17
to ggplot2, zach...@comcast.net, brando...@gmail.com, adr.f...@gmail.com, R.E....@warwick.ac.uk
Err, my code wasn't all completely copied to the last message. My bad.

Reply all
Reply to author
Forward
0 new messages