Color palette with ggplot

To create a reproducible example, I would have to provide shapefile data, etc., and that would be cumbersome for you (loading data, etc.), so here's an attempt, just providing the last part, and what about ggplot

Here's some sample code:

cols <- colorRampPalette(c("darkgreen","yellow","red"), space = "rgb")
myPal <- cols(11) 

ggplot(data=df, aes(x=long, y=lat, group=group)) + 
   geom_polygon(aes(fill = measure))+    # draw polygons
   coord_equal() +
   scale_x_continuous(breaks = as.numeric(levels(factor(df$measure))))+
   scale_fill_manual(values = myPal)+
   labs(title="mesure level", x="", y="")+
   theme(axis.text=element_blank(),axis.ticks=element_blank())

      

Basically, I'm trying to apply my own colors to fill regions by specifying a range of colors. The above doesn't work as it throws an error:

Error: Continuous value supplied to discrete scale

      

EDIT: This works, however:

ggplot(data=df, aes(x=long, y=lat, group=group)) + 
  geom_polygon(aes(fill = measure))+    # draw polygons
  coord_equal() +
  geom_path(color="grey", linestyle=2)+
  scale_fill_gradient(low = "#ffffcc", high = "#ff4444", 
                  space = "Lab", na.value = "grey50",
                  guide = "colourbar")+
  labs(title="measure level", x="", y="")+
  theme(axis.text=element_blank(),axis.ticks=element_blank())

      

EDIT2: The variable measure

is numeric () and this is how I insert the measure:

  df$measure <- as.numeric(round(runif(nrow(df), 0, 1), 1))

      

dput

is huge, so here str ()

str(df)
'data.frame':   344858 obs. of  8 variables:
$ long   : num  18 18 18 18 18 ...
$ lat    : num  48.7 48.7 48.7 48.7 48.7 ...
$ order  : int  1 2 3 4 5 6 7 8 9 10 ...
$ hole   : logi  FALSE FALSE FALSE FALSE FALSE FALSE ...
$ piece  : Factor w/ 2 levels "1","2": 1 1 1 1 1 1 1 1 1 1 ...
$ group  : Factor w/ 80 levels "0.1","1.1","2.1",..: 1 1 1 1 1 1 1 1 1 1    ...
$ id     : chr  "0" "0" "0" "0" ...
$ measure: num  0.7 0.4 0.8 0.8 0.8 0.2 0.8 0.5 0.2 0 ...

      

+3


source to share


2 answers


Uh-huh. scale_fill_gradient

is continuous. scale_fill_manual

is discrete and is measure

definitely numeric (and not a factor), so what you see is completely expected behavior. Here's an example toy to help explain:

library(rgdal)
library(curl)
library(ggplot2)
library(ggthemes)

# get a simple shapefile

map_url <- "https://andrew.cartodb.com/api/v2/sql?filename=us_states_hexgrid&q=SELECT+*+FROM+andrew.us_states_hexgrid&format=geojson&api_key="

res <- curl_fetch_disk(map_url, "hexes.json")

hex <- readOGR("hexes.json", "OGRGeoJSON")

## OGR data source with driver: GeoJSON 
## Source: "hexes.json", layer: "OGRGeoJSON"
## with 51 features
## It has 6 fields

str(hex@data)

## 'data.frame':    51 obs. of  6 variables:
##  $ cartodb_id: int  1219 1217 1218 220 215 228 232 227 230 229 ...
##  $ created_at: Factor w/ 4 levels "2015-05-13T22:02:22Z",..: 4 2 3 1 1 1 1 1 1 1 ...
##  $ updated_at: Factor w/ 51 levels "2015-05-14T14:17:56Z",..: 20 40 47 12 44 2 3 11 19 25 ...
##  $ label     : Factor w/ 51 levels "A.K.","Ala.",..: 20 40 47 12 44 2 3 11 19 25 ...
##  $ bees      : num  60.5 47.8 33.9 13.9 46.3 48.1 42.9 34.9 44.3 38.7 ...
##  $ iso3166_2 : Factor w/ 51 levels "AK","AL","AR",..: 22 40 47 12 44 2 4 11 19 26 ...

      

