RR语言与统计分析数据-R语言-图表-决策-Linux-Python

R-ggplot2-强迫症的福音-点与对应标签密度太高, 互相重

2020-01-02  本文已影响0人  TroyShen

目录


0. 问题导入

日常绘图过程中, 我们可能需要给图中的样本点加上标签. 但是, 当点的密度过于密集的时候, 标签的字可能会互相重叠, 这样会极大地影响信息的表达. 这时, 我们可能会通过缩小字的大小/增大图片的长宽来解决这个问题, 但这样会极大地影响图片的美感, 特别是在标字的大小与横/纵轴标签大小差距过大的时候. 此外, 标签的字过小也会失去其传达信息的本质作用, 出现在图中反而成为了一种累赘?! 那么应该如何解决这个问题呢?

本篇以Simple Correspondence Analysis分析结果图的呈现为例, 来就标签与标签重复以及标签与点重复的问题给出两套解决方案.(烦请大家多多转发并引导读者在简书平台中点赞加关注哈~特别感谢大家啦!)

1. 示例数据

点击蓝字下载示例数据

2. 示例数据导入及Simple Correspondence Analysis(CA对应分析)

本篇对示例数据进行CA处理,分析土地利用类型与EFT的对应关系, 并在分析最后对CA分析结果进行输出.

setwd('L:\\JianShu\\20200102')
text = read.csv('text.csv', header = T)
rownames = text[,1]
text = text[,-1]
rownames(text) = rownames
head(text)
                       EFT1   EFT2   EFT3    EFT4   EFT5
 Cropland           1792451 552037 382092 1545937  78970
 Forest                2877   3696   4226    2218   6491
 Grassland            61614 443988 591755  182162 395628
 Shrubland                3     73    277       7    559
 Impervious surface     817  25076  62320    3067 137074
 Bareland              1256   9760  40619    3488 155106
## CA Analysis
ca.res = ca(text)
ca.col = data.frame(DIM1 = ca.res$colcoord[,1],DIM2=ca.res$colcoord[,2],Label = colnames(text))
ca.row = data.frame(DIM1 = ca.res$rowcoord[,1],
                    DIM2 = ca.res$rowcoord[,2],Label = rownames(text))

ca_df = rbind(ca.col,ca.row)
ca_m = melt(ca_df,c('DIM1','DIM2'))
head(ca_m)
       DIM1      DIM2 variable     value
1 -0.889536 -0.548955    Label      EFT1
2  0.299793  1.262690    Label      EFT2
3  0.882275  1.303609    Label      EFT3
4 -0.689422 -0.196233    Label      EFT4
5  2.050763 -1.750576    Label      EFT5
6 -0.672387 -0.193882    Label  Cropland

3. CA分析结果初步可视化

CA分析结果会以png图片形式呈现在文件夹下.

p1 = ggplot()+
    geom_point(data = ca_m,aes(x = DIM1, y = DIM2, color = value,
                               shape = value),size = 3)+
    
    scale_shape_manual(values =  c(rep(1,6),rep(2,5)))+
    scale_color_manual(values = c(rep('blue',6),rep('red',5)))+
    geom_vline(data = ca_m,aes(xintercept = 0),size = 0.5,linetype = 'dashed',color = 'black')+
    geom_hline(data = ca_m,aes(yintercept = 0),size = 0.5,linetype = 'dashed',color = 'black')+
    geom_text(data = ca_m,aes(x = DIM1,y = DIM2, label = paste0(value),
                                    color = value), size = 5)+
    theme_bw()+
    xlim(-1,3)+
    theme(
      legend.position = 'none',
      panel.background = element_rect(fill = 'white'),
      panel.grid = element_blank(),
      axis.text = element_text(face='bold',colour='black',size=12,hjust=.5),
      axis.title = element_text(face='bold',colour='black',size=12,hjust=.5),
    )
  
  png('plot1.png',
      height = 20,
      width = 20,
      units = 'cm',
      res = 800)
  print(p1)
  dev.off()
图1 CA分析结果初步可视化

来来来, 我们仔细端详下图1. 是不是车祸现场, OMG, 简直就是逼死强迫症系列好吧! 特别是:
1. 标签与符号重叠?
2. 标签与标签重叠?
小编表示一阵心塞...下面, 我们就来解决这个问题~


4. 方案一: 基于geom_text 自带的属性去重叠(图2)

