数据绘图要点11-雷达图的注意事项

准确通过雷达图表现数据有许多值得需要思考的地方,本文主要介绍雷达图的一些注意事项。

文章目录

  • ​​数据绘图要点11-雷达图的注意事项​​
  • ​​雷达图绘制​​
  • ​​基础雷达图​​
  • ​​多类别雷达图​​
  • ​​雷达图存在的问题与解决方案​​
  • ​​雷达图存在的问题​​
  • ​​解决方案​​
  • ​​参考​​

雷达图绘制

基础雷达图

雷达图又称蜘蛛图或网络图,是一种二维图表类型,设计用于绘制多个定量变量的一个或多个数值系列。每个变量都有自己的轴,所有轴都连接在图形的中心。让我们考虑一个学生的考试成绩。他在数学、体育、统计学等十个主题上的得分范围为 0 到 20。雷达图为每个主题提供一个轴。通过该形状,您可以查看学生在哪些主题上表现出色或表现不佳。

# 加载库
library(tidyverse)
library(viridis)
library(patchwork)
library(hrbrthemes)
library(fmsb)
library(colormap)


# 创建数据
#设计随机种子
set.seed(42)
# 设计数据
data <- as.data.frame(matrix( sample( 2:20 , 10 , replace=T) , ncol=10))
# 添加列名
colnames(data) <- c("math" , "english" , "biology" , "music" , "R-coding", "data-viz" , "french" , "physic", "statistic", "sport" )
# 在数据中添加每一列的最大范围和最小范围
data <- rbind(rep(20,10) , rep(0,10) , data)
data

A data.frame: 3 × 10

math

english

biology

music

R-coding

data-viz

french

physic

statistic

sport

<dbl>

<dbl>

<dbl>

<dbl>

<dbl>

<dbl>

<dbl>

<dbl>

<dbl>

<dbl>

20

20

20

20

20

20

20

20

20

20

0

0

0

0

0

0

0

0

0

0

18

6

2

11

5

19

18

16

8

5

# 创建雷达图
par(mar=c(0,0,0,0))
radarchart( data, axistype=1,
# 自定义雷达图四边形
# pcol设置四边形边框颜色,pfcol设置四边形填充颜色,plwd设置边框粗细
pcol=rgb(0.9,0.6,0.5,0.9) , pfcol=rgb(0.2,0.5,0.5,0.5) , plwd=4,
# 自定义网格
# cglcol设置网格线条颜色,cglty设置网格线条类型,axislabcol设置轴标签字体颜色
# caxislabels设置轴的范围,cglwd设置网格线条粗细
cglcol="black", cglty=2, axislabcol="blue", caxislabels=seq(0,20,5), cglwd=0.8,
# vlcex设置类别标签位置大小
vlcex=1.2
)

[数据分析与可视化] 数据绘图要点11-雷达图的注意事项_数据挖掘

多类别雷达图

在上一个图表中,只绘制了一个系列,显示了一名学生的表现。一个常见的任务是比较几个人。只需几个系列,就可以在同一图表上显示每个组。如下图所示,很明显,Shirley综合表现优于Sonia,除了在运动、英语和 R 编码方面。

# 创建数据
set.seed(1)
data <-as.data.frame(matrix( c( sample( 2:20 , 10 , replace=T), sample( 2:9 , 10 , replace=T)) , ncol=10, byrow=TRUE))
colnames(data) <- c("math" , "english" , "biology" , "music" , "R-coding", "data-viz" , "french" , "physic", "statistic", "sport" )
# 设置第二行第二列数据为19
data[2,2]=19
# 在数据中添加每一列的最大范围和最小范围
data <- rbind(rep(20,10) , rep(0,10) , data)
data

A data.frame: 4 × 10

math

english

biology

music

R-coding

data-viz

french

physic

statistic

sport

<dbl>

<dbl>

<dbl>

<dbl>

<dbl>

<dbl>

<dbl>

<dbl>

<dbl>

<dbl>

20

20

20

20

20

20

20

20

20

20

0

0

0

0

0

0

0

0

0

