ggplot2 Heatmap 2不同的配色方案-混淆矩阵:与未分类的匹配的配色方案不同 [英] ggplot2 Heatmap 2 Different Color Schemes - Confusion Matrix: Matches in Different Color Scheme than Missclassifications

查看:65
本文介绍了ggplot2 Heatmap 2不同的配色方案-混淆矩阵:与未分类的匹配的配色方案不同的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我从

但是我无法在 cm_d $ ndiag 的元素上获得第二种配色方案我发现软件包

 #改编自https://stackoverflow.com/a/60150826/7318488library(ggplot2)#绘制library(gridExtra)#多放些库(网格)#一起绘制library(likert)#用于反转因子顺序图书馆(ggnewscale)plot.cm<-函数(cm){#将混淆矩阵值提取为data.framecm_d<-as.data.frame(cm $ table)cm_d $ diag<-cm_d $ Prediction == cm_d $参考#获取对角线cm_d $ ndiag<-cm_d $预测!= cm_d $参考#不是对角线cm_d [cm_d == 0]<-NA#将NA中的0替换为NAcm_d $ Reference<-reverse.levels(cm_d $ Reference)#对角线从左上角开始#绘制矩阵cm_d_p<-ggplot(数据= cm_d,aes(x =预测,y =参考,填充=频率))+scale_x_discrete(position ="top")+geom_tile(data = cm_d [!is.na(cm_d $ diag),],aes(color = Freq))+scale_fill_gradient(guide = FALSE,low = alpha("lightyellow",0.75),high ="yellow",na.value ='white')+#这不起作用#new_scale("fill")+#geom_tile(data = cm_d [!is.na(cm_d $ ndiag),],aes(color = Freq))+#scale_fill_gradient(guide = FALSE,low = alpha("red",0.75),high ="darkred",na.value ='white')+geom_text(aes(label = Freq),color ='black',size = 6)+theme_light()+主题(panel.grid.major = element_blank(),panel.grid.minor = element_blank(),legend.position =无",panel.border = element_blank(),plot.background = element_blank(),axis.line = element_blank())返回(cm_d_p)} 

样本数据:
插入符号混淆矩阵

 库(插入符号)#模拟数据set.seed(23)pred<-factor(sample(1:7,100,replace = T))ref<-factor(sample(1:7,100,replace = T))cm<-插入符:: confusionMatrix(pred,ref)g<-图.cm(cm)G 

解决方案

