第三章 类别数据可视化

Author

221527231雷景润

1 解释原始数据

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

    包含分组:一等舱,二等舱,三等舱,船员;性别:男女;幸存:是否,年龄:大人小孩,人数

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

2 条形图

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

2.1 数据准备

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

    选取性别和幸存情况的人数数据做列联表,根据性别和幸存情况对人数进行汇总,对其设置标签(性别,生还,人数)。使数据清晰可观

# 数据准备
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) 垂直并列条形图")+
  scale_x_discrete(
    "性别",
    labels = c(
      "Male" = "男",
      "Female" = "女"
    )
  )+
  scale_fill_discrete(
    "生还",
    labels = c(
      "No" = "否",
      "Yes" = "是"
    )
  )
  

# 图(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(
      "Male" = "男",
      "Female" = "女"
    )
  )+
  scale_fill_discrete(
    "生还",
    labels = c(
      "No" = "否",
      "Yes" = "是"
    )
  )

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

2.3 介绍图形特点和信息

  • 条形图清晰明了,可以清楚反映每个标签对应人数的情况,从图中我们可以看出不同性别年龄的生还情况,1.男性死亡的比例比女性的大得多,2.男性和女性虽然生还人数差不多,但对于女性,绝大多数的女性都生还下来,而大部分男性死亡

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()等函数作图

# 创建组合图表
ggplot(df, aes(x = 乘客舱位)) +
  # 柱状图 - 显示各舱位人数(使用左侧y轴)
  geom_col(aes(y = 人数), width = 0.6, fill = "#4E84C4", alpha = 0.7) +
  # 折线图 - 显示累积百分比(使用右侧y轴)
  geom_line(aes(y = 累积百分比 * max(人数) / 100), 
            group = 1, color = "#D16103", size = 1.2) +
  # 点图 - 标记累积百分比点
  geom_point(aes(y = 累积百分比 * max(人数) / 100), 
             color = "#D16103", size = 3) +
  # 添加人数标签
  geom_text(aes(y = 人数, label = 人数), 
            vjust = -0.5, size = 3.5, color = "black") +
  # 添加累积百分比标签
  geom_text(aes(y = 累积百分比 * max(人数) / 100, 
                label = paste0(累积百分比, "%")),
            vjust = -1, size = 3.5, color = "#D16103") +
  # 设置双y轴
  scale_y_continuous(
    name = "乘客人数",
    sec.axis = sec_axis(~ . * 100 / max(df$人数), 
                     name = "累积百分比(%)")
  ) +
  # 设置颜色和主题
  scale_color_identity() +
  labs(title = "泰坦尼克号各舱位乘客人数及累积百分比",
       x = "乘客舱位等级") +
  theme_minimal() +
  theme(
    plot.title = element_text(hjust = 0.5, size = 14, face = "bold"),
    axis.title.y.left = element_text(color = "#4E84C4"),
    axis.title.y.right = element_text(color = "#D16103"),
    axis.text.x = element_text(size = 11),
    panel.grid.major.x = element_blank()
  )

3.3 介绍图形特点和信息

  • 条形图和折线图的组合,既反映了不同分组的人数,船员>三等舱>一等舱>二等舱,船员的人数最多,二等舱的人数最少,又反映了不同分组累计百分比,船员占总人数的40.2%,三等仓占总人数的32.1%,一等仓占总人数的14.8%,二等仓占总人数的12.8%。

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)

4.2 利用geom_col() 作图

ggplot(df)+aes(x = Survived, y = percent, fill = Class)+ylab("百分比(%)")+
  geom_bar(stat="identity",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",
  reverse = TRUE,
  position = "stack"
)  

4.4 介绍图形特点和信息

  • 1.堆叠式结构:通过堆叠条形图(position = "stack")展示不同类别(如乘客等级Class)在两种生存状态(Survived = Yes/No)下的百分比分布,直观反映整体构成及类别间的相对比例,船员的死亡率最高,幸存率也最高,其次是三等仓,二等仓,一等仓。

  • 2.交叉比较:可同时观察同一Class在不同生存状态下的占比差异,或同一生存状态下各Class的分布情况。

  • 3.调色板控制:使用palette = "Blues"reverse = TRUE,通过颜色深浅反转突出关键类别(如深色代表高优先级或低频率群体)。

5 树状图和旭日图

绘制Class、Sex、Age和Survived4个变量的矩形树状图和旭日图

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

df<-data%>%
  rename(人数=Freq) # 将Freq命名为频数

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

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

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

5.3 介绍图形特点和信息

6 热图和南丁格尔玫瑰图

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

6.1 数据准备

df<-data%>%
  summarise(人数=sum(Freq),.by=c(Class,Survived)) 
  
# 图(a)Class和Survived的点阵图
palette<-rev(brewer.pal(11,"RdYlGn"))       # 设置调色板
ggballoonplot(df,x="Class",y="Survived",   # 设置图形的x轴和y轴
   shape=21,                    # 设置形状,默认21,可选22,23,24,25
   size="人数",fill="人数",                 # 设置点的大小和填充颜色变量
   size.range = c(7,15),                    # 设置最小点和最大点的范围
   rotate.x.text=FALSE,                     # x轴文本标签不旋转
   ggtheme=scale_fill_gradientn(colors=palette))+  # 设置渐变颜色
   theme(axis.text.y=element_text(angle=90))+      # y轴标签旋转90度
   ggtitle("(a)  Class和Survived的点阵图")

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

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

df <- data %>%
  group_by(Class, Survived) %>%
  summarise(人数 = sum(Freq), .groups = "drop")