0

5

8

2

3

12

15

19

20

2

11

7

19

3

8

2

8

6

6

2

2

# 设置颜色
colors_border=c( rgb(0.2,0.5,0.5,0.9), rgb(0.8,0.2,0.5,0.9) )
colors_in=c( rgb(0.2,0.5,0.5,0.4), rgb(0.8,0.2,0.5,0.4) )

# 创建雷达图
radarchart( data, axistype=1,
# 自定义四边形
pcol=colors_border , pfcol=colors_in , plwd=4, plty=1 ,
# 自定义网格
cglcol="grey", cglty=1, axislabcol="grey", caxislabels=seq(0,20,5), cglwd=1.1,
# 自定义标签
vlcex=0.8 )

# 设置图例
# bty设置图例文字外边框样式,pch设置图例图标样式,col设置图例图标颜色
# text.col设置图例文字颜色,cex设置图例文字大小,pt.cex设置图例图标大小
legend(x=0.85, y=1, legend = c("Shirley", "Sonia"), bty = "n", pch=20 , col=colors_border , text.col = "black", cex=0.9, pt.cex=1.6)

[数据分析与可视化] 数据绘图要点11-雷达图的注意事项_r语言_02

对于两个或三个以上的系列,使用多子图是一个很好的做法,以避免出现杂乱的数字。每个学生都有自己的雷达图。很容易理解特定个体的特征,寻找形状的相似性可以让您找到具有相似特征的学生。

# 创建数据
set.seed(1)
data <-as.data.frame(matrix( sample( 2:20 , 60 , replace=T) , ncol=10, byrow=TRUE))
colnames(data) <- c("math" , "english" , "biology" , "music" , "R-coding", "data-viz" , "french" , "physic", "statistic", "sport" )
# 在数据中添加每一列的最大范围和最小范围
data <- rbind(rep(20,10) , rep(0,10) , data)
data

A data.frame: 8 × 10

math

english

biology

music

R-coding

data-viz

french

physic

statistic

sport

<dbl>

<dbl>

<dbl>

<dbl>

<dbl>

<dbl>

<dbl>

<dbl>

<dbl>

<dbl>

20

20

20

20

20

20

20

20

20

20

0

0

0

0

0

0

0

0

0

0

5

8

2

3

12

15

19

20

2

11

15

11

8

10

16

6

10

15

6

6

3

11

13

16

2

4

7

11

11

7

16

13

7

9

13

7

8

20

11

7

15

3

14

19

15

7

2

20

20

9

7

13

7

9

8

12

18

5

14

9

# 设置颜色
colors_border=colormap(colormap=colormaps$viridis, nshades=6, alpha=1)
colors_in=colormap(colormap=colormaps$viridis, nshades=6, alpha=0.3)

# 设置标题
mytitle <- c("Max", "George", "Xue", "Tom", "Alice", "bob")

# 设置子图
par(mar=rep(0.8,4))
par(mfrow=c(2,3))

# 依次绘图
for(i in 1:6){
radarchart( data[c(1,2,i+2),], axistype=1,
pcol=colors_border[i] , pfcol=colors_in[i] , plwd=4, plty=1 ,
cglcol="grey", cglty=1, axislabcol="grey", caxislabels=seq(0,20,5), cglwd=0.8,
vlcex=0.8,
title=mytitle[i]
)
}

[数据分析与可视化] 数据绘图要点11-雷达图的注意事项_数据分析_03

雷达图存在的问题与解决方案

雷达图存在的问题

1 圆形布局表示更难阅读

沿着单个垂直或水平轴布局时,定量值更容易比较。这是对圆形布局的普遍指责。下图仅考虑一名学生的数据。比较条形图中的值更容易,也更准确。

# 创建数据
set.seed(1)
data <-as.data.frame(matrix( sample( 2:20 , 10 , replace=T) , ncol=10))
colnames(data) <- c("math" , "english" , "biology" , "music" , "R-coding", "data-viz" , "french" , "physic", "statistic", "sport" )