ggplot2 中的geom_text 自带一属性是check_overlap 是专门用来应对标签重叠的问题的. 它解决问题的方式方法十分粗暴, 直接将重叠的两个/多个标签同时删去...此外, geom_text 也自备了nudge_x 与nudge_y 两个参数来解决标签与点重合的问题. 那么, 下边我们就来看看基于geom_text 属性调整的解决结果.

p2 = ggplot()+
    geom_point(data = ca_m,aes(x = DIM1, y = DIM2, color = value,
                               shape = value),size = 3)+
    
    scale_shape_manual(values =  c(rep(1,6),rep(2,5)))+
    scale_color_manual(values = c(rep('blue',6),rep('red',5)))+
    geom_vline(data = ca_m,aes(xintercept = 0),size = 0.5,linetype = 'dashed',color = 'black')+
    geom_hline(data = ca_m,aes(yintercept = 0),size = 0.5,linetype = 'dashed',color = 'black')+
    geom_text(data = ca_m,aes(x = DIM1,y = DIM2, label = paste0(value),
                              color = value),size = 5,
             check_overlap = T, nudge_x = 0.2,nudge_y = 0.2)+
    theme_bw()+
    xlim(-1,3)+
    theme(
      legend.position = 'none',
      panel.background = element_rect(fill = 'white'),
      panel.grid = element_blank(),
      axis.text = element_text(face='bold',colour='black',size=12,hjust=.5),
      axis.title = element_text(face='bold',colour='black',size=12,hjust=.5),
    )
  
  png('plot2.png',
      height = 20,
      width = 20,
      units = 'cm',
      res = 800)
  print(p2)
  dev.off()
图2 方案一: 基于geom_text 自带的属性去重叠结果

我们对比下图1与图2, 可以发现经过基于geom_text自带属性调整, 整个画面已经变得清爽多了. 但是也是太清爽了, 太多标签被删去了, 表示我们无法判读图中许多点的具体信息, 这种操作显然是太过顾此失彼.
那么有没有更好的解决方案呢? 请接着往下看

5. 方案二: 基于geom_text_repel的去重操作(图3)

这个函数可谓是标签界的一股清流, 完美解决了标签与标签重复与完整保留标签信息之间的矛盾. 下面我们来看看怎么操作与具体的修正效果(图3):

  p3 = ggplot()+
    geom_point(data = ca_m,aes(x = DIM1, y = DIM2, color = value,
                               shape = value),size = 3)+
    
    scale_shape_manual(values =  c(rep(1,6),rep(2,5)))+
    scale_color_manual(values = c(rep('blue',6),rep('red',5)))+
    
    geom_text_repel(data = ca_m,aes(x = DIM1,y = DIM2, label = paste0(value),
                              color = value),force =3,size = 5)+
    geom_vline(data = ca_m,aes(xintercept = 0),size = 0.5,linetype = 'dashed',color = 'black')+
    geom_hline(data = ca_m,aes(yintercept = 0),size = 0.5,linetype = 'dashed',color = 'black')+
    
    theme_bw()+
    xlim(-1,3)+
    theme(
      legend.position = 'none',
      panel.background = element_rect(fill = 'white'),
      panel.grid = element_blank(),
      axis.text = element_text(face='bold',colour='black',size=12,hjust=.5),
      axis.title = element_text(face='bold',colour='black',size=12,hjust=.5),
    )
  
  png('plot3.png',
      height = 20,
      width = 20,
      units = 'cm',
      res = 800)
  print(p3)
  dev.off()
图3 方案二: 基于geom_text_repel的去重操作结果图

6. 总结

本篇主要解决了以下几个问题:
1. 如何在R中进行对应分析(CA)?
2. 如何将CA分析的结果通过ggplot2进行可视化呈现?
3. 如何在保全完整信息的前提下解决标签/标签及标签/点重复的问题?

7. 本文所使用的软件包(没有的需要通过install.packages('')来进行安装)

  library(ca)
  library(ggplot2)
  library(reshape2)
  library(ggrepel)

8. 致谢

首先,感谢大家的持续关注,小编会继续努力,持续更新下去的!

大家如果觉得有帮助啊,还麻烦大家关注点赞,也可以扩散到朋友圈,多多引导朋友加入咱们这个简书技术平台, 代码共享推动科研进程, 多谢大家啦~

大家如果在使用本代码的过程有遇到问题的,可以留言评论,也可以私信我哈~~


小编联系方式
上一篇 下一篇

猜你喜欢

热点阅读