The colorplaner R package is a ggplot2 extension to visualize two variables through one color aesthetic via mapping to a color space projection. The extension implements two new scales, scale_color_colorplane
and scale_fill_colorplane
, two new aesthetics, color2
and fill2
, and a new guide guide_colorplane
.
While Edward Tufte praises map visualizations as inherently high in dimensionality due to their geographic data, in practice maps are generally limited to no more than a single variable as a fill color without becoming uninterpretable.
The colorplaner package is an exploration into the possibility of using a single color aesthetic to convey the values of multiple variables in an interpretable way. While designed with map visualizations in mind it will work anywhere that a color gradient scale would work, thanks to the flexibility of ggplot2 extensions.
The spectrum of visible colors can be represented as a variety of different color spaces, and most of these use three parameters to define an individual color and thus can be represented as a 3-dimensional volume with a different color at each {x, y, z} point. While this could easily facilitate mapping three data variables to color using any arbitrary color space system, the results are not necessarily intuitively interpretable to the viewer.
The YUV color space (wikipedia) was designed at the advent of color television broadcasting to encode color data in a manner that would be backwards-compatible with black & white sets. To do this, the luminance of each pixel is encoded into one component (Y), which provides all of the information used by black & white displays, and all of the color information (chrominance) is encoded into the remaining two components (U & V).
When Y is held constant, the remaining color space is a U-V plane with corners of saturated green, orange, fuchsia, and blue and smooth gradients in between.
Holding Y constant at 35% yields this U-V color plane
Mapping data variables to these U and V components turns this color plane into a scale that produces a unique color for each combination of values for the two variables, and using these colors for the color
or fill
aesthetics of plotted objects allows the view to easily approximate the values of the two mapped variables and to discern relative values by comparing colors.
To implement color plane mapping in a ggplot
, simply create aesthetic mappings to color
and color2
or fill
and fill2
and add the corresponding color plane scale to the plot. The corresponding guide is added by default.
data(mtcars)
ggplot(mtcars, aes(x = wt, y = mpg, color = disp, color2 = hp)) +
geom_point(size = 5) +
scale_color_colorplane()
if(require(mapproj)) {
crimes <- data.frame(state = tolower(rownames(USArrests)), USArrests)
states_map <- map_data("state")
ggplot(crimes, aes(map_id = state, fill = Murder, fill2 = UrbanPop)) +
geom_map(map = states_map) +
scale_fill_colorplane() +
expand_limits(x = states_map$long, y = states_map$lat) +
coord_map()
}
Like ggplot2, colorplaner works with sensible defaults but allows ample tweaking to get the output just right. Refining the above crime map, we alter the plot in the following ways:
axis.text
, axis.ticks
) and move the guide below the map (legend.position
).label.theme
, label_y.theme
)axis_title
, axis_title_y
, title
)fill2
, labels_y
)limits_y
).color_projection
, see ?color_projections
for more)label.position
, label_y.position
)View ?scale_color_colorplane
and ?guide_colorplane
for all available options.
if(require(mapproj)) {
crimes <- data.frame(state = tolower(rownames(USArrests)), USArrests)
states_map <- map_data("state")
ggplot(crimes,
aes(map_id = state, fill = Murder, fill2 = UrbanPop/100)) +
geom_map(map = states_map) +
scale_fill_colorplane(labels_y = scales::percent,
axis_title = "Murder arrests\nper 100,000 people",
axis_title_y = "Percent Urban\nPopulation",
limits_y = c(0,1)) +
expand_limits(x = states_map$long, y = states_map$lat) +
coord_map() +
theme(legend.position = "bottom",
panel.background = element_blank(),
axis.text = element_blank(),
axis.ticks = element_blank()) +
labs(x = "", y = "", title = paste("1973 U.S. Arrest Data:\nMurder Rate",
"v. Urban Population by State")) +
guides(fill = guide_colorplane(
title = "State Color Key",
title.theme = element_text(size = 13),
label.theme = theme_grey(),
label_y.theme = theme_grey(),
axis_title.position = "top",
label.position = c("top", "bottom"),
label_y.position = c("left", "right")))
}