# 在数据中添加每一列的最大范围和最小范围
data <-rbind(rep(20,10) , rep(0,10) , data)
data

A data.frame: 3 × 10

math

english

biology

music

R-coding

data-viz

french

physic

statistic

sport

<dbl>

<dbl>

<dbl>

<dbl>

<dbl>

<dbl>

<dbl>

<dbl>

<dbl>

<dbl>

20

20

20

20

20

20

20

20

20

20

0

0

0

0

0

0

0

0

0

0

5

8

2

3

12

15

19

20

2

11

# 创建雷达图
par(mar=c(0,0,0,0))
p1 <- radarchart( data, axistype=1,
pcol=rgb(0.2,0.5,0.5,0.9) , pfcol=rgb(0.2,0.5,0.5,0.5) , plwd=4 ,
cglcol="grey", cglty=1, axislabcol="grey", caxislabels=seq(0,20,5), cglwd=0.8,vlcex=1.3 )

[数据分析与可视化] 数据绘图要点11-雷达图的注意事项_r语言_04

# 创建条形图
data %>% slice(3) %>% t() %>% as.data.frame() %>% add_rownames() %>% arrange(V1) %>% mutate(rowname=factor(rowname, rowname)) %>%
ggplot( aes(x=rowname, y=V1)) +
geom_segment( aes(x=rowname ,xend=rowname, y=0, yend=V1), color="grey") +
geom_point(size=5, color="#69b3a2") +
coord_flip() +
theme(
panel.grid.minor.y = element_blank(),
panel.grid.major.y = element_blank(),
axis.text = element_text( size=32),
legend.position="none"
) +
ylim(0,20) +
ylab("mark") +
xlab("")

[数据分析与可视化] 数据绘图要点11-雷达图的注意事项_数据分析_05

2 不支持排名

在上面的例子中,棒棒糖图是有序的。它使您可以立即查看哪个主题的得分最高以及每个主题的排名。对于没有起点和终点的雷达图,这更加困难。

3 类别排序有巨大的影响

雷达图的读者可能会关注观察到的形状。这可能会产生误导,因为这种形状高度依赖于周围类别的顺序。查看使用相同数据制作的这些图表,以下三张图数据一样,但更改了类别排序。

# 创建数据
set.seed(7)
data <- as.data.frame(matrix( sample( 2:20 , 10 , replace=T) , ncol=10))
colnames(data) <- c("math" , "english" , "biology" , "music" , "R-coding", "data-viz" , "french" , "physic", "statistic", "sport" )
data[1,1:3]=rep(19,3)
data[1,6:8]=rep(4,3)
data <- rbind(rep(20,10) , rep(0,10) , data)
data

A data.frame: 3 × 10

math

english

biology

music

R-coding

data-viz

french

physic

statistic

sport

<dbl>

<dbl>

<dbl>

<dbl>

<dbl>

<dbl>

<dbl>

<dbl>

<dbl>

<dbl>

20

20

20

20

20

20

20

20

20

20

0

0

0

0

0

0

0

0

0

0

19

19

19

3

16

4

4

4

16

9

# 改变排序创建其他数据
data2 <- data[,sample(1:10,10, replace=FALSE)]
data2
data3 <- data[,sample(1:10,10, replace=FALSE)]
data3

A data.frame: 3 × 10

sport

biology

music

english

data-viz

statistic

math

R-coding

french

physic

<dbl>

<dbl>

<dbl>

<dbl>

<dbl>

<dbl>

<dbl>

<dbl>

<dbl>

<dbl>

20

20

20

20

20

20

20

20

20

20

0

0

0

0

0

0

0

0

0

0

9

19

3

19

4

16

19

16

4

4

A data.frame: 3 × 10

french

english

music

data-viz

biology

physic

math

sport

statistic

R-coding

<dbl>

<dbl>

<dbl>

<dbl>

<dbl>

<dbl>

<dbl>

<dbl>

<dbl>

<dbl>

20

20

20

20

20

20

20

20

20

20

0

0

0

0

0

0

0

0

0

0

4

19

3

4

19

4

19

9

16

16

