Ответ 1
Во-первых, воссоздайте график из сообщения, обновив его для новой версии ggplot2
(0.9.2.1), которая имеет другую систему тем и прикрепляет меньшее количество пакетов:
nba <- read.csv("http://datasets.flowingdata.com/ppg2008.csv")
nba$Name <- with(nba, reorder(Name, PTS))
library("ggplot2")
library("plyr")
library("reshape2")
library("scales")
nba.m <- melt(nba)
nba.s <- ddply(nba.m, .(variable), transform,
rescale = scale(value))
ggplot(nba.s, aes(variable, Name)) +
geom_tile(aes(fill = rescale), colour = "white") +
scale_fill_gradient(low = "white", high = "steelblue") +
scale_x_discrete("", expand = c(0, 0)) +
scale_y_discrete("", expand = c(0, 0)) +
theme_grey(base_size = 9) +
theme(legend.position = "none",
axis.ticks = element_blank(),
axis.text.x = element_text(angle = 330, hjust = 0))
Использование разных цветов градиента для разных категорий не так просто. Концептуальный подход, чтобы отобразить fill
to interaction(rescale, Category)
(где Category
- атакующий/защитный/другой, см. Ниже) не работает, потому что взаимодействие фактора и непрерывной переменной дает дискретную переменную, которая fill
не может для отображения.
Чтобы обойти это, искусственно выполнить это взаимодействие, сопоставляя rescale
с неперекрывающимися диапазонами для разных значений Category
, а затем используйте scale_fill_gradientn
для сопоставления каждой из этих областей с разными цветовыми градиентами.
Сначала создайте категории. Я думаю, что эти карты относятся к комментариям, но я не уверен; изменение этой переменной в какой категории легко.
nba.s$Category <- nba.s$variable
levels(nba.s$Category) <-
list("Offensive" = c("PTS", "FGM", "FGA", "X3PM", "X3PA", "AST"),
"Defensive" = c("DRB", "ORB", "STL"),
"Other" = c("G", "MIN", "FGP", "FTM", "FTA", "FTP", "X3PP",
"TRB", "BLK", "TO", "PF"))
Так как rescale
находится в пределах нескольких (3 или 4) из 0, разные категории могут быть смещены на сто, чтобы их разделить. В то же время определите, где конечные точки каждого градиента цвета должны быть как с точки зрения масштабирования, так и с цветами.
nba.s$rescaleoffset <- nba.s$rescale + 100*(as.numeric(nba.s$Category)-1)
scalerange <- range(nba.s$rescale)
gradientends <- scalerange + rep(c(0,100,200), each=2)
colorends <- c("white", "red", "white", "green", "white", "blue")
Теперь замените переменную fill
на rescaleoffset
и измените масштаб fill
, чтобы использовать scale_fill_gradientn
(помня, чтобы перемасштабировать значения):
ggplot(nba.s, aes(variable, Name)) +
geom_tile(aes(fill = rescaleoffset), colour = "white") +
scale_fill_gradientn(colours = colorends, values = rescale(gradientends)) +
scale_x_discrete("", expand = c(0, 0)) +
scale_y_discrete("", expand = c(0, 0)) +
theme_grey(base_size = 9) +
theme(legend.position = "none",
axis.ticks = element_blank(),
axis.text.x = element_text(angle = 330, hjust = 0))
Переупорядочение для получения связанных статистических данных является еще одним применением функции reorder
для различных переменных:
nba.s$variable2 <- reorder(nba.s$variable, as.numeric(nba.s$Category))
ggplot(nba.s, aes(variable2, Name)) +
geom_tile(aes(fill = rescaleoffset), colour = "white") +
scale_fill_gradientn(colours = colorends, values = rescale(gradientends)) +
scale_x_discrete("", expand = c(0, 0)) +
scale_y_discrete("", expand = c(0, 0)) +
theme_grey(base_size = 9) +
theme(legend.position = "none",
axis.ticks = element_blank(),
axis.text.x = element_text(angle = 330, hjust = 0))