GitHub Workflow Coverage status CRAN_status_badge cran checks Downloads DOI

biscale implements a set of functions for bivariate thematic mapping based on the tutorial written by Timo Grossenbacher and Angelo Zehr as well as a set of bivariate mapping palettes, including Joshua Stevens’ classic color schemes.

In addition to support for two-by-two, three-by-three, and four-by-four maps, the package also supports a range of methods for calculating breaks for bivariate maps.

What’s New in v1.0.0?

New Features

Breaking Changes

Deprecated Functions

Internal Improvements

Documentation Improvements


Installing biscale

The easiest way to get biscale is to install it from CRAN:


Alternatively, the development version of biscale can be accessed from GitHub with remotes:

# install.packages("remotes")

Installing Suggested Dependencies

Since the package does not directly use functions from sf, it is a suggested dependency rather than a required one. However, the most direct approach to using biscale is with sf objects, and we therefore recommend users install sf. Windows and macOS users should be able to install sf without significant issues unless they are building from source. Linux users will need to install several open source spatial libraries to get sf itself up and running.

The other suggested dependency that users may want to consider installing is cowplot. All of the examples in the package documentation utilize it to construct final map images that combine the map with the legend. Like sf, it is suggested because none of the functions in biscale call cowplot directly.

If you want to use them, you can either install these packages individually (faster) or install all of the suggested dependencies at once (slower, will also give you a number of other packages you may or may not want):

## install just cowplot and sf
install.packages(c("cowplot", "sf"))

## install all suggested dependencies
install.packages("biscale", dependencies = TRUE)


Quick Overview

Creating bivariate plots in the style described by Grossenbacher and Zehr requires a number of dependencies in addition to biscale - ggplot2 for plotting and sf for working with spatial objects in R. We’ll also use cowplot in these examples:

# load dependencies

The biscale package comes with some sample data from St. Louis, MO that you can use to check out the bivariate mapping workflow. Our first step is to create our classes for bivariate mapping. biscale currently supports a both two-by-two and three-by-three tables of classes, created with the bi_class() function:

# create classes
data <- bi_class(stl_race_income, x = pctWhite, y = medInc, style = "quantile", dim = 3)

The default method for calculating breaks is "quantile", which will provide breaks at 33.33% and 66.66% percent (i.e. tercile breaks) for three-by-three palettes. Other options are "equal", "fisher", and "jenks". These are specified with the optional style argument. The dim argument is used to adjust whether a two-by-two and three-by-three tables of classes is returned.

Once breaks are created, we can use bi_scale_fill() as part of our ggplot() call:

# create map
map <- ggplot() +
  geom_sf(data = data, mapping = aes(fill = bi_class), color = "white", size = 0.1, show.legend = FALSE) +
  bi_scale_fill(pal = "GrPink", dim = 3) +
    title = "Race and Income in St. Louis, MO",
    subtitle = "Dark Blue (DkBlue) Palette"
  ) +

There are a variety of other options for palettes. See the “Bivarite Palettes” vignette or ?bi_pal for more details. The bi_theme() function applies a simple theme without distracting elements, which is preferable given the already elevated complexity of a bivariate map. We need to specify the dimensions of the palette for bi_scale_fill() as well.

To add a legend to our map, we need to create a second ggplot object. We can use bi_legend() to accomplish this, which allows us to easily specify the fill palette, the x and y axis labels, and their size along with the dimensions of the palette:

legend <- bi_legend(pal = "GrPink",
                    dim = 3,
                    xlab = "Higher % White ",
                    ylab = "Higher Income ",
                    size = 8)

Note that plotmath is used to draw the arrows since Unicode arrows are font dependent. This happens internally as part of bi_legend() - you don’t need to include them in your xlab and ylab arguments!

With our legend drawn, we can then combine the legend and the map with cowplot. The values needed for this stage will be subject to experimentation depending on the shape of the map itself.

# combine map with legend
finalPlot <- ggdraw() +
  draw_plot(map, 0, 0, 1, 1) +
  draw_plot(legend, 0.2, .65, 0.2, 0.2)

The completed map, created with the sample code in this README, looks like this:

Contributor Code of Conduct

Please note that this project is released with a Contributor Code of Conduct. By participating in this project you agree to abide by its terms.