问题描述
对 Learning R 博客文章发表评论的人)是:是否可以为不同类别的统计数据(进攻性、防守性、其他)使用不同的渐变颜色?
首先,从帖子中重新创建图表,为较新 (0.9.2.1) 版本的 ggplot2
更新它,该版本具有不同的主题系统并附加更少的包:
nba <- read.csv("http://datasets.flowingdata.com/ppg2008.csv")nba$Name
为不同的类别使用不同的渐变颜色并不是那么简单.将 fill
映射到 interaction(rescale, Category)
的概念方法(其中 Category
是进攻性/防御性/其他;见下文)不起作用,因为因子和连续变量的相互作用会产生一个离散变量,fill
无法映射到该变量.
解决这个问题的方法是人为地进行这种交互,将 rescale
映射到 Category
的不同值的非重叠范围,然后使用 scale_fill_gradientn
将每个区域映射到不同的颜色渐变.
首先创建类别.我认为这些映射到评论中的那些,但我不确定;更改哪个变量属于哪个类别很容易.
nba.s$Category
由于 rescale
在 0 的几个(3 或 4)范围内,不同的类别可以偏移一百以保持它们分开.同时,根据重新缩放的值和颜色,确定每个颜色渐变的端点应该在哪里.
nba.s$rescaleoffset
现在将 fill
变量替换为 rescaleoffset
并更改 fill
比例以使用 scale_fill_gradientn
(记住重新缩放值):
ggplot(nba.s, aes(variable, Name)) +geom_tile(aes(fill = rescaleoffset), color = "white") +scale_fill_gradientn(colours = colorends, values = rescale(gradientends)) +scale_x_discrete("", expand = c(0, 0)) +scale_y_discrete("", expand = c(0, 0)) +主题灰色(base_size = 9)+主题(legend.position =无",axis.ticks = element_blank(),轴.文本.x = element_text(角度= 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), color = "white") +scale_fill_gradientn(colours = colorends, values = rescale(gradientends)) +scale_x_discrete("", expand = c(0, 0)) +scale_y_discrete("", expand = c(0, 0)) +主题灰色(base_size = 9)+主题(legend.position =无",axis.ticks = element_blank(),轴.文本.x = element_text(角度= 330,hjust = 0))
This Learning R blog post shows how to make a heatmap of basketball stats using ggplot2. The finished heatmap looks like this:
My question (inspired by Jake who commented on the Learning R blog post) is: would it be possible to use different gradient colors for different categories of stats (offensive, defensive, other)?
First, recreate the graph from the post, updating it for the newer (0.9.2.1) version of ggplot2
which has a different theme system and attaches fewer packages:
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))
Using different gradient colors for different categories is not all that straightforward. The conceptual approach, to map the fill
to interaction(rescale, Category)
(where Category
is Offensive/Defensive/Other; see below) doesn't work because interacting a factor and continuous variable gives a discrete variable which fill
can not be mapped to.
The way to get around this is to artificially do this interaction, mapping rescale
to non-overlapping ranges for different values of Category
and then use scale_fill_gradientn
to map each of these regions to different color gradients.
First create the categories. I think these map to those in the comment, but I'm not sure; changing which variable is in which category is easy.
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"))
Since rescale
is within a few (3 or 4) of 0, the different categories can be offset by a hundred to keep them separate. At the same time, determine where the endpoints of each color gradient should be, in terms of both rescaled values and colors.
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")
Now replace the fill
variable with rescaleoffset
and change the fill
scale to use scale_fill_gradientn
(remembering to rescale the values):
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))
Reordering to get related stats together is another application of the reorder
function on the various variables:
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))
这篇关于ggplot2 热图:对类别使用不同的梯度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!