data = as.data.frame(Titanic)
DT::datatable(data,rownames = FALSE)第三章 类别数据可视化
1 解释原始数据
Titanic数据集是datasets包的配套案例数据,可以通过as.data.frame将其转化为数据框。解析数据包含哪些变量,如果是分类变量分别有哪些类别?- Class(船舱等级)
1st,2nd,3rd,CrewSex(性别)Male,FemaleAge(年龄)Child,AdultSurvived(是否幸存)No,YesFreq(频数)数值变量,记录每组人数。
2 条形图
绘制Sex和 Survived的并列条形图和堆叠条形图,并为条形图添加频数标签。
2.1 数据准备
- 下面代码作了什么数据处理?为什么要这样处理?
- 处理:筛选数据:只保留
Sex(性别)、Survived(生还)和Freq(频数)三列 分组汇总:按性别和生还状态分组,计算每组的总人数(sum(Freq)) 重命名列:将列名改为中文(性别、生还、人数) 交互展示:用DT包生成交互式表格,方便查看数据
目的:统计不同性别乘客的生存情况,并以直观的交互表格形式展示结果。
# 数据准备
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_x_discrete(
"性别",
labels = c(
"Female" = "女性",
"Male" = "男性"
)
)+
scale_fill_discrete(
"生还",
labels = c(
"No" = "否",
"Yes" = "是"
)
)
# 修改标签为中文(scale_x_discrete)
ggtitle("(a) 垂直并列条形图")$title
[1] "(a) 垂直并列条形图"
attr(,"class")
[1] "labels"
# 图(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_x_discrete(
"性别",
labels = c(
"Female" = "女性",
"Male" = "男性"
)
)+
scale_fill_discrete(
"生还",
labels = c(
"No" = "否",
"Yes" = "是"
)
)
ggtitle("(b) 垂直堆叠条形图")$title
[1] "(b) 垂直堆叠条形图"
attr(,"class")
[1] "labels"
grid.arrange(p1,p2,ncol=2) # 按2列组合图形2.3 介绍图形特点和信息
- 特点:p1并列展示,每个柱子上方标注具体人数,直观显示数据,便于直接对比。
- 信息:可以快速比较不同性别的生还情况。女性生还人数明显高于男性,符合“妇女儿童优先”的历史背景。适合用于展示 分类变量之间的对比。
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=1000,label="百分比(%)",angle=90,size=3.5)+
annotate("text",x=3.5,y=700,label="累积百分比曲线",size=3.5) # 添加注释文本3.3 介绍图形特点和信息
特点:组合图表:柱状图(数量分布)+ 折线图(累积百分比)双Y轴:左轴:绝对人数(柱状图)右轴:累积百分比(折线图)视觉设计:渐变色柱状图(Reds调色板,越红舱位越高)带数值标签(人数/百分比)辅助注释文本
信息:舱位分布:三等舱人数最多,头等舱最少。累积趋势:低舱位乘客占比快速累积(前三个舱位累积超60%)阶层差异:高舱位(深色)人数少但累积占比增长快
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_col(stat="identity",width = 0.8, color = "grey50") +
scale_fill_brewer(palette = "Blues")4.3 利用ggiraphExtra包ggSpine()
ggSpine(df,aes(x=Survived,y=percent,fill=Class),stat="identity",labelsize=3,reverse=TRUE) 4.4 介绍图形特点和信息
- 特点:
- 柱状图:柱状图由一系列矩形柱子组成,每个柱子的长度或高度代表数据的大小。柱子通常沿水平或垂直轴排列,以展示不同类别或组别之间的比较。柱子的颜色、图案或纹理可以用来区分不同的数据系列或分类。
- 脊柱图:脊柱图是一种特殊的柱状图,其中柱子的宽度非常窄,看起来像一条“脊柱”。柱子通常沿水平轴排列,高度表示数值大小。脊柱图通常用于展示大量的类别,这些类别在常规柱状图中可能会因为柱子太宽而难以区分。脊柱图可以水平或垂直展示,但更常见的是水平展示。
- 体现的信息:
- 柱形图:比较:柱状图适合用来比较不同类别之间的数值大小。趋势:当柱子按顺序排列时,可以展示数据随时间或有序类别变化的趋势。分布:可以展示数据的分布情况,通过柱子的长度可以直观地看出各部分占总体的比例。
- 脊柱图:特别适合展示数据的密度,即在特定数值范围内数据点的集中程度。分布:可以展示数据的分布形状,如正态分布、偏态分布等。比较:虽然脊柱图主要用于展示分布,但也可以用来比较不同数据集的分布形状。细节:由于柱子宽度较窄,脊柱图可以展示更多的类别,同时保持图表的清晰度。
- 总结:
- 柱状图:适用于比较不同类别的数值大小,展示趋势和分布,以及比例关系。
- 脊柱图:适用于展示数据的密度和分布形状,特别适合处理大量类别的数据。
5 树状图和旭日图
绘制Class、Sex、Age和Survived4个变量的矩形树状图和旭日图
5.1 利用treemap::treemap()函数作树状图
# 转换数据格式
df <- as.data.frame(Titanic) %>%
group_by(Class, Sex, Age, Survived) %>%
summarise(Freq = sum(Freq), .groups = "drop") %>%
mutate(
Class = factor(Class, levels = c("1st", "2nd", "3rd", "Crew")),
Survived = factor(Survived, labels = c("遇难", "生还")),
Age = factor(Age, labels = c("儿童", "成人"))
)
treemap(df,
index = c("Class", "Sex", "Age", "Survived"), # 分层变量
vSize = "Freq", # 方块大小
vColor = "Freq", # 颜色深浅
type = "value", # 基于数值着色
palette = "Reds", # 红色渐变
title = "泰坦尼克号乘客分布",
fontsize.title = 12,
border.col = "white" # 边框颜色
)5.2 利用sunburstR::sunburst() 函数作旭日图
- 通过
d3r::d3_nest将数据框转化为层次数据“d3.js”作为绘图输入
library(d3r)
df<-data%>%select(Sex,Class,Age,Survived,Freq) # 根据需要调整列变量的位置
df_tree<-d3_nest(df,value_cols="Freq") # 将数据框转换为“d3.js”层次结构
datatable(df,rownames = FALSE)library(sunburstR)
sunburst(data=df_tree, # 绘制旭日图
valueField="Freq", # 计算大小字段的字符为vSize
count=TRUE, # 在解释中包括计数和总数
sumNodes=TRUE) # 默认总和节点=TRUE5.3 介绍图形特点和信息
- 特点:
- 树状图:使用矩形表示数据,矩形的大小表示数值的大小。矩形可以嵌套,用于展示层级结构。颜色可以用来区分类别或表示额外的变量。
- 旭日图:以圆形为基础,从中心向外分层,每一层代表一个层级。每个扇区的角度表示数值的大小,颜色可以区分类别。可以交互式地展开或折叠层级。
- 体现的信息:
- 树状图:层次结构:适合展示多层级的数据,如组织架构、文件系统等。 比例关系:矩形的面积直观地表示数据的大小比例。分类信息:通过颜色和分组展示不同类别之间的差异。
- 旭日图:层级结构:适合展示多层级的数据,如分类数据的嵌套关系。 比例关系:扇区的角度直观地表示数据的大小比例。分类信息:通过颜色和层级展示不同类别之间的差异。
- 总结:
- 树状图适合展示层次结构和比例关系,适合平面布局。
- 旭日图适合展示层次结构和比例关系,适合圆形布局,交互性强。
6 热图和南丁格尔玫瑰图
绘制Class和Survived 的点阵图、热图和南丁格尔玫瑰图。
6.1 数据准备
df <- as.data.frame(Titanic) %>%
group_by(Class, Survived) %>%
summarise(Freq = sum(Freq), .groups = "drop") %>%
mutate(
Class = factor(Class, levels = c("1st", "2nd", "3rd", "Crew")),
Survived = factor(Survived, labels = c("遇难", "生还")),
Percent = Freq / sum(Freq) * 100
)6.2 利用ggiraphExtra::ggHeatmap()作热力图
分别作矩形热图和极坐标热图
#矩形热图
p1<-ggHeatmap(
data = df,
mapping = aes(x = Class, y = Survived, fill = Freq) # 必须通过mapping指定
,addlabel=TRUE) +
scale_fill_gradient(low = "white", high = "red") + # 颜色梯度
labs(title = "泰坦尼克号舱位-生存热力图")
#极坐标热图
p2<-ggHeatmap(
data = df,
mapping = aes(x = Class, y = Survived, fill = Freq),
polar = TRUE # 转换为极坐标
,addlabel=TRUE
) +
scale_fill_viridis_c() + # 使用viridis色阶
labs(title = "极坐标热力图")
grid.arrange(p1,p2,ncol=2) 6.3 利用ggiraphExtra::ggRose() 作玫瑰图
# 加载必要的包
library(ggplot2)
library(dplyr)
library(ggrepel)
library(RColorBrewer)
library(forcats)
# 将Class和Survived变为有序因子
df <- df %>%
mutate(
Class = factor(Class, levels = c("1st", "2nd", "3rd", "Crew"), ordered = TRUE),
Survived = factor(Survived, levels = c("遇难", "生还"), ordered = TRUE)
)
# 设置标签角度,使之垂直于坐标轴
myangle <- seq(-20, -340, length.out = length(unique(df$Class)))
# 设置离散型调色板
palette <- brewer.pal(2, "Set2") # 使用Set2调色板,颜色对比更明显
# 绘制玫瑰图
p <- ggplot(df, aes(x = Class, y = Freq, fill = Survived)) +
geom_col(width = 1, colour = "grey20", position = "stack") + # 使用geom_col代替geom_bar(stat="identity")
coord_polar(theta = "x", start = 0) + # 转换为极坐标,使用x轴作为角度
scale_fill_manual(values = palette) + # 自定义填充颜色
labs(
title = "泰坦尼克号乘客生存情况玫瑰图",
subtitle = "按舱位等级和生存状态分类",
fill = "生存状态",
x = NULL,
y = "乘客数量"
) +
theme_minimal(base_size = 10) + # 使用简洁的主题,设置基础字体大小
theme(
axis.text.x = element_text(size = 8, angle = myangle, hjust = 0.5, vjust = 0.5),
plot.title = element_text(hjust = 0.5, face = "bold"),
plot.subtitle = element_text(hjust = 0.5),
legend.position = "bottom"
) +
geom_text_repel(
aes(label = paste0(Freq, "\n", Percent)),
size = 3,
color = "grey30",
position = position_stack(vjust = 0.5),
box.padding = 0.1,
segment.color = NA
) # 为图形添加文本,显示数量和百分比
# 显示图形
print(p)6.4 介绍图形特点和信息
- 特点 :
- 热力图以矩阵形式展示数据,每个单元格用颜色表示数值大小。颜色深浅或冷暖表示数值的高低。可以添加行和列的标签,用于说明数据的分类。
- 玫瑰图:类似于饼图,但每个扇区的半径表示数值大小。扇区的角度通常固定,半径的变化更明显。可以使用颜色区分不同的类别。
- 体现的信息:
- 数值分布:直观展示数据在不同维度上的分布情况。相关性:用于展示变量之间的相关性或相似性。趋势和模式:通过颜色变化发现数据中的趋势和模式。
- 体现的信息:分类占比:展示各分类在总量中的占比。数值大小:通过半径的长度直观比较不同分类的数值大小。周期性数据:适合展示周期性或方向性数据(如时间、方向)。
- 总结:
- 热力图适合展示多维度数据的分布和相关性,适合分析复杂数据集。
- 玫瑰图适合展示分类数据的占比和数值大小,适合展示周期性或方向性数据。
7 饼环图
绘制Class和 Sex的饼环图。
7.1 数据准备
# 数据处理
df<-data |> select(Class,Sex,Freq) |>
summarise(n=sum(Freq),.by=c(Class,Sex)) |>
mutate(percent = n*100/sum(n),.by = Sex)
datatable(df)7.2 利用ggiraphExtra::ggPieDonut()作饼环图
# 绘制饼环图
p1<-ggPieDonut(data=df,aes(pies=Sex,donuts=Class,count=n),
title="(a) Class为饼图,Sex为环形图")
grid.arrange(p1)7.3 介绍图形特点和信息
特点:
图形特点:环形结构:饼环图的中心是空的,形成一个环形,这使得图形在视觉上更加轻盈和现代。扇区划分:环形被划分为若干扇区,每个扇区代表数据集中的一个类别或部分。颜色区分:不同的扇区通常使用不同的颜色来区分,这有助于快速识别各个类别。中心利用:中心的空白区域有时可以用来显示额外的信息,如标题、图例或关键数据点。交互性:在交互式图表中,饼环图的扇区可以响应用户的操作,如鼠标悬停或点击,显示更多详细信息。
体现的信息:
比例关系:饼环图直观地展示了各个类别在整体中所占的比例,通过扇区的大小来表示。分类比较:通过比较不同扇区的大小,可以快速了解各类别之间的相对大小。层次结构:如果数据具有层次结构,饼环图可以通过嵌套的环形来展示这种结构,每个环形代表一个层级。数据分布:饼环图可以展示数据的分布情况,帮助识别哪些类别是主要的,哪些是次要的。视觉吸引力:由于其独特的环形设计,饼环图在视觉上比传统的饼图更具吸引力,适合用于报告和演示。