custom fill color in ggvis (and other options)
ggvis, r
Solution
I set the colors for each cell by creating a new variable `def.color` that maps each value of `defense` to a specific color. In `ggplot2` you can set the colors directly within the call to `ggplot` using one line of code, such as `scale_fill_manual()`, rather than adding a color variable to the data frame. I'm hoping there's a way to do that in `ggvis`, but I haven't found it yet. So, for now, here we go:
# Create a new variable df2$def.color for mapping df2$defense values to colors
# Functions to create color ramps for the blue and orange color ranges
Blue = colorRampPalette(c("darkblue","lightblue"))
Orange = colorRampPalette(c("orange","darkorange3"))
# Negative values of defense get a blue color scale with 10 colors
df2$def.color[!is.na(df2$defense) & df2$defense<0] =
as.character(cut(df2$defense[!is.na(df2$defense) & df2$defense<0],
seq(min(df2$defense - 0.1, na.rm=TRUE), 0, length.out=11),
labels=Blue(10)))
# Positive values of defense get an orange color scale with 10 colors
df2$def.color[!is.na(df2$defense) & df2$defense>=0] =
as.character(cut(df2$defense[!is.na(df2$defense) & df2$defense>=0],
seq(0, max(df2$defense, na.rm=TRUE)+0.1, length.out=11),
labels=Orange(10)))
# Set NA values in df2$def.color to light gray in df2$def.color
df2$def.color[is.na(df2$defense)] = "#E5E5E5"
# Set NA values in df2$defense to blanks so that we won't get "NaN" in cells with
# missing data
df2$defense[is.na(df2$defense)] = ""
Now we create the plot. To get the colors, map `def.color` to `fill` using `:=` to override the default colors. To add the values of `defense` use `layer_text`. I'm not happy with the text placement within each cell, but this is the best I've been able to come up with for now.
df2 %>%
ggvis(~week, ~team, fill:=~def.color) %>%
layer_rects(width = band(), height = band()) %>%
scale_nominal("x", padding = 0, points = FALSE) %>%
scale_nominal("y", padding = 0, points = FALSE) %>%
layer_text(text:=~defense, stroke:="white", align:="left", baseline:="top")
Problem
I'm trying to use ggvis to create a NFL strength-of-schedule chart for the 2014 season. The data comes from FootballOutsiders.com, and later I'll make a Shiny app that automatically scrapes data from the website as it's updated during the season. The example below is pretty close, but I'd like to make a few modifications. I want to... Include the numeric value of "defense" in each cell of the chart, so the visualization resembles the original "df" data frame. Customize the color scale so positive values are increasingly orange and negative values are increasingly blue (i.e. more negative = more blue). An alternative to #2 could be to make a gradient from orange to blue, and make the opacity decrease to 0.5 as the value of "defense" approaches zero. Be able to choose the color of NA, because it currently shows up as black in the chart. I've been tinkering around with `add_scale()` and `props()`, but nothing has been working so far. Here's the chart: Here's the data: ``` df <- structure(list(team = c("ARI", "ATL", "BAL", "BUF", "CAR", "CHI", "CIN", "CLE", "DAL", "DEN", "DET", "GB", "HOU", "IND", "JAX", "KC", "MIA", "MIN", "NE", "NO", "NYG", "NYJ", "OAK", "PHI", "PIT", "SD", "SEA", "SF", "STL", "TB", "TEN", "WAS"), w1 = c(17.5, -5.8, -12.6, 8.7, -6.8, -13.8, -8.7, 4, -4.6, 0.9, -11.4, -25.9, 4.2, -0.2, 4.9, 4.2, 4.2, -5.7, 2.4, 13.5, -0.8, 10.3, -5.6, 10.9, 8.2, -16.4, 14.4, 13.8, 10.5, -15.7, -6.7, 2.5), w2 = c(-11.4, -12.6, 4, 2.4, -0.8, -4.6, 13.5, -5.8, 4.2, -6.7, -15.7, -5.6, 10.3, 4.9, 4.2, -0.2, -13.8, 4.2, 10.5, 8.2, -16.4, 14.4, 2.5, 0.9, -8.7, -25.9, 17.5, 8.7, -6.8, -5.7, 13.8, 10.9), w3 = c(-4.6, -6.8, 8.2, 17.5, 4, -5.6, 4.2, -8.7, -5.7, -25.9, 14.4, -0.8, -11.4, 10.9, 0.9, 2.4, -6.7, -5.8, 10.3, 10.5, 2.5, 8.7, 4.2, 4.2, -15.7, -13.8, -0.2, -16.4, 13.8, 13.5, -12.6, 4.9), w4 = c(NA, 10.5, -15.7, 2.5, -8.7, 14.4, NA, NA, -5.8, NA, -5.6, 8.7, -13.8, 4.2, 17.5, 4.2, 10.3, 13.5, -6.7, 13.8, 4.2, -0.8, 2.4, -4.6, -6.8, 10.9, NA, 4.9, NA, 4, 0.9, -11.4), w5 = c(-0.2, -11.4, 0.9, -0.8, 8.7, -15.7, 4.2, 4.2, 2.5, -16.4, -13.8, 10.5, 13.8, -8.7, 4, -4.6, NA, 14.4, -12.6, -6.8, 13.5, 17.5, NA, -5.7, 10.9, -5.6, 4.2, -6.7, 4.9, -5.8, 8.2, -25.9), w6 = c(4.2, 8.7, -6.8, 4.2, -12.6, 13.5, -15.7, 4, -25.9, -5.6, 10.5, 2.4, 0.9, 2.5, 4.2, NA, 14.4, -0.8, -13.8, NA, 4.9, -0.2, 17.5, -11.4, 8.2, 10.3, 13.8, -5.7, -4.6, -8.7, 10.9, -16.4), w7 = c(10.3, -8.7, 13.5, 10.5, 14.4, 2.4, 0.9, 10.9, -11.4, -4.6, -5.8, -15.7, 4, -12.6, 8.2, 17.5, 8.7, -13.8, -5.6, -0.8, 13.8, 4.2, -16.4, NA, 2.5, -6.7, -5.7, -0.2, -25.9, NA, 4.2, 4.2), w8 = c(4.9, -0.8, -12.6, -5.6, -25.9, 4.2, -8.7, 10.3, 4.2, 17.5, 13.5, -5.8, 4.2, 4, 2.4, -5.7, 10.9, -6.8, 8.7, 14.4, NA, -13.8, 8.2, -16.4, 0.9, -0.2, -15.7, NA, -6.7, 10.5, 2.5, 13.8), w9 = c(13.8, NA, 4, NA, -5.8, NA, 10.9, -6.8, -16.4, 4.2, NA, NA, 4.9, -11.4, -12.6, -5.6, 17.5, 4.2, -0.2, -15.7, 0.9, -6.7, -25.9, 2.5, -8.7, 2.4, 10.3, -5.7, -4.6, 8.2, NA, 10.5), w10 = c(-5.7, -6.8, 4.2, -6.7, 4.9, 14.4, 8.2, -12.6, 10.9, 10.3, 2.4, 8.7, NA, NA, 13.8, -13.8, -0.8, NA, NA, -4.6, -25.9, 4, -0.2, -15.7, -5.6, NA, -11.4, -5.8, -16.4, 13.5, -8.7, NA), w11 = c(-0.8, -15.7, NA, 2.4, 13.5, 10.5, -5.8, 2.5, NA, -5.7, -16.4, 4.9, 8.2, 4.2, NA, -25.9, -13.8, 8.7, 0.9, -12.6, -4.6, NA, 17.5, 14.4, 4.2, 10.3, -6.7, -11.4, -0.2, 4.2, 4, -6.8), w12 = c(-25.9, 8.2, -5.8, -5.6, NA, -6.8, 2.5, 13.5, -11.4, 2.4, 4.2, 10.5, -12.6, 10.9, 0.9, 10.3, -0.2, 14.4, -0.8, -8.7, 13.8, -13.8, -6.7, 4.2, NA, -5.7, -16.4, 4.2, 17.5, 8.7, 4.9, -4.6), w13 = c(13.5, -16.4, 17.5, 8.2, 10.5, -0.8, -6.8, -13.8, 4.9, -6.7, 8.7, 4.2, 4.2, 4.2, -11.4, -0.2, -5.6, -15.7, 14.4, 4, 10.9, 2.4, -5.7, 13.8, -5.8, -8.7, -4.6, -25.9, 10.3, -12.6, 2.5, 0.9), w14 = c(-6.7, 14.4, 2.4, -0.2, -5.8, 13.8, 4, 0.9, 8.7, -13.8, -6.8, 13.5, 10.9, 8.2, 2.5, -16.4, -8.7, -5.6, 17.5, -15.7, 4.2, 10.5, -4.6, -25.9, -12.6, 4.2, 4.9, 10.3, 4.2, -0.8, -11.4, -5.7), w15 = c(-5.7, 4, 10.9, 14.4, -6.8, -5.8, 8.2, -12.6, 4.9, 17.5, 10.5, -13.8, 0.9, 2.5, -8.7, 10.3, 4.2, -0.8, 2.4, 8.7, 4.2, 4.2, -6.7, 13.8, 13.5, -0.2, -4.6, -25.9, -16.4, -15.7, -5.6, -11.4), w16 = c(-25.9, -5.8, 2.5, 10.3, 8.2, -0.8, -0.2, -15.7, 0.9, -12.6, 8.7, -6.8, -8.7, 13.8, 4.2, 4, 10.5, 2.4, -5.6, 13.5, -5.7, 4.2, -13.8, 4.2, -6.7, -4.6, -16.4, 17.5, -11.4, 14.4, 10.9, 4.9), w17 = c(-4.6, -15.7, 8.2, 4.2, 13.5, 10.5, 4, -8.7, 4.2, 10.3, 14.4, -0.8, 10.9, 4.2, 2.5, 17.5, -5.6, 8.7, -13.8, -6.8, 4.9, 2.4, -0.2, -11.4, -12.6, -6.7, -5.7, -16.4, -25.9, -5.8, 0.9, 13.8)), .Names = c("team", "w1", "w2", "w3", "w4", "w5", "w6", "w7", "w8", "w9", "w10", "w11", "w12", "w13", "w14", "w15", "w16", "w17"), row.names = c(NA, 32L), class = "data.frame") ``` And here's the code so far: ``` require(dplyr) require(ggvis) require(tidyr) # For the gather function df2 <- df %>% gather(key, value, w1:w17) names(df2) <- c("team", "week", "defense") df2 %>% ggvis(~week, ~team, fill = ~defense) %>% layer_rects(width = band(), height = band()) %>% scale_nominal("x", padding = 0, points = FALSE) %>% scale_nominal("y", padding = 0, points = FALSE) ```