我认为问题很简单,就是您指定的是 aes(color = Freq)而不是 aes(fill =Freq .绘图的目的是什么?您还可以通过使用发散的色标并创建一个新变量来简化所有这些操作,如果变量不在对角线上,则将Freq标记为负值,请参见下面的第二个示例

 <代码>#改编自https://stackoverflow.com/a/60150826/7318488library(ggplot2)#绘制library(gridExtra)#多放些库(网格)#一起绘制library(likert)#用于反转因子顺序#>加载所需的软件包:xtable图书馆(ggnewscale)plot.cm<-函数(cm){#将混淆矩阵值提取为data.framecm_d<-as.data.frame(cm $ table)cm_d $ diag<-cm_d $ Prediction == cm_d $参考#获取对角线cm_d $ ndiag<-cm_d $预测!= cm_d $参考#不是对角线cm_d [cm_d == 0]<-NA#将NA中的0替换为NAcm_d $ Reference<-reverse.levels(cm_d $ Reference)#对角线从左上角开始#绘制矩阵cm_d_p<-ggplot(数据= cm_d,aes(x =预测,y =参考,填充=频率))+scale_x_discrete(position ="top")+geom_tile(data = cm_d [!is.na(cm_d $ diag),],aes(fill = Freq))+scale_fill_gradient(guide = FALSE,low = alpha("lightyellow",0.75),high ="yellow",na.value ='white')+#这不起作用new_scale("fill")+geom_tile(data = cm_d [!is.na(cm_d $ ndiag),],aes(fill = Freq))+scale_fill_gradient(guide = FALSE,low = alpha("red",0.75),high ="red",na.value ='white')+geom_text(aes(label = Freq),color ='black',size = 6)+theme_light()+主题(panel.grid.major = element_blank(),panel.grid.minor = element_blank(),legend.position =无",panel.border = element_blank(),plot.background = element_blank(),axis.line = element_blank())返回(cm_d_p)}图书馆(插入符号)#>加载所需包装:格子#模拟数据set.seed(23)pred<-factor(sample(1:7,100,replace = T))ref<-factor(sample(1:7,100,replace = T))cm<-插入符:: confusionMatrix(pred,ref)g<-图.cm(cm)G#>警告:删除了包含缺失值(geom_text)的8行. 

由(v0.3.0)创建于2020-04-29 sup>

I adapted a heatmap plot for a confusion matrix from this answer.
However I would like to twist it. In the diagonal (from top left to bottom right) are the matches (correct classifications). My aim would be, to plot this diagonal in a yellow color palette. And mismatches (so all tiles except those in the diagonal) in a red color palette.

In my plot.cm function I can get the diagonal with

  cm_d$diag <- cm_d$Prediction == cm_d$Reference # Get the Diagonal
  cm_d$ndiag <- cm_d$Prediction != cm_d$Reference # Not the Diagonal

And with the correct geom_tile aesthetics I can get only the diagonal (in the desired yellow-ish) color scheme

geom_tile( data = cm_d[!is.na(cm_d$diag), ],aes(color = Freq)) +
scale_fill_gradient(guide = FALSE,low=alpha("lightyellow",0.75), high="yellow",na.value = 'white') 

However I am not able to get the second color scheme on the elements of cm_d$ndiag I found the package ggnewscale that offers new_scale() as well as new_scale_fill().
I tired to implement it with the help of this blog. However the result are only darkgray filled tiles for the rest of the heatmap

# adapted from https://stackoverflow.com/a/60150826/7318488
library(ggplot2)     # to plot
library(gridExtra)   # to put more
library(grid)        # plot together
library(likert)      # for reversing the factor order
library(ggnewscale)

plot.cm <- function(cm){
  # extract the confusion matrix values as data.frame
  cm_d <- as.data.frame(cm$table)
  cm_d$diag <- cm_d$Prediction == cm_d$Reference # Get the Diagonal
  cm_d$ndiag <- cm_d$Prediction != cm_d$Reference # Not the Diagonal     
  cm_d[cm_d == 0] <- NA # Replace 0 with NA for white tiles
  cm_d$Reference <-  reverse.levels(cm_d$Reference) # diagonal starts at top left

  # plotting the matrix
  cm_d_p <-  ggplot(data = cm_d, aes(x = Prediction , y =  Reference, fill = Freq))+
    scale_x_discrete(position = "top") +
    geom_tile( data = cm_d[!is.na(cm_d$diag), ],aes(color = Freq)) +
    scale_fill_gradient(guide = FALSE,low=alpha("lightyellow",0.75), high="yellow",na.value = 'white') +
    # THIS DOESNT WORK
    # new_scale("fill") +
    # geom_tile( data = cm_d[!is.na(cm_d$ndiag), ],aes(color = Freq)) +
    # scale_fill_gradient(guide = FALSE,low=alpha("red",0.75), high="darkred",na.value = 'white') +

    geom_text(aes(label = Freq), color = 'black', size = 6) +
    theme_light() +
    theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
      legend.position = "none",
      panel.border = element_blank(),
      plot.background = element_blank(),
      axis.line = element_blank())

  return(cm_d_p)
}

Sample Data:
Simulated Caret Confusion Matrix

library(caret)
# simulated data
set.seed(23)
pred <- factor(sample(1:7,100,replace=T))
ref<- factor(sample(1:7,100,replace=T))
cm <- caret::confusionMatrix(pred,ref)
g <- plot.cm(cm)
g

解决方案

I believe the issue is simply that you're specifying aes(color = Freq) instead of aes(fill = Freq. Is plot what you were aiming for? You could also simplify all of this by just using a divergent color scale and creating a new variable that marks Freq as negative if it's off the diagonal? See second example below

