Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ggplot2 continuous colors for discrete scale and delete a legend

Tags:

r

ggplot2

I have the following data frame:

df
zone        X        Y   Value
   1   604000  2673000     522
   1   612000  2643000     524
   .        .        .       .
   .        .        .       .
 615   604000  2673000     698

In fact I have 615 zones, X and Y are the Lambert coordinates and Value is the rain. My zones represents France and I am trying to plot them:

mi <- 300
ma <- 1900

df$val <- cut(df$Sim, breaks=seq(mi,ma,100),
          labels = paste( "(", format(seq(mi,ma,100)[1:(length(seq(mi,ma,100))-1)]), 
                          ", ", format(seq(mi,ma,100)[-1]), "]", sep = ""))

breaks <- unique(bincol(df$Sim,"green","yellow","red"))
breaks <- breaks[order(unique(df$val))]

p <- ggplot(data =df, aes(x=X, y=Y))
p <- (p    
      + theme_bw()
      + coord_equal() 
      + geom_tile(aes(fill=val))
      + scale_colour_manual("mm", values = breaks)
      + geom_path(data = polfrance, colour = 'black', 
               aes(x = long, y = lat, group = group))
      + geom_path(data = sympzones, colour = 'grey40', 
                  aes(x = long, y = lat, group = group))
      )

p <- (p + scale_y_continuous(limits=c(1580000,2730000),
                         breaks=seq(1600000,2700000, 200000), 
                         labels= seq(1600,2700,200), expand=c(0,0))
        + scale_x_continuous(limits=c(0,1250000), 
                         breaks= seq(0,1250000, 400000), 
                         labels= seq(0,1250, 400), expand=c(0,0))
        + xlab("X Lambert  [km]")
        + ylab("Y Lambert  [km]")
        )

I use sympzones and polfrance to draw the contour of my zones.

AND

bincol <- function(x,low,medium,high) {
  breaks <- function(x) pretty(range(x), n = nclass.Sturges(x), min.n = 1)

  colfunc <- colorRampPalette(c(low, medium, high))

  binned <- cut(x,breaks(x))

  res <- colfunc(length(unique(binned)))[as.integer(binned)]
  names(res) <- as.character(binned)
  res
}

Values are from 300 to 1900 and this is what I obtain:

plot

I have a problem:

I can't change the legend, this is the legend from geom_file and it doesn't take into account the scale_colour_manual. So this is not an ascending order, not the good title (I want "mm") and not the good colors.

I don't know if it is really clear... Can someone help me?

Edit: I took inspiration from that: easiest way to discretize continuous scales for ggplot2 color scales?

like image 332
Chika Avatar asked May 09 '14 19:05

Chika


1 Answers

You have two scales because you are using both a fill and a color aesthetic, and you are using different variables for them (one discrete, one continuous). What you want to do is use a single variable just for the fill.

Additionally, your labels are all messed up because you are passing them as character, which ggplot will then sort lexically (so "10" comes before "2").

Here is a solution that bypasses both these problems. We keep the original factor format for the output of cut, which will be labeled in the correct order, and we just use the fill aesthetic. Note also how much simpler it is to set the scale by creating the colors and labeling them with the levels, and using scale_fill_manual:

library(ggplot2)
df <- expand.grid(1:10, 1:10)                   # make up data
df <- transform(df, z=Var1 * Var2)              # make up data
df <- transform(df, z.cut=cut(z, 10))           # bin data

colors <- colorRampPalette(c("blue", "yellow", "red"))(length(levels(df$z.cut)))
ggplot(df, aes(x=Var1, y=Var2, fill=z.cut)) + 
  geom_tile() +
  scale_fill_manual(values=setNames(colors, levels(df$z.cut)))

enter image description here

like image 141
BrodieG Avatar answered Sep 28 '22 10:09

BrodieG