第三章 类别数据可视化

Author

221527112陈丹盈

1 解释原始数据

  • Titanic数据集是datasets包的配套案例数据,可以通过as.data.frame将其转化为数据框。解析数据包含哪些变量,如果是分类变量分别有哪些类别?

    答:数据包括Class、Sex、Age、Survived、Freq五个变量。Class有以下类别:“1st”, “2nd”, “3rd”, “Crew”。Sex有以下类别:“Male”, “Female”。Age有以下类别:“Child”, “Adult”。Survived有以下类别:“No”, “Yes”。

data = as.data.frame(Titanic)
DT::datatable(data,rownames = FALSE)

2 条形图

绘制Sex和 Survived的并列条形图和堆叠条形图,并为条形图添加频数标签。

2.1 数据准备

  • 下面代码作了什么数据处理?为什么要这样处理?

    答:从原始数据中只选择Sex、Survived和Freq这三列。并按性别和生存状态的组合分组,并计算每组的总人数。将列名改为中文。

# 数据准备
df <- data %>% select(Sex,Survived,Freq) %>% 
  summarise(n=sum(Freq),.by=c(Sex,Survived)) %>% 
  rename(性别=Sex,生还=Survived,人数=n) 
  
DT::datatable(df,rownames = FALSE)

2.2 利用geom_col函数作图

# 图(a)垂直并列条形图
p1<-ggplot(df,aes(x=性别,y=人数,fill=生还))+
  geom_col(width=0.8,    # 设置条形宽度
  position="dodge",      # 绘制并列条形图
  color="gray50")+       # 设置条形图的边框颜色
  scale_fill_brewer(palette="Set2")+  # 设置填充颜色
  geom_text(aes(label=人数),position=position_dodge(0.9),vjust=-0.5,size=3)+          # 设置标签垂直位置和字体大小
  ylim(0,1.1*max(df$人数))+      # 设置y轴范围
  ggtitle("(a) 垂直并列条形图")

# 图(b) 水平并列条形图
p2<-ggplot(df,aes(x=性别,y=人数,fill=生还))+
  geom_col(width=0.7,color="gray50")+ # 绘制堆叠条形图(默认)
  geom_text(aes(label=人数),position=position_stack(0.5),size=3)+
  scale_fill_brewer(palette="Set2")+
  ggtitle("(b) 垂直堆叠条形图")

grid.arrange(p1,p2,ncol=2)           # 按2列组合图形

  • 你可以通过修改数据或者修改刻度标签将图中性别和生还的类别标签改为中文,请给出代码完成修改。
# 图(a)垂直并列条形图
p1<-ggplot(df,aes(x=性别,y=人数,fill=生还))+
  geom_col(width=0.8,    # 设置条形宽度
  position="dodge",      # 绘制并列条形图
  color="gray50")+       # 设置条形图的边框颜色
  scale_fill_brewer(palette="Set2")+  # 设置填充颜色
  geom_text(aes(label=人数),position=position_dodge(0.9),vjust=-0.5,size=3)+          # 设置标签垂直位置和字体大小
  ylim(0,1.1*max(df$人数))+      # 设置y轴范围
  ggtitle("(a) 垂直并列条形图")

# 图(b) 水平并列条形图
p2<-ggplot(df,aes(x=性别,y=人数,fill=生还))+
  geom_col(width=0.7,color="gray50")+ # 绘制堆叠条形图(默认)
  geom_text(aes(label=人数),position=position_stack(0.5),size=3)+
  scale_fill_brewer(palette="Set2")+
  ggtitle("(b) 垂直堆叠条形图")

grid.arrange(p1,p2,ncol=2)           # 按2列组合图形

# 图(a)垂直并列条形图
p1<-ggplot(df,aes(x=性别,y=人数,fill=生还))+
  geom_col(width=0.8,    # 设置条形宽度
  position="dodge",      # 绘制并列条形图
  color="gray50")+       # 设置条形图的边框颜色
  scale_fill_brewer(palette="Set2")+  # 设置填充颜色
  geom_text(aes(label=人数),position=position_dodge(0.9),vjust=-0.5,size=3)+          # 设置标签垂直位置和字体大小
  ylim(0,1.1*max(df$人数))+      # 设置y轴范围
  ggtitle("(a) 垂直并列条形图")+
  scale_x_discrete(
    "性别",
    labels = c("男","女" )
  )+
   scale_fill_discrete(
    "生还",
    labels = c("否","是" )
  )

