7

I'm trying to map dates to the viridis colour scale in ggplot2. The default ggplot colour scale works fine for dates. But I'm having trouble mapping them to the viridis scale, getting an error regarding 'origin' not being supplied to as.Date.numeric() (similar error when trying to use ggplot2::scale_color_gradient()). See reprex below.

Any advice on the most efficient way to sort this?


### data
df <- structure(list(height = c(182.87, 179.12, 169.15, 175.66, 164.47, 
158.27, 161.69, 165.84, 181.32, 167.37, 160.06, 166.48, 175.39, 
164.7, 163.79, 181.13, 169.24, 176.22, 174.09, 180.11, 179.24, 
161.92, 169.85, 160.57, 168.24, 177.75, 183.21, 167.75, 181.15, 
181.56, 160.03, 165.62, 181.64, 159.67, 177.03, 163.35, 175.21, 
160.8, 166.46, 157.95, 180.61, 159.52, 163.01, 165.8, 170.03, 
157.16, 164.58, 163.47, 185.43, 165.34, 163.45, 163.97, 161.38, 
160.09, 178.64, 159.78, 161.57, 161.83, 169.66, 166.84, 159.32, 
170.51, 161.84, 171.41, 166.75, 166.19, 169.16, 157.01, 167.51, 
160.47, 162.33, 175.67, 174.25, 158.94, 172.72, 159.23, 176.54, 
184.34, 163.94, 160.09, 162.32, 162.59, 171.94, 158.07, 158.35, 
162.18, 159.38, 171.45, 163.17, 183.1, 177.14, 171.08, 159.33, 
185.43, 162.65, 159.44, 164.11, 159.13, 160.58, 164.88), weight = c(76.57, 
80.43, 75.48, 94.54, 71.78, 69.9, 68.85, 70.44, 76.9, 79.06, 
72.37, 67.34, 92.22, 75.69, 65.76, 72.33, 73.3, 97.67, 72.2, 
75.72, 75.54, 69.92, 90.63, 63.54, 69.57, 74.84, 83.36, 82.06, 
83.93, 79.54, 64.3, 76.72, 96.91, 71.88, 74.04, 70.46, 83.65, 
64.77, 76.83, 67.41, 83.59, 67.99, 65.19, 71.77, 66.68, 69.64, 
72.99, 72.89, 87.23, 70.84, 67.67, 66.71, 73.55, 65.93, 97.05, 
68.31, 67.92, 66.03, 77.3, 88.25, 64.92, 84.35, 69.97, 81.7, 
79.06, 67.46, 90.08, 66.56, 84.15, 68.2, 66.47, 88.82, 80.93, 
65.14, 67.62, 69.96, 90.76, 90.41, 71.47, 68.94, 72.72, 69.76, 
82.11, 69.8, 69.72, 67.81, 70.37, 84.29, 64.47, 82.47, 88.7, 
72.51, 70.68, 73.63, 73.99, 66.21, 70.66, 66.96, 71.49, 68.07
), birth = structure(c(766, 896, 920, 959, 1258, 1277, 815, 1226, 
729, 1295, 854, 682, 811, 690, 741, 1056, 690, 1199, 1133, 1233, 
806, 1097, 838, 1278, 773, 1059, 1373, 1038, 1387, 859, 1343, 
926, 1074, 1366, 784, 1207, 1222, 1150, 965, 862, 819, 1072, 
1238, 1320, 976, 1296, 760, 833, 1295, 767, 1030, 727, 774, 1126, 
1113, 849, 1285, 928, 1247, 799, 1130, 1049, 829, 1318, 790, 
1067, 1013, 831, 936, 841, 781, 1378, 801, 1247, 770, 1372, 1129, 
892, 1172, 720, 982, 884, 1380, 871, 889, 820, 1374, 791, 1271, 
1033, 698, 1185, 1273, 1257, 952, 1048, 904, 906, 1051, 684), class = "Date")), class = "data.frame", .Names = c("height", 
"weight", "birth"), row.names = c(NA, -100L))

### libraries
library(ggplot2)
library(viridis)
#> Loading required package: viridisLite

### plot default colour scale
ggplot(data=df, aes(x = height, y = weight, colour = birth)) + 
    geom_point(size=4)

### plot with viridis colour scale
ggplot(data=df, aes(x = height, y = weight, colour = birth)) + 
    geom_point(size=4) + 
    scale_colour_viridis()
#> Error in as.Date.numeric(value): 'origin' must be supplied
Martin Schmelzer
  • 23,283
  • 6
  • 73
  • 98
Anna Krystalli
  • 413
  • 3
  • 13

2 Answers2

11

An alternative that doesn't require any extra variables is to set trans = "date".

ggplot(df, aes(x = height, y = weight, colour = birth)) + 
    geom_point(size = 4) +
    scale_colour_viridis_c(trans = "date")

(Using {ggplot2} v3.3.2)

Scatter plot of weight vs height coloured by birth date

lazappi
  • 186
  • 1
  • 5
9

Here is a workaround:

Convert the dates to numeric values before assigning them to the colour aesthetic. In the call to scale_colour_viridis() you then use corresponding breaks and labels:

# create equidistant sequence of dates to use as labels
lab_dates <- pretty(df$birth)

ggplot(data=df, aes(x = height, y = weight, colour = as.numeric(birth))) + 
  geom_point(size=4) + scale_colour_viridis(breaks = as.numeric(lab_dates), 
                                            labels = lab_dates)

enter image description here

Martin Schmelzer
  • 23,283
  • 6
  • 73
  • 98