We will use bees

it since it is similar to yours measure

.

# make it so we can use the polygons in ggplot

hex_map <- fortify(hex, region="iso3166_2")

str(hex_map)

## 'data.frame':    357 obs. of  7 variables:
##  $ long : num  -133 -130 -130 -133 -135 ...
##  $ lat  : num  55.3 54.4 52.5 51.6 52.5 ...
##  $ order: int  1 2 3 4 5 6 7 8 9 10 ...
##  $ hole : logi  FALSE FALSE FALSE FALSE FALSE FALSE ...
##  $ piece: Factor w/ 1 level "1": 1 1 1 1 1 1 1 1 1 1 ...
##  $ group: Factor w/ 51 levels "AK.1","AL.1",..: 1 1 1 1 1 1 1 2 2 2 ...
##  $ id   : chr  "AK" "AK" "AK" "AK" ...

      

It bees

will be considered a continuous variable by default, and the default fill color scale will reflect this:

gg <- ggplot()
gg <- gg + geom_map(data=hex_map, map=hex_map,
                    aes(x=long, y=lat, map_id=id),
                    fill="#ffffff", color="#7f7f7f", size=0.25)
gg <- gg + geom_map(data=hex@data, map=hex_map, aes(map_id=iso3166_2, fill=bees))
gg <- gg + coord_map()
gg <- gg + theme_map()
gg <- gg + theme(legend.position="right")
gg

      

enter image description here

You can have ggplot's use of automatic cuts and a discrete color palette versus a continuous color map with scale_fill_distiller

:



gg <- ggplot()
gg <- gg + geom_map(data=hex_map, map=hex_map,
                    aes(x=long, y=lat, map_id=id),
                    fill="#ffffff", color="#7f7f7f", size=0.25)
gg <- gg + geom_map(data=hex@data, map=hex_map, aes(map_id=iso3166_2, fill=bees))
gg <- gg + scale_fill_distiller()
gg <- gg + coord_map()
gg <- gg + theme_map()
gg <- gg + theme(legend.position="right")
gg

      

enter image description here

You can also do manual cut outside of ggplot operations and pass this new column to scale_fill_manual

.

If you must use a continuous color gamut, consider using the viridis color map:

devtools::install_github("sjmgarnier/viridis")
library(viridis)

gg <- ggplot()
gg <- gg + geom_map(data=hex_map, map=hex_map,
                    aes(x=long, y=lat, map_id=id),
                    fill="#ffffff", color="#7f7f7f", size=0.25)
gg <- gg + geom_map(data=hex@data, map=hex_map, aes(map_id=iso3166_2, fill=bees))
gg <- gg + coord_map()
gg <- gg + scale_fill_viridis()
gg <- gg + theme_map()
gg <- gg + theme(legend.position="right")
gg

      

enter image description here

It is more accurate overall, accurately visible to the blind and grayscale downscaling (and accurate).

+6


source


With scale_manual

you "[c] re-create your own discrete scale" ( ?scale_fill_manual

). Thus, the error "Error: continuous value [ie" The measurement "] is fed to the discrete scale [ scale_fill_manual

]".

You need a continuous scale and give it a try scale_fill_gradient

. Good. However, it would be easier to achieve the desired palette by using scale_fill_gradientn

that creates a "Smooth Color Gradient Between n Colors".

A simpler example:



# some data
df <- data.frame(x = 1:11, y = 1)

# an analogue to your failed attempt 
ggplot(data = df, aes(x = x, y = y, fill = x)) +
  geom_point(pch = 21, size = 20) +
  scale_fill_manual(values = myPal)
# Error: Continuous value supplied to discrete scale


# using the continuous scale_fill_gradientn instead, with the desired color vector and space
ggplot(data = df, aes(x = x, y = y, fill = x)) +
  geom_point(pch = 21, size = 20) +
  scale_fill_gradientn(colours = c("darkgreen", "yellow", "red"), space = "rgb")  

      

enter image description here

+1


source







All Articles