Reputation: 339
I am working to use r's ggplot to recreate a graphic originally created in python. The graphic uses a color scale specified via RGB colors. When I create my graphic using the same RGB colors they don't render properly in my Windows 10/Rstudio set up. Below I show the legend rendered correctly and the rendering my r script produces. It seems there is too much yellow coming through the colors.
I don't know where to begin to try to determine why the specified colors are not rendering into the same colors as the example image that I have. What suggestions do you have to try to troubleshoot this?
My reproducible example is below.
library(urbnmapr)
library(ggplot2)
library(dplyr)
library(ggthemes)
# Set colors
red <- c(0.67, 0.75, 0.84, 0.92, 1, 1, 0.8, 0.53, 0, 0, 0, 0)
green <- c(0.25, 0.4, 0.56, 0.71, 0.86, 1, 1, 0.95, 0.9, 0.75, 0.6, 0.48)
blue <- c(0.11, 0.18, 0.25, 0.33, 0.4, 0.45, 0.4, 0.27, 0, 0, 0, 0)
# Obtain county polygon data
states_sf <- get_urbn_map(map = "states", sf = TRUE)
counties_sf <- get_urbn_map(map = "counties", sf = TRUE)
# Assign random values of data to each count
counties_sf$value = runif(length(counties_sf$county_fips), min=-3.0, max=3.0)
# Remove AK and HI - lower 48 only
states_sf <- states_sf[!(states_sf$state_abbv %in% c("HI","AK")),]
counties_sf <- counties_sf[!(counties_sf$state_abbv %in% c("HI","AK")),]
# Plot county level data with a discrete legend
data_levels <- c(-3,-1.5, -0.8, -0.5, -0.25,-0.1,0.1,0.25,0.5,.8,1.5,3)
level_colors <- rgb(red, green, blue)
length(data_levels)
length(level_colors)
counties_sf %>%
ggplot() +
# Overlay State Outlines
# Plot county data and fill with value
geom_sf(mapping = aes(fill = value), color = NA) +
geom_sf(data = states_sf, fill = NA, color = "black", size = 0.25) +
# Remove grid lines from plot
coord_sf(datum = NA) +
scale_fill_stepsn(breaks=data_levels, colors=level_colors, limits=c(-3,3),
labels=scales::label_number(accuracy=0.1)) +
labs(title='This Data is Completely Random',
fill ='The Legend') +
theme_map() +
theme(legend.position = "bottom",
legend.key.width=unit(1.5,"cm"),
legend.box.background = element_rect(color="black", size=2),
legend.title = element_text(face = "bold"),
legend.spacing = unit(0.25,"cm"),
legend.justification = "center",
plot.title=element_text(hjust=0.5)) +
guides(fill = guide_bins(title.position="top", title.hjust = 0.5,
keywidth=unit(20,'points'), axis=FALSE,
axis.linewidth=unit(3,'points')))
Upvotes: 1
Views: 263
Reputation: 78917
Is this the plot you are looking for? Use n.breaks=12
Replace
scale_fill_stepsn(breaks=data_levels, colors=level_colors, limits=c(-3,3), labels=scales::label_number(accuracy=0.1)) +
with
scale_fill_stepsn(n.breaks=12, colors=level_colors, limits=c(-3,3), labels=scales::label_number(accuracy=0.1)) +
When I run your code I get this plot.
Upvotes: 2
Reputation: 9582
Looks like perhaps you aren't using all the levels? I didn't install the urbnmapr
package to run your example, but when I run this more minimal example the colors look about right.
# Set colors
red <- c(0.67, 0.75, 0.84, 0.92, 1, 1, 0.8, 0.53, 0, 0, 0, 0)
green <- c(0.25, 0.4, 0.56, 0.71, 0.86, 1, 1, 0.95, 0.9, 0.75, 0.6, 0.48)
blue <- c(0.11, 0.18, 0.25, 0.33, 0.4, 0.45, 0.4, 0.27, 0, 0, 0, 0)
level_colors <- rgb(red, green, blue)
library(ggplot2)
ggplot(data.frame(x=level_colors, y=1),
aes(x=level_colors, y=1, fill=level_colors)) +
geom_col() +
scale_fill_manual(values = level_colors)
Note that if not all the levels are present in the data, they don't all show up.
ggplot(data.frame(x=level_colors[1:5], y=1),
aes(x=x, y=y, fill=factor(x))) +
geom_col() +
scale_fill_manual(values = level_colors)
But you can force them to show in legend with drop = FALSE
in the scale call:
dat <- data.frame(x=factor(level_colors, levels=level_colors), y=1)
ggplot(dat[1:5,], aes(x=x, y=y, fill=x)) +
geom_col() +
scale_fill_manual(values = level_colors, drop=F)
Upvotes: 2