7

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?

Community
  • 1
  • 1
Chika
  • 1,455
  • 2
  • 16
  • 24
  • I think you may be confusing color and fill. By specifying `color=...` in `geom_tile(...)` you are specifying the *border color*, which is not what you want. That's why you "have a lot of little squares". Reordering the legend is a bit more complicated. If you upload your dataset (including the map) and provide links, I can show you. – jlhoward May 09 '14 at 20:14
  • setting `decreasing = FALSE` in `breaks <- breaks[order(labels,decreasing = TRUE)]` and `labels <- labels[order(labels,decreasing = TRUE)]` should set the order of legend labels as ascending – Silence Dogood May 09 '14 at 20:18
  • TRUE, I changed it and my new problem is that I can't change the legend (name, color, order). jlhoward, what do you mean by provide links? – Chika May 09 '14 at 21:15
  • For future reference, you need to use the "@" before a name if you want them to see your comment. Provide links means upload your dataset, e.g. to Dropbox or some such, and provide a link so we can download it and use in in the response. It looks like you have an answer that works for you though, so no need at this point. – jlhoward May 10 '14 at 18:39

1 Answers1

11

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

BrodieG
  • 51,669
  • 9
  • 93
  • 146