How to modify the colors in the legend of a plot u

2019-07-16 12:34发布

问题:

Following up on this question, how would you modify the colors of a contour plot legend?

Here is how to generate the plot:

x <- rep(seq(0.01, 0.1, length.out = 50), 50)
y <- rep(seq(0.01, 0.1, length.out = 50), each = 50)
z <- 1 / (x^2 + y^2)

my.data <- data.frame(x, y, z)

ggplot(my.data, aes(x = x, y = y, fill = z)) +
  geom_tile() +
  scale_fill_gradientn(colours = c("blue",
                                   "cyan",
                                   "green",
                                   "yellow",
                                   "orange",
                                   "red"),
                       values = rescale(c(0.3, 1, 2, 5, 10, 20, 35))) +
  scale_x_continuous(expand = c(0, 0)) +
  scale_y_continuous(expand = c(0, 0))

Here is the result:

I want to be able to set manually the colors (I know how to do it for the breaks) so that it is more readable. In the example above, you cannot say much about lower values, which might be the most interested in. The blue color does not even appear in the legend.

回答1:

It looks like your values=... is messing things up. Reading the documentation and experimenting with the values function, it looks like by specifying the range, you are giving less/more weight to each of the colors. What I think the problem you're running into is that the colors are still in the legend, but because they are being "weighted" so much less due to your values call, they aren't visible (that is they are there, but they are a tiny sliver of the legend).

You can experiment with this if you try doing an extreme value for the values=.... I use 100 in this example:

ggplot(my.data) +
  geom_tile(aes(x = x, y = y, fill = z)) +
  scale_fill_gradientn(colours = c("blue",
                                   "cyan",
                                   "green",
                                   "yellow",
                                   "orange",
                                   "red"),
                       values = rescale(c(0.3, 1, 2, 5, 10, 20, 100))) +
  scale_x_continuous(expand = c(0, 0)) +
  scale_y_continuous(expand = c(0, 0))

You can see that basically the whole legend is taken over by red and furthermore, there is much more red in the plot.

To correct your issue, you could try something without the values=... like this:

ggplot(my.data) +
  geom_tile(aes(x = x, y = y, fill = z)) +
  scale_fill_gradientn(colours = c("blue",
                                   "cyan",
                                   "green",
                                   "yellow",
                                   "orange",
                                   "red"))+
  scale_x_continuous(expand = c(0, 0)) +
  scale_y_continuous(expand = c(0, 0))

Then you can see the legend has the blue in it, but there is much more blue in your plot. This is an artifact of your data. If you try quantile(my.data$z,c(seq(0,1,by=0.05))) you can see that the 95th percentile is ~800 and the max is 5000. As you can see in your legend z values under 1000 is being filled with blue (which is 95% of your data!).

If you want it to have less blue, you could mess around with the values again (which I don't recommend - you probably want to accurately represent your data). Something like this:

ggplot(my.data) +
  geom_tile(aes(x = x, y = y, fill = z)) +
  scale_fill_gradientn(colours = c("blue",
                                   "cyan",
                                   "green",
                                   "yellow",
                                   "orange",
                                   "red"),
                       values =rescale(c(0.3, 3, 4, 5, 10, 20, 35))) +
  scale_x_continuous(expand = c(0, 0)) +
  scale_y_continuous(expand = c(0, 0))

Alternatively, and which I think is a better solution, you could get rid of your outliers so your plot isn't as skewed. Right now the ggplot function without the values manipulation is accurately representing your data.



标签: r ggplot2