This brief example shows the importance of careful colour selection. It uses the goby example from Chapter 10, which compared gonad mass for fish from five rivers, while adjusting for fish size (as total length).

Load standard package set for examples

Load colorBlindness package

library(colorBlindness)

Import data and produce standard ggplot scatterplot, plus basic adjustments from theme “qk”. Use river to identify groups and generate colours. For clarity, particularly with colorBlindness, we’ll hide the legend as well.

bleeker1 <- read_csv("../data/bleeker1.csv")
Rows: 69 Columns: 3── Column specification ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Delimiter: ","
chr (1): river
dbl (2): tl, gm
ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
cbt<-ggplot(data=bleeker1, aes(x=tl,y=gm, color=river))+
    geom_point() +
  geom_smooth(method="lm", se=FALSE)+
  labs(x = "Total length", y = "Gonad mass", 
       )+
  theme_qk()+ theme(legend.position="none")
cbt

Note that this plot just uses ggplot default colours.

Now see how this graph looks with various forms of colourblindness

cvd<-cvdPlot(cbt)
`geom_smooth()` using formula = 'y ~ x'
cvd

Now change plot to colour palette that is more compatible with a wide range of viewers. We’ll use the viridis package, and its default settings, though there are several other options in other packages, such as rcolorBrewer and ggsci.

cbt2<-cbt+scale_color_viridis(discrete=TRUE)
cbt2

This plot is OK on screen, but when projected, in, e.g. a lecture, the yellow tends to fade into the backgroun, so we’d use a different palette.

On the plus side, this palette still works with several forms of colorblindness:

cvd2<-cvdPlot(cbt2)
`geom_smooth()` using formula = 'y ~ x'
cvd2

Here’s another option, using the u_chicago palette from ggsci

cbt3<-cbt+scale_color_uchicago()
cbt3

This palette still works with several forms of colorblindness:

cvd3<-cvdPlot(cbt3)
`geom_smooth()` using formula = 'y ~ x'
cvd3

For teaching, export these plots.