# 绘图
par(mar=c(0,0,0,0))
par(mfrow=c(3,1))
radarchart( data, axistype=1, pcol=rgb(0.2,0.5,0.5,0.9) , pfcol=rgb(0.2,0.5,0.5,0.5) , plwd=4 ,
cglcol="grey", cglty=1, axislabcol="grey", caxislabels=seq(0,20,5), cglwd=0.8, vlcex=0.8 )
radarchart( data2, axistype=1, pcol=rgb(0.2,0.5,0.5,0.9) , pfcol=rgb(0.2,0.5,0.5,0.5) , plwd=4 ,
cglcol="grey", cglty=1, axislabcol="grey", caxislabels=seq(0,20,5), cglwd=0.8, vlcex=0.8 )
radarchart( data3, axistype=1, pcol=rgb(0.2,0.5,0.5,0.9) , pfcol=rgb(0.2,0.5,0.5,0.5) , plwd=4 ,
cglcol="grey", cglty=1, axislabcol="grey", caxislabels=seq(0,20,5), cglwd=0.8, vlcex=0.8 )

[数据分析与可视化] 数据绘图要点11-雷达图的注意事项_数据挖掘_06

4 不确定的数值比例

雷达图显示几个定量变量的值,所有变量都表示在一个轴上。在前面的示例中,所有变量(范围从0 到 20的)共享相同的比例和相同的单位。但雷达图也可以显示完全不同的变量。在这种情况下,不要忘记为每个显示一个明显的比例:否则读者会期望相同的比例。

5 对差异的过度评估

雷达图中形状的面积也呈二次而非线性增加,这可能会导致观看者认为微小的变化比实际情况更重要。在下面的示例中,左边的学生在每个主题上的得分为 7,而右边的学生在每个主题上的得分为 14。但是,右图的面积是左图面积的两倍多。

# 创建数据
data <- as.data.frame(matrix( c(7,7,7,7,7) , ncol=5))
colnames(data) <- c("math" , "english" , "biology" , "music" , "R-coding")
data <- rbind(rep(20,10) , rep(0,10) , data)
data
data2 <- data
data2[3,] <- rep(14,5)
data2

A data.frame: 3 × 5

math

english

biology

music

R-coding

<dbl>

<dbl>

<dbl>

<dbl>

<dbl>

20

20

20

20

20

0

0

0

0

0

7

7

7

7

7

A data.frame: 3 × 5

math

english

biology

music

R-coding

<dbl>

<dbl>

<dbl>

<dbl>

<dbl>

20

20

20

20

20

0

0

0

0

0

14

14

14

14

14

# 绘图
par(mar=rep(0,4))
par(mfrow=c(2,1))
radarchart( data, axistype=1, pcol=rgb(0.2,0.5,0.5,0.9) , pfcol=rgb(0.2,0.5,0.5,0.5) ,
plwd=4 , cglcol="grey", cglty=1, axislabcol="grey", caxislabels=seq(0,20,5), cglwd=0.8, vlcex=0.8 )
radarchart( data2, axistype=1, pcol=rgb(0.2,0.5,0.5,0.9) , pfcol=rgb(0.2,0.5,0.5,0.5) ,
plwd=4 , cglcol="grey", cglty=1, axislabcol="grey", caxislabels=seq(0,20,5), cglwd=0.8, vlcex=0.8 )

[数据分析与可视化] 数据绘图要点11-雷达图的注意事项_r语言_07

解决方案

如果您要显示单个系列并且所有定量变量都具有相同的比例,则使用条形图或棒棒糖图,对变量进行排名:

# 创建数据
set.seed(1)
data <-as.data.frame(matrix( sample( 2:20 , 10 , replace=T) , ncol=10))
colnames(data) <- c("math" , "english" , "biology" , "music" , "R-coding", "data-viz" , "french" , "physic", "statistic", "sport" )
data <-rbind(rep(20,10) , rep(0,10) , data)

