2014-07-17 6 views
8

che sto cercando di utilizzare ggvis per creare un grafico NFL forza-di-programma per la stagione 2014. I dati provengono da FootballOutsiders.com, e in seguito creerò un'app Shiny che scarica automaticamente i dati dal sito web mentre viene aggiornata durante la stagione. L'esempio qui sotto è piuttosto vicino, ma mi piacerebbe apportare alcune modifiche. Voglio ...riempimento personalizzato colore ggvis (e altre opzioni)

  1. includono il valore numerico di "difesa" in ciascuna cella della tabella, quindi la visualizzazione assomiglia alla "df" frame di dati originale.

  2. personalizzare la scala cromatica così valori positivi sono sempre arancione e valori negativi sono sempre più blu (cioè più negativo = più blu).

  3. Un'alternativa alla # 2 potrebbe essere quella di ottenere un gradiente dall'arancione al blu e ridurre l'opacità a 0,5 quando il valore di "difesa" si avvicina a zero.

  4. Essere in grado di scegliere il colore della NA, perché mostra attualmente come nero nel grafico.

Ho armeggiare intorno con add_scale() e props(), ma niente ha lavorato finora.

Ecco il grafico: enter image description here

Ecco i dati:

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") 

Ed ecco il codice finora:

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) 

risposta

14

ho impostare i colori per ogni cella con la creazione di un nuovo variabile def.color che mappa ogni valore di defense ad un colore specifico. In ggplot2 è possibile impostare i colori direttamente all'interno della chiamata su ggplot utilizzando una riga di codice, ad esempio scale_fill_manual(), anziché aggiungere una variabile di colore al frame di dati. Spero che ci sia un modo per farlo in ggvis, ma non l'ho ancora trovato. Quindi, per ora, qui andiamo:

# 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)] = "" 

Ora creiamo la trama. Per ottenere la mappa def.color colori, per fill utilizzando := per ignorare i colori predefiniti. Per aggiungere i valori di defense uso layer_text. Non sono contento del posizionamento del testo all'interno di ogni cella, ma questo è il migliore che sia stato in grado di elaborare per ora.

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") 

enter image description here

+0

Sembra un po 'contro-intuitivo che bisogna mappare manualmente la variabile su un colore. Non c'è modo che le funzioni di scala di ggvis lo facciano ancora? –

+0

Non ho provato a usare 'ggvis' per un po 'ed è stato in rapido sviluppo.Sono d'accordo sul fatto che sarebbe molto più preferibile che le funzioni di scala si occupino di questo. Spero che ci sia, o presto sarà, un modo per farlo. Mi piacerebbe anche trovare un modo per avere più controllo su dove i numeri sono posizionati all'interno delle celle. – eipi10

+0

Ho guardato solo ggvis per alcuni giorni. Da quello che ho letto, farlo facilmente è una funzionalità futura. Per ora puoi definire una scala di riempimento o di un tratto con un colore arbitrario ad ogni estremità, ma non puoi ancora avere l'equivalente di {scale} 'scale_fill_gradientn - che è essenziale per situazioni come blu-bianco-rosso o i colori solo molto l'uno nell'altro con blu-rosso. –

2

Una soluzione che ho trovato per visualizzare una legenda, facendo uso della funzione scale_ordinal. Ho usato molto del codice scritto da @ eipi10, grazie!

# Functions to create color ramps for the blue and orange color ranges, 
# combined in a single palette with 10 colors of each ramp and gray for NAs 
Blue <- colorRampPalette(c("darkblue","lightblue")) 
Orange <- colorRampPalette(c("orange","darkorange3")) 
palette <- c(Blue(10), "#E5E5E5", Orange(10)) 

# Negative values of defense get a blue color scale with 10 colors, indexes 
# from 1 to 10 
df2$def.label[!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 = palette[1:10])) 

# Positive values of defense get an orange color scale with 10 colors, 
# indexes from 12 to 21 
df2$def.label[!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 = palette[12:21])) 

# Set NA values in df2$defense to 11 in def.label, the label for gray color 
df2$def.label[is.na(df2$defense)] <- palette[[11]] 

# Define the values to be displayed on the legend 
pos.cut.values <- seq(0, max(df2$defense, na.rm = TRUE) + 0.1, length.out = 11) 
neg.cut.values <- seq(min(df2$defense - 0.1, na.rm = TRUE), 0, length.out = 11) 
legend.values <- c(paste(neg.cut.values[1:10], '..', neg.cut.values[2:11]), 
        'NA', paste(pos.cut.values[1:10], '..', pos.cut.values[2:11])) 

# 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)] <- "" 

df2 %>% 
    ggvis(~week, ~team, fill:=~def.label) %>% 
    scale_ordinal('fill', range = palette) %>% 
    add_legend(scales = 'fill', values = legend.values) %>% 
    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") 

Added legend to ggvis matrix