# adapted from https://stackoverflow.com/a/60150826/7318488
library(ggplot2)     # to plot
library(gridExtra)   # to put more
library(grid)        # plot together
library(likert)      # for reversing the factor order
#> Loading required package: xtable
library(ggnewscale)

plot.cm <- function(cm){
  # extract the confusion matrix values as data.frame
  cm_d <- as.data.frame(cm$table)
  cm_d$diag <- cm_d$Prediction == cm_d$Reference # Get the Diagonal
  cm_d$ndiag <- cm_d$Prediction != cm_d$Reference # Not the Diagonal     
  cm_d[cm_d == 0] <- NA # Replace 0 with NA for white tiles
  cm_d$Reference <-  reverse.levels(cm_d$Reference) # diagonal starts at top left

  # plotting the matrix
  cm_d_p <-  ggplot(data = cm_d, aes(x = Prediction , y =  Reference, fill = Freq))+
    scale_x_discrete(position = "top") +
    geom_tile( data = cm_d[!is.na(cm_d$diag), ],aes(fill = Freq)) +
    scale_fill_gradient(guide = FALSE,low=alpha("lightyellow",0.75), high="yellow",na.value = 'white') +
    # THIS DOESNT WORK
    new_scale("fill") +
    geom_tile( data = cm_d[!is.na(cm_d$ndiag), ],aes(fill = Freq)) +
    scale_fill_gradient(guide = FALSE,low=alpha("red",0.75), high="red",na.value = 'white') +

    geom_text(aes(label = Freq), color = 'black', size = 6) +
    theme_light() +
    theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
          legend.position = "none",
          panel.border = element_blank(),
          plot.background = element_blank(),
          axis.line = element_blank())

  return(cm_d_p)
}

library(caret)
#> Loading required package: lattice
# simulated data
set.seed(23)
pred <- factor(sample(1:7,100,replace=T))
ref<- factor(sample(1:7,100,replace=T))
cm <- caret::confusionMatrix(pred,ref)
g <- plot.cm(cm)
g
#> Warning: Removed 8 rows containing missing values (geom_text).

Created on 2020-04-29 by the reprex package (v0.3.0)

# adapted from https://stackoverflow.com/a/60150826/7318488
library(ggplot2)     # to plot
library(gridExtra)   # to put more
library(grid)        # plot together
library(likert)      # for reversing the factor order
#> Loading required package: xtable
library(ggnewscale)

plot.cm <- function(cm){
  # extract the confusion matrix values as data.frame
  cm_d <- as.data.frame(cm$table)
  cm_d$diag <- cm_d$Prediction == cm_d$Reference # Get the Diagonal
  cm_d$ndiag <- cm_d$Prediction != cm_d$Reference # Not the Diagonal     
  cm_d[cm_d == 0] <- NA # Replace 0 with NA for white tiles
  cm_d$Reference <-  reverse.levels(cm_d$Reference) # diagonal starts at top left

  cm_d$ref_freq <- cm_d$Freq * ifelse(is.na(cm_d$diag),-1,1)

  # plotting the matrix
  cm_d_p <-  ggplot(data = cm_d, aes(x = Prediction , y =  Reference, fill = Freq))+
    scale_x_discrete(position = "top") +
    geom_tile( data = cm_d,aes(fill = ref_freq)) +
    scale_fill_gradient2(guide = FALSE,low="red",high="yellow", midpoint = 0,na.value = 'white') +
    geom_text(aes(label = Freq), color = 'black', size = 6)+
     theme_light() +
    theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
          legend.position = "none",
          panel.border = element_blank(),
          plot.background = element_blank(),
          axis.line = element_blank())

  return(cm_d_p)
}

library(caret)
#> Loading required package: lattice
# simulated data
set.seed(23)
pred <- factor(sample(1:7,100,replace=T))
ref<- factor(sample(1:7,100,replace=T))
cm <- caret::confusionMatrix(pred,ref)
g <- plot.cm(cm)
g
#> Warning: Removed 8 rows containing missing values (geom_text).

Created on 2020-04-29 by the reprex package (v0.3.0)

这篇关于ggplot2 Heatmap 2不同的配色方案-混淆矩阵:与未分类的匹配的配色方案不同的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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