Reputation: 1196
I want to produce a confusion matrix plot where the diagonal entries are green, the zero entries white, and the off-diagonal non-zero entries should be red.
This is the data:
gg <- structure(list(Prediction = structure(c(1L, 2L, 3L, 4L, 5L, 6L,
7L, 8L, 9L, 10L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 1L,
2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 1L, 2L, 3L, 4L, 5L, 6L,
7L, 8L, 9L, 10L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 1L,
2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 1L, 2L, 3L, 4L, 5L, 6L,
7L, 8L, 9L, 10L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 1L,
2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 1L, 2L, 3L, 4L, 5L, 6L,
7L, 8L, 9L, 10L), .Label = c("0", "1", "2", "3", "4", "5", "6",
"7", "8", "9"), class = "factor"), Reference = structure(c(1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L,
2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 4L, 4L, 4L,
4L, 4L, 4L, 4L, 4L, 4L, 4L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L,
5L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 7L, 7L, 7L, 7L, 7L,
7L, 7L, 7L, 7L, 7L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 9L,
9L, 9L, 9L, 9L, 9L, 9L, 9L, 9L, 9L, 10L, 10L, 10L, 10L, 10L,
10L, 10L, 10L, 10L, 10L), .Label = c("0", "1", "2", "3", "4",
"5", "6", "7", "8", "9"), class = "factor"), Freq = c(93L, 7L,
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 100L, 0L, 0L, 0L, 0L, 0L,
0L, 0L, 0L, 2L, 89L, 6L, 0L, 0L, 0L, 0L, 3L, 0L, 0L, 1L, 98L,
0L, 0L, 0L, 1L, 0L, 0L, 0L, 0L, 0L, 26L, 0L, 0L, 71L, 0L, 0L,
3L, 0L, 0L, 2L, 69L, 0L, 0L, 1L, 25L, 0L, 3L, 0L, 0L, 6L, 64L,
0L, 0L, 0L, 0L, 30L, 0L, 0L, 0L, 1L, 13L, 0L, 0L, 0L, 0L, 0L,
86L, 0L, 0L, 3L, 96L, 0L, 0L, 0L, 0L, 0L, 1L, 0L, 0L, 4L, 37L,
0L, 0L, 5L, 0L, 0L, 54L, 0L, 0L)), class = "data.frame", row.names = c(NA,
-100L))
In this example, the off-diagonal zeros are white. But how can I intentionally set the diagonal to green and non-zero off-diagonal red?
gg %>% dplyr::mutate(Freq2 = ifelse(Freq == 0,NA,Freq)) %>%
ggplot(aes(Prediction, Reference, fill = Freq2)) +
geom_tile() +
geom_text(aes(label=Freq)) +
scale_fill_gradientn(colours = c("#f8766d", "#00ba38"),na.value="white") +
labs(x = "Prediction",y = "Reference", fill = "Freq")
Upvotes: 2
Views: 674
Reputation: 388982
One option using scale_fill_identity
-
library(dplyr)
library(ggplot2)
gg %>%
mutate(color = case_when(Prediction == Reference ~ 'green',
Freq == 0 ~ 'white',
TRUE ~ ' red')) %>%
ggplot(aes(Prediction, Reference, fill = color)) +
geom_tile() +
geom_text(aes(label=Freq)) +
scale_fill_identity() +
labs(x = "Prediction",y = "Reference")
Upvotes: 3
Reputation: 1196
Figured it out. Had to use scale_fill_manual
gg2 <- gg %>% dplyr::mutate(Freq2 = ifelse(Freq == 0,NA,Freq))
gg2[gg2$Prediction == gg2$Reference,]$Freq2 = "diag"
gg2[gg2$Prediction != gg2$Reference & !is.na(gg2$Freq2),]$Freq2 = "notDiag"
gg2 %>%
ggplot(aes(Prediction, Reference, fill = Freq2)) +
geom_tile() +
geom_text(aes(label=Freq)) +
scale_fill_manual(values=c("#00ba38", "#f8766d"),na.value="white")+
labs(x = "Prediction",y = "Reference", fill = "Freq")
Upvotes: 1