# 绘制条形图
data %>% slice(3) %>% t() %>% as.data.frame() %>% add_rownames() %>% arrange(V1) %>% mutate(rowname=factor(rowname, rowname)) %>%
ggplot( aes(x=rowname, y=V1)) +
geom_segment( aes(x=rowname ,xend=rowname, y=0, yend=V1), color="grey") +
geom_point(size=5, color="#69b3a2") +
coord_flip() +
theme(
panel.grid.minor.y = element_blank(),
panel.grid.major.y = element_blank(),
axis.text = element_text( size=32 ),
legend.position="none"
) +
ylim(0,20) +
ylab("mark") +
xlab("")

[数据分析与可视化] 数据绘图要点11-雷达图的注意事项_数据挖掘_08

如果您有两个系列要绘制,您仍然可以使用条形图和棒棒糖图。这是一个有2个系列的例子。它侧重于第一个学生(深色),并让您可以看到另一个学生(浅色)的表现如何。

# 创建数据
set.seed(1)
data <-as.data.frame(matrix( sample( 2:20 , 20 , replace=T) , ncol=10))
colnames(data) <- c("math" , "english" , "biology" , "music" , "R-coding", "data-viz" , "french" , "physic", "statistic", "sport" )
data <-rbind(rep(20,10) , rep(0,10) , data)

# 绘图
data %>% slice(c(3,4)) %>% t() %>% as.data.frame() %>% add_rownames() %>% arrange(V1) %>% mutate(rowname=factor(rowname, rowname)) %>%
ggplot( aes(x=rowname, y=V1)) +
# 绘制线条
geom_segment( aes(x=rowname ,xend=rowname, y=V2, yend=V1), color="grey") +
geom_point(size=5, color="#69b3a2") +
# 设置透明度
geom_point(aes(y=V2), size=5, color="#69b3a2", alpha=0.5) +
coord_flip() +
theme(
panel.grid.minor.y = element_blank(),
panel.grid.major.y = element_blank(),
axis.text = element_text( size=32 )
) +
ylim(0,20) +
ylab("mark") +
xlab("")

[数据分析与可视化] 数据绘图要点11-雷达图的注意事项_数据_09

如果你有超过2个系列要绘制,使用条形图或棒棒糖图的分面也许可以解决问题:

# 创建数据
set.seed(1)
data <-as.data.frame(matrix( sample( 2:20 , 40 , replace=T) , ncol=10))
colnames(data) <- c("math" , "english" , "biology" , "music" , "R-coding", "data-viz" , "french" , "physic", "statistic", "sport" )
data <-rbind(rep(20,10) , rep(0,10) , data)
rownames(data) <- c("-", "--", "John", "Angli", "Baptiste", "Alfred")

# 绘图数据
data <- data %>% slice(c(3:6)) %>%
t() %>%
as.data.frame() %>%
add_rownames() %>%
arrange() %>%
mutate(rowname=factor(rowname, rowname)) %>%
gather(key=name, value=mark, -1)

# 编制数据
data$name <- recode(data$name, V1 = "John", V2 = "Angli", V3 = "Baptiste", V4 = "Alfred")

# 绘图
data %>% ggplot( aes(x=rowname, y=mark)) +
geom_bar(stat="identity", fill="#69b3a2", width=0.6) +
coord_flip() +
theme(
panel.grid.minor.y = element_blank(),
panel.grid.major.y = element_blank(),
axis.text = element_text( size=16 )
) +
ylim(0,20) +
ylab("mark") +
xlab("") +
facet_wrap(~name, ncol=4)

[数据分析与可视化] 数据绘图要点11-雷达图的注意事项_数据挖掘_10

如果您有很多系列要绘制,或者您的变量没有相同的比例,那么最好的选择可能是切换到平行坐标图。

library(GGally)
# 导入iris数据
data <- iris

# 绘图
data %>%
ggparcoord(
columns = 1:4, groupColumn = 5, order = "anyClass",
showPoints = TRUE,
title = "Parallel Coordinate Plot for the Iris Data",
alphaLines = 0.3
) +
scale_color_viridis(discrete=TRUE)

[数据分析与可视化] 数据绘图要点11-雷达图的注意事项_数据分析_11

参考