ggplot2 热图:对类别使用不同的梯度 [英] ggplot2 heatmaps: using different gradients for categories

查看:42
本文介绍了ggplot2 热图:对类别使用不同的梯度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对 Learning R 博客文章发表评论的人)是:是否可以为不同类别的统计数据(进攻性、防守性、其他)使用不同的渐变颜色?

解决方案

首先,从帖子中重新创建图表,为较新 (0.9.2.1) 版本的 ggplot2 更新它,该版本具有不同的主题系统并附加更少的包:

nba <- read.csv("http://datasets.flowingdata.com/ppg2008.csv")nba$Name <- with(nba, reorder(Name, PTS))图书馆(ggplot2")图书馆(plyr")图书馆(重塑2")图书馆(秤")nba.m <- 融化(nba)nba.s <- ddply(nba.m, .(variable), 变换,重新缩放 = 缩放(值))ggplot(nba.s, aes(variable, Name)) +geom_tile(aes(fill = rescale), color = "white") +scale_fill_gradient(low = "white", high = "steelblue") +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))

为不同的类别使用不同的渐变颜色并不是那么简单.将 fill 映射到 interaction(rescale, Category) 的概念方法(其中 Category 是进攻性/防御性/其他;见下文)不起作用,因为因子和连续变量的相互作用会产生一个离散变量,fill 无法映射到该变量.

解决这个问题的方法是人为地进行这种交互,将 rescale 映射到 Category 的不同值的非重叠范围,然后使用 scale_fill_gradientn 将每个区域映射到不同的颜色渐变.

首先创建类别.我认为这些映射到评论中的那些,但我不确定;更改哪个变量属于哪个类别很容易.

nba.s$Category <- nba.s$variable级别(nba.s$Category)<-list("进攻" = c("PTS", "FGM", "FGA", "X3PM", "X3PA", "AST"),"防御" = c("DRB", "ORB", "STL"),"其他" = c("G", "MIN", "FGP", "FTM", "FTA", "FTP", "X3PP","TRB", "BLK", "TO", "PF"))

由于 rescale 在 0 的几个(3 或 4)范围内,不同的类别可以偏移一百以保持它们分开.同时,根据重新缩放的值和颜色,确定每个颜色渐变的端点应该在哪里.

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), 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 热图:对类别使用不同的梯度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