# 图(b) 水平并列条形图
p2<-ggplot(df,aes(x=性别,y=人数,fill=生还))+
  geom_col(width=0.7,color="gray50")+ # 绘制堆叠条形图(默认)
  geom_text(aes(label=人数),position=position_stack(0.5),size=3)+
  scale_fill_brewer(palette="Set2")+
  ggtitle("(b) 垂直堆叠条形图")+
  scale_x_discrete(
    "性别",
    labels = c("男","女" )
  )+
   scale_fill_discrete(
    "生还",
    labels = c("否","是" )
  )

grid.arrange(p1,p2,ncol=2)           # 按2列组合图形

2.3 介绍图形特点和信息

  • 垂直并列条形图的不同类别的条形并排排列,便于直接比较同一分组内不同类别的值。垂直堆叠条形图,不同类别的条形堆叠在一起,形成整体条形,同时显示部分与整体的关系。从图中可以看出,不同性别的存活人数虽然大致相同,但女性的存活比例明显大于男性的存活比例。

3 帕累托图

绘制Class 的帕累托图。

3.1 数据准备

df<-data |> 
  select(Class,Freq) |> 
  summarise(n=sum(Freq),.by=Class) |> 
  rename(乘客舱位=Class,人数=n ) |> 
  arrange(desc(人数)) |> 
  mutate(累积百分比 = cumsum(人数*100/sum(人数)), #计算累积百分比
         累积百分比 = round(累积百分比,1),        #保留一位小数 
         乘客舱位 = fct_inorder(乘客舱位)         #按字符出现顺序定义因子水平
         )

datatable(df,rownames = FALSE)

3.2 利用geom_col()+geom_line()+geom_point()等函数作图

palette<-rev(brewer.pal(4,"Reds"))        # 设置调色板
# 绘制条形图
p<-ggplot(df)+aes(x=乘客舱位,y=人数)+                
  geom_col(width=0.8,fill=palette,color="grey50")+# 绘制条形图
 
  geom_text(aes(x=乘客舱位,y=人数,label=人数,vjust=-0.5),size=3,color="gray50")+                      # 添加数值标签,垂直调整标签位置
   ylab("人数\n(人)")+               # 设置y轴标签 
  theme(axis.text.y=element_text(angle=90,hjust=0.5,vjust=0.5))+     # 调整y轴标签角度
  theme(legend.position="none")         # 删除图例

# 绘制折线和点
p1<-p+geom_line(aes(x=as.numeric(乘客舱位),y=累积百分比*max(人数/100)))+     # 绘制累积百分比曲线
  geom_point(aes(x=as.numeric(乘客舱位),y=累积百分比*max(人数/100)),
             size=2.5,shape=23,fill="white")+                     # 绘制点
  geom_text(aes(label=累积百分比,x=乘客舱位,y=1*累积百分比*max(人数/100),
    hjust=0.6,vjust=-0.95),size=3,colour="blue3")+                # 添加百分比数值标签
  scale_y_continuous(sec.axis = sec_axis(~./max(df$人数/100)))# 添加坐标轴
p1+annotate("text",x=4.5,y=800,label="百分比(%)",angle=90,size=3.5)+
   annotate("text",x=3,y=700,label="累积百分比曲线",size=3.5)   # 添加注释文本

3.3 介绍图形特点和信息

  • 该图结合了柱状图和折线图。柱状图的数据必须按数值从大到小降序排列,确保能直观识别最重要的类别。从图中可以看出,机组人员占比最大,其次分别为三等舱、一等舱、二等舱。

4 脊形图

绘制Class和 Survived 的脊形图。

4.1 数据准备

df<- data |> select(Class,Survived,Freq) %>% 
  summarise(n=sum(Freq),.by=c("Class","Survived")) %>%
  mutate(percent=n*100/sum(n),.by=Survived)

datatable(df,rownames = FALSE)

4.2 利用geom_col() 作图

ggplot(df)+aes(x=Survived,y=percent,fill=Class)+ylab("百分比(%)")+
  geom_col(width=0.8,color="grey50")+
  scale_fill_brewer(palette="Blues")

4.3 利用ggiraphExtra包ggSpine()

df1<- df %>% mutate(
  Class=factor(Class,levels=c("Crew","3rd","2nd","1st"))
)
ggSpine(data=df1,aes(x=Survived,y=percent,fill=Class),stat="identity",
  palette="Blues",labelsize=3,reverse=TRUE)  # 反转调色板颜色

4.4 介绍图形特点和信息

  • 直观显示每个生存状态下各舱位的百分比构成。从图中可以观察出,在存活人数中,机组人员占比最高,其次是一等舱、三等舱,最后是二等舱。但是死亡人数中,机组人员占比也最高,其次是三等舱、二等舱,最后是一等舱。

5 树状图和旭日图

