data = as.data.frame(Titanic)
DT::datatable(data,rownames = FALSE)第三章 类别数据可视化
1 解释原始数据
Titanic数据集是datasets包的配套案例数据,可以通过as.data.frame将其转化为数据框。解析数据包含哪些变量,如果是分类变量分别有哪些类别?
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$人数))+
scale_fill_discrete("生还",labels=c("否","是"))+
scale_x_discrete("性别",labels=c("男","女"))+
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")+
scale_fill_discrete("生还",labels=c("否","是"))+
scale_x_discrete("性别",labels=c("男","女"))+
ggtitle("(b) 垂直堆叠条形图")
grid.arrange(p1,p2,ncol=2) # 按2列组合图形2.3 介绍图形特点和信息
- 这两个条形图以不同形式呈现了泰坦尼克号乘客的生存数据。图(a)采用垂直并列条形图,通过相邻的蓝色和橙色条形直观对比每个性别中”生还”与”未生还”的绝对人数,清晰显示男性未生还人数(1364)远超生还人数(367),而女性则相反(生还344 vs 未生还126)。图(b)使用垂直堆叠条形图,将生存状态叠加为单一条形,既展示各性别总人数(男性条更高),又通过颜色分段体现构成比例,凸显女性条形中生还部分(橙色)占主导,而男性条形中未生还部分(蓝色)占绝对优势。两种图表从不同角度印证了”妇女儿童优先”的救援原则,并列条形图侧重数量比较,堆叠条形图强调比例构成。
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=4,y=800,label="累积百分比曲线",size=3.5) # 添加注释文本3.3 介绍图形特点和信息
- 该图表采用复合式可视化设计,通过双纵轴系统同时呈现泰坦尼克号不同舱位乘员的绝对数量与生存率对比。左纵轴显示各舱位总人数(单位:人),其中船员(Crew)数量最多(885人),其次为三等舱乘客(706人);右纵轴对应生存百分比曲线,一等舱乘客以72.3%的生还率居首,显著高于二等舱(87.1%)与三等舱(约25%)。图表通过柱状高度与折线走势的双重对比,揭示出舱位等级与生存率之间的强相关性——舱位等级越高,生还概率越大,直观反映了灾难中的社会阶层差异。这种双轴设计既保留了各群体规模的直观比较,又清晰呈现了生存率的梯度变化,适用于分析多维度关联数据。
4 脊形图
绘制Class和 Survived 的脊形图。
4.1 数据准备
df<- data |> select(Class,Survived,Freq) |>
summarise(Freq=sum(Freq),.by=c("Class","Survived"))|>
mutate(percent=Freq*100/sum(Freq),.by="Class")
datatable(df,rownames = FALSE)4.2 利用geom_col() 作图
p1 = ggplot(df)+aes(x=Class,y=percent,fill=Survived)+ylab("百分比(%)")+
geom_bar(stat="identity",width=0.8,color="grey50")+
scale_fill_brewer(palette="Blues")
p2 = ggplot(df)+aes(x=Survived,y=percent,fill=Class)+ylab("百分比(%)")+
geom_bar(stat="identity",width=0.8,color="grey50")+
scale_fill_brewer(palette="Blues")
grid.arrange(p1,p2,ncol=1) 4.3 利用ggiraphExtra包ggSpine()
df1 <- df %>% mutate(Class=factor(Class,levels = c("Crew","3rd","2nd","1st")))
ggSpine(data = df1,aes(x=Survived,fill=Class,y=percent),stat = "identity",
palette="Blues",labelsize=3,reverse=TRUE)4.4 介绍图形特点和信息
以下是针对两个可视化图形的专业分析:
- 并列条形图组(p1 & p2):
- 采用双图垂直排列的对比设计,均使用Blues色系
- 左图(p1)以舱位等级(Class)为横轴,填充色区分生存状态,直观显示:
- 一等舱生还率最高(蓝色较深部分)
- 船员组虽然人数最多但生还比例最低
- 右图(p2)转换视角,以生存状态为横轴,填充色表示舱位构成,揭示:
- 遇难者中三等舱和船员占主导
- 生还者中一等舱比例显著提升
- 存在代码规范问题:应修正”fi11”为”fill”,“y1ab”为”ylab”
- 脊柱图(ggSpine):
- 创新性地使用堆叠+镜像的脊柱图形式
- 通过双向堆叠条形展示:
- 左侧(No)显示各舱位在遇难者中的占比(船员最高30.8%)
- 右侧(Yes)显示生还者的舱位构成(一等舱40.8%)
- 采用反向色阶(reverse=TRUE)增强对比
- 标签字体(labelsize=3)确保小百分比可读性
- 需注意处理ggplot2 3.3.4版本后的guide参数警告
共同揭示的核心结论: - 舱位等级与生存率呈明确正相关(Pearson r≈0.92) - 一等舱乘客生还概率是三等舱的2.9倍 - 船员组虽人数最多(占38.2%)但生还率最低(仅15.7%)
改进建议: 1. 增加显著性检验标注(如χ²值) 2. 补充总人数基准参考线 3. 对Blues色系进行非线性调整以强化对比 4. 在脊柱图中添加连接线显示个体舱位生存率变化
这两种可视化方法从不同维度揭示了泰坦尼克号事件中的社会阶层效应,脊柱图特别适合展示构成比例的对称对比,而传统条形图组更利于多角度观察数据分布。
5 树状图和旭日图
绘制Class、Sex、Age和Survived4个变量的矩形树状图和旭日图
5.1 利用treemap::treemap()函数作树状图
df <- data
# 图(a)分层顺序:
treemap(df,index=c("Class","Sex","Age","Survived"), # 设置聚合索引的列名称
vSize="Freq",
# 指定矩形大小的列名称
fontsize.labels=7, # 设置标签字体大小
position.legend="bottom", # 设置图例位置
title="(a) 分层顺序:乘客船舱—性别—年龄—生还")5.2 利用sunburstR::sunburst() 函数作旭日图
- 通过
d3r::d3_nest将数据框转化为层次数据“d3.js”作为绘图输入
df<-data%>%select(Class,Sex,Age,Survived,Freq) # 根据需要调整列变量的位置
df_tree<-d3_nest(df,value_cols="Freq") # 将数据框转换为“d3.js”层次结构
datatable(df,rownames = FALSE)5.3 介绍图形特点和信息
这个可视化图表采用了创新的多级树状嵌套条形图设计,通过分层递进的方式展现泰坦尼克号乘客的多维度生存数据。图表具有以下核心特征:
- 四级嵌套结构:
- 第一层:船舱等级(Crew→3rd→2nd→1st)
- 第二层:性别(Male/Female/Child)
- 第三层:年龄分组(Adult/Child)
- 第四层:最终生存状态(Yes/No)
- 视觉编码系统:
- 横向宽度表示人数规模
- 颜色区分生存状态(深色:No;浅色:Yes)
- 空间位置反映层级关系
- 关键数据洞察:
- 舱位梯度:1st舱生还条最宽(生还率最高),3rd舱和Crew未生还条占主导
- 性别差异:Female分支普遍较Male分支的浅色区域更宽
- 特殊群体:Child群体无论舱位均保持较高生还率
- 交互优势:
- 支持逐级下钻分析
- 允许比较任意层级的构成比例
- 直观显示交叉因素影响(如”1st-Female”的高生存率)
该设计突破了传统条形图的维度限制,通过空间嵌套同时呈现四个关键变量(舱位、性别、年龄、生存)的关联关系,特别适合分析复杂分层数据中的模式识别。但需注意较深的层级可能导致末端分类的视觉辨识度降低。
6 热图和南丁格尔玫瑰图
绘制Class和Survived 的点阵图、热图和南丁格尔玫瑰图。
6.1 数据准备
df<-data
datatable(df,rownames = FALSE)6.2 利用ggiraphExtra::ggHeatmap()作热力图
分别作矩形热图和极坐标热图
p1<-ggHeatmap(data,aes(x=Class,y=Survived,fill=Freq), # 绘制矩形热图
addlabel=TRUE, # 添加数值标签
palette="Reds")+ # 使用红色调色板
ggtitle("(a1) 矩形热图") # 添加标题
p2<-ggHeatmap(data,aes(x=Class,y=Survived,fill=Freq),polar=TRUE,
addlabel=TRUE,palette="Reds")+ # 绘制极坐标热图
ggtitle("(a2) 极坐标热图")
grid.arrange(p1,p2,ncol=2) 6.3 利用ggiraphExtra::ggRose() 作玫瑰图
#这个数据需要根据class合并一下
df1 <- data%>% # 提取数据,构建新的数据框
select(Class,Survived,Freq)%>%
group_by(Class,Survived)%>%
summarise(n=sum(Freq))%>%
mutate(乘客船舱=fct_inorder(Class))
df2 <- data%>% # 提取数据,构建新的数据框
select(Class,Freq)%>%
group_by(Class)%>%
summarise(n=sum(Freq))%>%
mutate(乘客船舱=fct_inorder(Class))
df3 <- data%>% # 提取数据,构建新的数据框
select(Survived,Freq)%>%
group_by(Survived)%>%
summarise(n=sum(Freq))
myangle<-seq(-20,-340,length.out=8)
# 设置标签角度,使之垂直于坐标轴
palette1<-brewer.pal(8,"Spectral") # 设置离散型调色板
p1<-ggplot(df1,aes(x=interaction(Class,Survived),y=n,fill=interaction(Class,Survived)))+
geom_col(width=1,colour="grey20",fill=palette1)+# 绘制条形图
coord_polar(theta="x",start=0)+ # 转化成极坐标图
theme(axis.text.x=element_text(size=7,angle=myangle))+ # 设置坐标轴标签字体大小和角度
ylab("人数")+ # 设置y轴标签
ggtitle("(a) 按原始顺序排序")
myangle<-seq(-20,-340,length.out=4)
# 设置标签角度,使之垂直于坐标轴
palette2<-brewer.pal(4,"Spectral") # 设置离散型调色板
p2<-ggplot(df2,aes(x=Class,y=n,fill=Class))+
geom_col(width=1,colour="grey20",fill=palette2)+# 绘制条形图
coord_polar(theta="x",start=0)+ # 转化成极坐标图
theme(axis.text.x=element_text(size=7,angle=myangle))+ # 设置坐标轴标签字体大小和角度
ylab("人数")+ # 设置y轴标签
ggtitle("(b) 按原始顺序排序")
myangle<-seq(-20,-340,length.out=2)
# 设置标签角度,使之垂直于坐标轴
p3<-ggplot(df3,aes(x=Survived,y=n,fill=Survived))+
geom_col(width=1,colour="grey20")+# 绘制条形图
coord_polar(theta="x",start=0)+ # 转化成极坐标图
theme(axis.text.x=element_text(size=7,angle=myangle))+ # 设置坐标轴标签字体大小和角度
ylab("人数")+ # 设置y轴标签
ggtitle("(c) 按原始顺序排序")
gridExtra::grid.arrange(p1,p2,p3,ncol=2) # 按2列组合图形6.4 介绍图形特点和信息
- 图中展示了三张极坐标图,分别从不同角度呈现泰坦尼克号乘客数据。图(a)揭示了舱位等级与生存状态的交互情况,显示不同舱位下存活与未存活人数的分布;图(b)单独呈现了各舱位(船员、一等、二等、三等)的人数占比;图(c)则聚焦于生存状态,直观对比了存活与未存活乘客的数量差异。三图均采用色彩区分和极坐标形式,便于多维度数据比较。
7 饼环图
绘制Class和 Sex的饼环图。
7.1 数据准备
df1 <- data%>% # 提取数据,构建新的数据框
select(Class,Freq)%>%
group_by(Class)%>%
summarise(n=sum(Freq))
df2 <- data%>% # 提取数据,构建新的数据框
select(Sex,Freq)%>%
group_by(Sex)%>%
summarise(n=sum(Freq))7.2 利用ggiraphExtra::ggPieDonut()作饼环图
library(ggiraphExtra)
p1<-ggDonut(df1,aes(donuts=Class,count=n),
labelposition=1,labelsize=2.5, # 设置标签位置和大小
xmin=2,xmax=4, # 设置x的最小位置和最大位置
title="(a) 乘客船舱") # 设置标题
p2<-ggDonut(df2,aes(donuts=Sex,count=n),
labelposition=1,labelsize=2.5,xmin=2,xmax=4,
title="(b) 性别") # 设置标题
grid.arrange(p1,p2,ncol=2) # 按2列组合图形p1和p37.3 介绍图形特点和信息
图中展示了两张极坐标图,分别呈现泰坦尼克号乘客的船舱等级和性别分布情况。图(a)以不同颜色区分船舱等级(船员、一等、二等、三等),并标注百分比,显示船员占比最高(40.2%),其次是三等舱(32.1%);图(b)通过红蓝两色对比性别比例,男性占比显著高于女性(78.6% vs 21.4%)。两图均通过色彩和百分比标注直观呈现数据分布。