ggHeatmap(df,aes(x=Class,y=Survived,fill=人数),          # 绘制矩形热图
   addlabel=TRUE,                                      # 添加数值标签
   palette="Reds")+                                    # 使用红色调色板
   ggtitle("(a1) 矩形热图")                            # 添加标题

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

df <- df %>%
  group_by(Class) %>%
  arrange(Survived) %>%  # 确保Survived按顺序排列
  mutate(ypos = 人数 - cumsum(人数) / 20) # 计算标签的垂直位置  

# 定义标签角度和调色板
myangle <- seq(-20, -340, length.out = 8) 
palette <- brewer.pal(n = 2, "Set3")       # 根据Survived类别数选择颜色数

# 绘制玫瑰图
p <- ggplot(df, aes(x = Class, y = 人数, fill = Survived)) + 
  geom_col(width = 1, color = "grey20", position = "stack") +  # 堆叠条形图
  geom_text(aes(y = ypos, label = 人数),  # 添加数值标签
            size = 3.5,                   # 标签字体大小
            color = "black",              # 标签颜色(与背景对比)
            show.legend = FALSE) +        # 不显示图例中的文本标签
  coord_polar(theta = "x", start = 0) +    # 极坐标转换
  scale_fill_manual(values = palette) +    # 手动指定填充颜色
  theme(axis.text.x = element_text(size = 10, angle = myangle),
    legend.position = "right") +
  labs(y = "人数", title = "乘客生存情况玫瑰图")
print(p)

6.4 介绍图形特点和信息

  • 南丁格尔玫瑰图(Nightingale Rose Chart)特点

    1. 图形结构

      • 极坐标系:数据以圆心为原点,通过扇形区域的半径长度和角度表示数值大小。

      • 面积映射:每个扇形的面积与其代表的数值成正比(面积=半径²×角度),适合强调类别间的相对比例。

      • 多分类对比:用户图表中通过不同扇形区分 Class(如1st、2nd、3rd、Crew)和 Survived(Yes/No),直观展示生存情况的分布差异。

    2. 数据展示

      • 纵轴标注:人数(如“673”代表某一类别的总人数)。

      • 横轴分类

        • Survived:分为“Yes”和“No”,表示生存状态。

        • Class:乘客等级(如1st、2nd等),可能与生存状态嵌套展示。

      • 数值示例

        • “N=9”可能表示某一小类的人数(如Crew中未幸存的人数)。

        • 扇形面积差异显著,例如“Yes”对应的扇形可能半径较大,表示生存人数较多。

  • Survived=Yes

    • 1st舱:212人(扇形半径较大,面积占比高)。

    • Crew:148人(面积中等,颜色区别于其他舱位)。

  • Survived=No

    • 3rd舱:673人(最大扇形,颜色最深)。

    • 2nd舱:128人(面积较小)。

  • 热图(Heatmap)特点(基于常规定义,用户图表中未明确展示)

    1. 图形结构

      • 矩阵形式:行和列代表不同维度(如 ClassSurvived),单元格颜色表示交叉统计值(如人数、比例)。

      • 颜色映射:使用渐变色(如深红→浅红)表示数值高低,颜色越深代表值越大。

    2. 数据展示

      • 若应用于泰坦尼克号数据,可展示:

        • Class(1st、2nd、3rd、Crew)。

        • Survived(Yes/No)。

        • 单元格:填充人数或生存率,颜色深浅反映数值大小。

    3. 优势

      • 密集数据对比:快速识别高密度区域(如3rd舱未幸存人数最多)。

      • 多维分析:支持添加更多维度(如叠加 SexAge)。

7 饼环图

绘制Class和 Sex的饼环图。

7.1 数据准备

# 按Class和Sex分组汇总人数
df <- data %>%
  group_by(Class, Sex) %>%
  summarise(人数 = sum(Freq), .groups = "drop") %>%
  mutate(Class = factor(Class, levels = c("1st", "2nd", "3rd", "Crew")),
  Sex = factor(Sex, levels = c("Male", "Female")))

datatable(df,rownames = FALSE)

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

# 绘制饼环图
ggPieDonut(data = df,
  aes(pies = Class, donuts = Sex, count = 人数), 
  title = "(b) Class为饼图,Sex为环形图") 

7.3 介绍图形特点和信息

  • 7.3.0.1 1. 分层数据可视化

    • 双维度对比:同时展示乘客等级(Class)和性别(Sex)两个维度的分布,例如:

      • 内层饼图显示 Crew 占 40.2%,是最大的乘客群体。

      • 外层环形图显示 Crew 中男性占 33.2%,女性占 14.8%。

    • 嵌套结构:每个 Class 区块的环形部分对应其性别细分,直观体现层级关系。

    7.3.0.2 2. 比例直观性

    • 面积映射比例:区块大小与人数占比成正比,例如:

      • 3rd 等级占 32.1%,面积明显大于 2nd(12.9%)。

      • 在 1st 等级中,男性占 8.2%,女性占 1%,性别比例差异显著。

    7.3.0.3 3. 交互性支持(若启用)

    • 悬停提示:可显示精确数值(如 Class: 1st, Sex: Male, 人数: 8.2%)。

    • 点击钻取:进一步展开某一层级的详细信息(需代码额外配置)。

    7.3.0.4 4. 颜色与标签设计

    • 颜色区分:不同 ClassSex 通过颜色区分(如蓝色代表男性,红色代表女性)。

    • 标签标注:百分比直接标注在区块上(需注意标签排版,例如修正 2nd (12.9%)st2nd (12.9%))。