ggsave("cbt.pdf", plot = cbt)
ggsave("cbt2.pdf", plot = cbt2)
ggsave("cvd.pdf", plot = cvd)
ggsave("cvd2.pdf", plot = cvd2)
ggsave("cbt3.pdf", plot = cbt3)
ggsave("cvd2.pdf", plot = cvd3)
LS0tCnRpdGxlOiAiUUsgMm5kIEVkIENoIDE3IgpvdXRwdXQ6IAogIGh0bWxfbm90ZWJvb2s6CiAgICB0aGVtZTogZmxhdGx5Ci0tLQoKVGhpcyBicmllZiBleGFtcGxlIHNob3dzIHRoZSBpbXBvcnRhbmNlIG9mIGNhcmVmdWwgY29sb3VyIHNlbGVjdGlvbi4gSXQgdXNlcyB0aGUgZ29ieSBleGFtcGxlIGZyb20gQ2hhcHRlciAxMCwgd2hpY2ggY29tcGFyZWQgZ29uYWQgbWFzcyBmb3IgZmlzaCBmcm9tIGZpdmUgcml2ZXJzLCB3aGlsZSBhZGp1c3RpbmcgZm9yIGZpc2ggc2l6ZSAoYXMgdG90YWwgbGVuZ3RoKS4KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9CmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSkKYGBgCkxvYWQgc3RhbmRhcmQgcGFja2FnZSBzZXQgZm9yIGV4YW1wbGVzCgpgYGB7ciBlY2hvPUZBTFNFLCBpbmNsdWRlPUZBTFNFLCByZXN1bHRzPSdoaWRlJ30Kc291cmNlKCIuLi9SL2xpYnJhcmllcy5SIikKc291cmNlKCIuLi9SL2FwcGVhcmFuY2UuUiIpCmBgYAoKTG9hZCBjb2xvckJsaW5kbmVzcyBwYWNrYWdlCmBgYHtyfQpsaWJyYXJ5KGNvbG9yQmxpbmRuZXNzKQpgYGAKSW1wb3J0IGRhdGEgYW5kIHByb2R1Y2Ugc3RhbmRhcmQgZ2dwbG90IHNjYXR0ZXJwbG90LCBwbHVzIGJhc2ljIGFkanVzdG1lbnRzIGZyb20gdGhlbWUgInFrIi4KVXNlIHJpdmVyIHRvIGlkZW50aWZ5IGdyb3VwcyBhbmQgZ2VuZXJhdGUgY29sb3Vycy4KRm9yIGNsYXJpdHksIHBhcnRpY3VsYXJseSB3aXRoIGNvbG9yQmxpbmRuZXNzLCB3ZSdsbCBoaWRlIHRoZSBsZWdlbmQgYXMgd2VsbC4KCmBgYHtyfQpibGVla2VyMSA8LSByZWFkX2NzdigiLi4vZGF0YS9ibGVla2VyMS5jc3YiKQpjYnQ8LWdncGxvdChkYXRhPWJsZWVrZXIxLCBhZXMoeD10bCx5PWdtLCBjb2xvcj1yaXZlcikpKwogICAgZ2VvbV9wb2ludCgpICsKICBnZW9tX3Ntb290aChtZXRob2Q9ImxtIiwgc2U9RkFMU0UpKwogIGxhYnMoeCA9ICJUb3RhbCBsZW5ndGgiLCB5ID0gIkdvbmFkIG1hc3MiLCAKICAgICAgICkrCiAgdGhlbWVfcWsoKSsgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikKY2J0CmBgYApOb3RlIHRoYXQgdGhpcyBwbG90IGp1c3QgdXNlcyBnZ3Bsb3QgZGVmYXVsdCBjb2xvdXJzLgoKTm93IHNlZSBob3cgdGhpcyBncmFwaCBsb29rcyB3aXRoIHZhcmlvdXMgZm9ybXMgb2YgY29sb3VyYmxpbmRuZXNzCmBgYHtyfQpjdmQ8LWN2ZFBsb3QoY2J0KQpjdmQKYGBgCk5vdyBjaGFuZ2UgcGxvdCB0byBjb2xvdXIgcGFsZXR0ZSB0aGF0IGlzIG1vcmUgY29tcGF0aWJsZSB3aXRoIGEgd2lkZSByYW5nZSBvZiB2aWV3ZXJzLgpXZSdsbCB1c2UgdGhlIHZpcmlkaXMgcGFja2FnZSwgYW5kIGl0cyBkZWZhdWx0IHNldHRpbmdzLCB0aG91Z2ggdGhlcmUgYXJlIHNldmVyYWwgb3RoZXIgb3B0aW9ucyBpbiBvdGhlciBwYWNrYWdlcywgc3VjaCBhcyAqcmNvbG9yQnJld2VyKiBhbmQgKmdnc2NpKi4KYGBge3J9CmNidDI8LWNidCtzY2FsZV9jb2xvcl92aXJpZGlzKGRpc2NyZXRlPVRSVUUpCmNidDIKYGBgClRoaXMgcGxvdCBpcyBPSyBvbiBzY3JlZW4sIGJ1dCB3aGVuIHByb2plY3RlZCwgaW4sIGUuZy4gYSBsZWN0dXJlLCB0aGUgeWVsbG93IHRlbmRzIHRvIGZhZGUgaW50byB0aGUgYmFja2dyb3VuLCBzbyB3ZSdkIHVzZSBhIGRpZmZlcmVudCBwYWxldHRlLgoKT24gdGhlIHBsdXMgc2lkZSwgdGhpcyBwYWxldHRlIHN0aWxsIHdvcmtzIHdpdGggc2V2ZXJhbCBmb3JtcyBvZiBjb2xvcmJsaW5kbmVzczoKYGBge3J9CmN2ZDI8LWN2ZFBsb3QoY2J0MikKY3ZkMgpgYGAKCkhlcmUncyBhbm90aGVyIG9wdGlvbiwgdXNpbmcgdGhlIHVfY2hpY2FnbyBwYWxldHRlIGZyb20gKmdnc2NpKgpgYGB7cn0KY2J0MzwtY2J0K3NjYWxlX2NvbG9yX3VjaGljYWdvKCkKY2J0MwpgYGAKVGhpcyBwYWxldHRlIHN0aWxsIHdvcmtzIHdpdGggc2V2ZXJhbCBmb3JtcyBvZiBjb2xvcmJsaW5kbmVzczoKYGBge3J9CmN2ZDM8LWN2ZFBsb3QoY2J0MykKY3ZkMwpgYGAKCkZvciB0ZWFjaGluZywgZXhwb3J0IHRoZXNlIHBsb3RzLiAKYGBge3IgZXZhbD1GQUxTRX0KZ2dzYXZlKCJjYnQucGRmIiwgcGxvdCA9IGNidCkKZ2dzYXZlKCJjYnQyLnBkZiIsIHBsb3QgPSBjYnQyKQpnZ3NhdmUoImN2ZC5wZGYiLCBwbG90ID0gY3ZkKQpnZ3NhdmUoImN2ZDIucGRmIiwgcGxvdCA9IGN2ZDIpCmdnc2F2ZSgiY2J0My5wZGYiLCBwbG90ID0gY2J0MykKZ2dzYXZlKCJjdmQyLnBkZiIsIHBsb3QgPSBjdmQzKQpgYGAK