绘制Class、Sex、Age和Survived4个变量的矩

5.1 利用treemap::treemap()函数作树状图

treemap(data,index=c("Class","Sex","Age","Survived"),  # 设置聚合索引的列名称
   vSize="Freq",                                  # 指定矩形大小的列名称
  #fontsize.labels=9,                             # 设置标签字体大小
  position.legend="bottom",                      # 设置图例位置
  title="(a) 分层顺序:Class—Sex—Age-Survived")

5.2 利用sunburstR::sunburst() 函数作旭日图

  • 通过d3r::d3_nest将数据框转化为层次数据“d3.js”作为绘图输入
df<-data%>%select(Class,Sex,Age,Survived) 
df_tree<-d3_nest(df,value_cols="Survived")    
datatable(df,rownames = FALSE)
sunburst(data=df_tree,
         valueField="Survived",
         count=TRUE,                   # 在解释中包括计数和总数
         sumNodes=TRUE)  # 计算大小字段的字符为vSize
Legend
                 # 默认总和节点=TRUE

5.3 介绍图形特点和信息

树状图:过嵌套矩形展示 四级层级结构,先按船舱等级分割,再按性别,再按年龄,最后按生存状态每个矩形面积由 Freq(频数)决定,数值越大面积越大。有图可以看出,在不同的船舱中,女性的存活率要高于男性。

旭日图:直观地呈现数据的层级结构和占比情况

6 热图和南丁格尔玫瑰图

绘制Class和Survived 的点阵图、热图和南丁格尔玫瑰图。

6.1 数据准备

heatmap_data

 # 数据准备
df <- data %>% 
  group_by(Class, Survived) %>%
  summarise(Count = sum(Freq), .groups = 'drop') 
 
 DT::datatable(df,rownames = FALSE)

6.2 利用ggiraphExtra::ggHeatmap()作热力图

分别作矩形热图和极坐标热图

p1<-ggHeatmap(df,aes(x=Class,y=Survived,fill = Count ),       # 绘制矩形热图
   addlabel=TRUE,                                      # 添加数值标签
   palette="Reds")+                                   # 使用红色调色板
   ggtitle("(a1) 矩形热图")                      # 添加标题
 
p2<-ggHeatmap(df,aes(x=Class,y=Survived,fill = Count ),polar=TRUE,
   addlabel=TRUE,palette="Reds")+                      # 绘制极坐标热图
   ggtitle("(a2) 极坐标热图")
grid.arrange(p1,p2,ncol=2)  

6.3 利用ggiraphExtra::ggRose() 作玫瑰图

myangle<-seq(-20,-340,length.out=8)       # 设置标签角度,使之垂直于坐标轴
palette<-brewer.pal(8,"Set3")            # 设置离散型调色板

# 绘制玫瑰图
p1<-ggplot(df,aes(x=Class,y=Count,fill=Survived))+           
  geom_col(width=1,colour="grey20",fill=palette)+# 绘制条形图
  coord_polar(theta="x",start=0)+   # 转化成极坐标图
  theme(axis.text.x=element_text(size=5,angle=myangle))+ # 设置坐标轴标签字体大小和角度
  ylab("Count")+                   # 设置y轴标签
  ggtitle("按Class原始顺序排序")
p1

6.4 介绍图形特点和信息

  • 热力图:是一种通过颜色梯度直观展示数据矩阵中数值大小关系的可视化工具。由图可得,机组人员的死亡人数的颜色最深,即死亡人数最多

  • 玫瑰图:特点是视觉冲击力强,适合展示周期性数据或分类数据的对比。扇形的面积与数据值成正比,比普通柱状图更突出差异。

7 饼环图

绘制Class和 Sex的饼环图。

7.1 数据准备

# 数据准备
df <- data %>% 
  group_by(Class, Sex) %>%
  summarise(Freq = sum(Freq), .groups = 'drop') 
 
 DT::datatable(df,rownames = FALSE)

7.2 利用ggiraphExtra::ggPieDonut()作饼环图

p1<-ggPieDonut(data=df,aes(pies=Class,donuts=Sex,count = Freq ),
  title="(a) 乘客舱位为饼图,性别为环形图")
  

p2<-ggPieDonut(df,aes(pies=Sex,donuts=Class,count = Freq ),
  title="(b) 性别为饼图,乘客舱位为环形图")

grid.arrange(p1,p2,ncol=2)

7.3 介绍图形特点和信息

  • 通过中心留白形成环形结构,在展示构成比例的同时优化了数据对比效果。由图可以观察到,泰坦尼克号上人员由机组人员、一等舱、二等舱、三等舱人员组成。机组人员中女性的占比和男性占比。