第四章 数据分布可视化

Author

21527136邹伟亮

1 解释原始数据

  • faithful是R语言中自带的一个经典数据集,它记录了美国黄石国家公园老忠实间歇泉(Old Faithful geyser)的喷发数据。这个数据集经常被用于统计教学和数据分析示例。

  • faithful数据集包含两个变量,共有272个观测值。

    data = faithful
    datatable(data,rownames = FALSE)
  • eruptions: 喷发持续时间,连续数值变量,以分钟为单位,范围:1.6分钟到5.1分钟。

  • waiting: 两次喷发之间的等待时间,连续数值变量,以分钟为单位,范围:43分钟到96分钟。

2 单变量直方图

2.1 绘图要求

  • 利用geom_histogram(aes(y=..density..))绘制eruptions的直方图,使用预设主题:mytheme;

  • 利用geom_rug()为直方图添加地毯图;

  • 利用geom_density()为直方图添加核密度曲线;

  • 利用annotate()在直方图标注峰度和偏度信息;

  • 利用geom_vline() 为直方图添加一条垂直的均值参考线;

  • 利用geom_point()在横轴上添加一个中位数参考点,并在点上方添加文字注释

2.2 作图代码

library(e1071)        # 用于计算偏度系数和峰度系数

df<-data
ggplot(data = df, aes(x = eruptions)) + 
  mytheme +# 绘制直方图
  geom_histogram(aes(y = ..density..), fill = "lightgreen", color = "gray50") +
  geom_rug(size = 0.2, color = "blue3") +
  geom_density(color="blue2",size=0.7)+
  annotate("text",x=2.5,y=0.7,label="偏度系数 =",size=3)+  # 添加注释文本
  annotate("text",x=2.8,y=0.7,label=round(skewness(df$eruptions),4),size=3)+  # 添加偏度系数
  annotate("text",x=2.5,y=0.60,label="峰度系数 =",size=3)+  # 添加注释文本
  annotate("text",x=2.8,y=0.60,label=round(kurtosis(df$eruptions),4),size=3)+  # 添加峰度系数
    annotate("text",x=3.35,y=0.65,label="均值线 =",size=3)+  # 添加注释文本
  annotate("text",x=3.65,y=0.65,label=round(mean(df$eruptions),4),size=3)+  # 添加峰度系数
  geom_vline(xintercept=mean(df$eruptions),linetype="twodash",size=0.6,color="red")+ # 添加均值垂线,并设置线形、线宽和颜色
  geom_point(x=median(df$eruptions),y=0,shape=21,size=4,fill="yellow")+# 添加中位数点
  annotate("text",x=median(df$eruptions),y=0.05,label="中位数",size=3,color="red3") # 添加注释文本

2.3 图形观察和代码编写的心得体会

  • 生成了地毯图、核密度曲线、均值参考线,还标注了峰度和偏度信息,并生成了中位点添加了文本注释

  • 代码中的文本和数值不是一体的,需要按情况修改定位以契合图形

  • 通过ggplot2的图层叠加和annotate文本注释,实现了美观且信息丰富的图形展示

3 叠加直方图和镜像直方图

3.1 绘图要求

  • 绘制eruptionswaiting两个变量的叠加直方图和镜像直方图,使用预设主题:mytheme。

  • 将数据转化为长型数据再作叠加直方图,利用scale_fill_brewer()将叠加直方图配色方案改为set3

  • 镜像直方图中eruptions在正方向,waiting在负方向,直方数bins=30,并添加文字标签作标签。

  • 两种图都需要针对原始数据作图和标准标准化数据作图,可以使用scale()函数对变量标准化,分类标准化可以使用plyr::ddply()函数。

3.2 叠加直方图代码

#数据处理
df <- data |>  select(eruptions,waiting) |> 
  gather(eruptions,waiting,key=指标,value=指标值)|>   # 融合数据
  ddply("指标",transform,标准化值=scale(指标值)) # 计算标准化值并返回数据框


# 图(a)叠加直方图
p1<-ggplot(df)+aes(x=指标值,y=..density..,fill=指标)+
  geom_histogram(position="identity",color="gray60",alpha=0.5)+
  scale_fill_brewer(palette="Set3")+# 设置调色板
  theme(legend.position=c(0.8,0.8),# 设置图例位置
       legend.background=element_rect(fill="grey90",color="grey"))+
                                                # 设置图例背景色和边框颜色
  ggtitle("原始数据的叠加直方图")

p2<-ggplot(df)+aes(x=标准化值,y=..density..,fill=指标)+
  geom_histogram(position="identity",color="gray60",alpha=0.5)+
  scale_fill_brewer(palette="Set3")+# 设置调色板
  theme(legend.position=c(0.8,0.8),# 设置图例位置
       legend.background=element_rect(fill="grey90",color="grey"))+
                                                # 设置图例背景色和边框颜色
  ggtitle("标准化数据的叠加直方图")

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

3.3 镜像直方图代码

df <- data |> 
  mutate(
    std.eruptions=scale(eruptions),
    std.waiting=scale(waiting))
p1<-ggplot(df)+aes(x=x)+
   geom_histogram(aes(x=eruptions,y=..density..),color="grey50",fill="red",alpha=0.3,bins=30)+ # 绘制eruptions的直方图(上图)
   geom_label(aes(x=20,y=0.1),label="eruptions",color="red")+  # 添加标签
   geom_histogram(aes(x=waiting,y=-..density..),color="grey50",fill="blue",alpha=0.3,bins=30)+ # 绘制waiting的直方图(下图)
   geom_label(aes(x=60,y=-0.125),label="waiting",color="blue")+  # 添加标签
   xlab("指标值")+ggtitle("原始数据的镜像直方图")
p2<-ggplot(df)+aes(x=x)+
   geom_histogram(aes(x=std.eruptions,y=..density..),color="grey50",fill="red",alpha=0.3,bins=30)+ # 绘制eruptions的直方图(上图)
   geom_label(aes(x=-0.5,y=0.5),label="eruptions",color="red")+  # 添加标签
   geom_histogram(aes(x=std.waiting,y=-..density..),color="grey50",fill="blue",alpha=0.3,bins=30)+ # 绘制waiting的直方图(下图)
   geom_label(aes(x=-0.5,y=-0.5),label="waiting",color="blue")+  # 添加标签
   xlab("指标值")+ggtitle("标准化数据的镜像直方图")

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

3.4 图形观察和代码编写的心得体会

  • 叠加直方图:通过在同一坐标轴上绘制多个类别的直方图,便于比较不同类别变量的分布差异,但重叠区域较多时可能不易辨识。

  • 镜像直方图:将两个类别的直方图上下对称显示,有效解决了重叠干扰的问题,使得分布差异更加直观

  • 图层控制与分组变量设置:叠加图通常使用position = "identity"来控制条形显示方式,镜像图则需要对数据进行适当变换,通过y=-..density..将一组取反。

  • 配色与透明度设置:通过调整fill颜色和alpha透明度,增强了图形的可读性,避免重叠部分信息丢失。

4 核密度图

4.1 绘图要求

  • 绘制eruptions和 waiting两个变量的分组核密度图、分面核密度图和镜像核密度图。

  • 分组核密度图,采用geom_density(position="identity")

  • 分面核密度图,采用geom_density()+facet_wrap(~xx,scale="free")

  • 镜像核密度图中eruptions在正方向,waiting在负方向,直方数bins=30,并添加文字标签作标签。

  • 分组核密度图和镜像核密度图需要针对原始数据作图和标准标准化数据作图。

4.2 分组核密度图

#数据处理
df <- data |>  select(eruptions,waiting) |> 
  gather(eruptions,waiting,key=指标,value=指标值)|>   # 融合数据
  ddply("指标",transform,标准化值=scale(指标值)) # 计算标准化值并返回数据框


# 图(a)叠加直方图
p1<-ggplot(df)+aes(x=指标值,y=..density..,fill=指标)+
  geom_density(position="identity",color="gray60",alpha=0.5)+
  scale_fill_brewer(palette="Set3")+# 设置调色板
  theme(legend.position=c(0.8,0.8),# 设置图例位置
       legend.background=element_rect(fill="grey90",color="grey"))+
                                                # 设置图例背景色和边框颜色
  ggtitle("原始数据的叠加直方图")

p2<-ggplot(df)+aes(x=标准化值,y=..density..,fill=指标)+
  geom_density(position="identity",color="gray60",alpha=0.5)+
  scale_fill_brewer(palette="Set3")+# 设置调色板
  theme(legend.position=c(0.8,0.8),# 设置图例位置
       legend.background=element_rect(fill="grey90",color="grey"))+
                                                # 设置图例背景色和边框颜色
  ggtitle("标准化数据的叠加直方图")

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

4.3 分面核密度图

p1<-ggplot(df)+aes(x=指标值,y=..density..,fill=指标)+
  geom_density(position="identity",color="gray60",alpha=0.5)+
  scale_fill_brewer(palette="Set3")+# 设置调色板
  facet_wrap(~指标,scale="free")+
  guides(fill="none")+
  theme(legend.position=c(0.8,0.8),# 设置图例位置
       legend.background=element_rect(fill="grey90",color="grey"))
p1

4.4 镜像核密度图

df <- data |> 
  mutate(
    std.eruptions=scale(eruptions),
    std.waiting=scale(waiting))
p1<-ggplot(df)+aes(x=x)+
   geom_density(aes(x=eruptions,y=..density..),color="grey50",fill="red",alpha=0.3,bins=30)+ # 绘制eruptions的直方图(上图)
   geom_label(aes(x=20,y=0.1),label="eruptions",color="red")+  # 添加标签
   geom_density(aes(x=waiting,y=-..density..),color="grey50",fill="blue",alpha=0.3,bins=30)+ # 绘制waiting的直方图(下图)
   geom_label(aes(x=60,y=-0.125),label="waiting",color="blue")+  # 添加标签
   xlab("指标值")+ggtitle("原始数据的镜像直方图")
p2<-ggplot(df)+aes(x=x)+
   geom_density(aes(x=std.eruptions,y=..density..),color="grey50",fill="red",alpha=0.3,bins=30)+ # 绘制eruptions的直方图(上图)
   geom_label(aes(x=-0.5,y=0.5),label="eruptions",color="red")+  # 添加标签
   geom_density(aes(x=std.waiting,y=-..density..),color="grey50",fill="blue",alpha=0.3,bins=30)+ # 绘制waiting的直方图(下图)
   geom_label(aes(x=-0.5,y=-0.5),label="waiting",color="blue")+  # 添加标签
   xlab("指标值")+ggtitle("标准化数据的镜像直方图")

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

4.5 图形观察和代码编写的心得体会

  • 分组核密度图:通过不同颜色在同一图中展示多个组的密度曲线,直观对比各组的分布差异,但曲线重叠较多时需注意可读性。
  • 分面核密度图:利用facet_wrap()facet_grid()将每个组的密度图单独展示,避免重叠,利于逐一分析各组的分布特征。
  • 镜像核密度图:通过上下镜像的方式展示两组分布,能清晰看出两组在密度、集中趋势等方面的差异,视觉冲击力较强。

  • 分组密度图:借助aes(fill=group, color=group)geom_density(alpha=0.5)实现颜色区分和透明度控制

  • 分面密度图:使用facet_wrap(~group)可以快速分组绘图,无需担心曲线重叠,代码简洁且易于扩展到多组数据。
  • 镜像密度图:需人为对某一组的密度值取负(y=-..density..),并手动设置y轴或对称坐标,使其镜像显示,逻辑稍复杂但图形效果明显。

5 箱线图和小提琴图

5.1 绘图要求

  • 根据实际数据和标准化后的数据绘制eruptionswaiting两个变量的箱线图geom_boxplot和小提琴图geom_violin

  • 采用stat_summary(fun="mean",geom="point")在箱线图和均值图中要添加均值点。

  • 小提琴图中要加入点图和箱线图

  • 采用调色板前两种颜色,brewer.pal(6,"Set2")[1:2] ,作为箱体填充颜色。

"#66C2A5" "#FC8D62" "#8DA0CB" "#E78AC3" "#A6D854" "#FFD92F"

5.2 箱线图代码

#数据处理
df<-data |>
  gather(eruptions,waiting,key=指标,value=指标值) |>  # 融合数据,将宽数据转为长格式
  ddply("指标",transform,标准化值=scale(指标值))    # 计算标准化值,分组计算后自动合并结果,保持数据结构完整

palette<-brewer.pal(6,"Set2")[1:2]          # 设置离散型调色板

p1<-ggplot(df,aes(x=指标,y=指标值))+
  geom_boxplot(fill=palette)+      # 绘制箱线图并设置填充颜色
  stat_summary(fun="mean",geom="point",shape=21,size=2.5,fill="white")+
  ggtitle("(a) 原始数据箱线图")
p2<-ggplot(df,aes(x=指标,y=标准化值))+
  geom_boxplot(fill=palette)+  # 绘制箱线图并设置填充颜色
  stat_summary(fun="mean",geom="point",shape=21,size=2.5,fill="white")+
ggtitle("(b) 标准化数据箱线图")

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

5.3 小提琴图代码

  • 通过d3r::d3_nest将数据框转化为层次数据“d3.js”作为绘图输入
#数据处理
df<-data |>
  gather(eruptions,waiting,key=指标,value=指标值) |>  # 融合数据,将宽数据转为长格式
  ddply("指标",transform,标准化值=scale(指标值))    # 计算标准化值,分组计算后自动合并结果,保持数据结构完整

# 转换为D3嵌套格式
d3_data <- d3r::d3_nest(df, root = "data", value_cols = c("指标值", "标准化值"))

# 图(a)原始数据小提琴图
p1<-ggplot(df,aes(x=指标,y=指标值,fill=指标))+
     geom_violin(scale="width",trim=FALSE)+
     geom_point(color="black",size=0.8)+  # 添加点
     geom_boxplot(outlier.size=0.7,outlier.color="white",size=0.3,
               width=0.2,fill="white")+  # 添加并设置箱线图和离群点参数
     scale_fill_brewer(palette="Set2")+
     stat_summary(fun=mean,geom="point",shape=21,size=2)+# 添加均值点
     guides(fill="none")+
     ggtitle("(a) 原始数据小提琴图")

# 图(b)数据标准化后的小提琴图
p2<-ggplot(df,aes(x=指标,y=标准化值,fill=指标))+
     geom_violin(scale="width",trim=FALSE)+
     geom_point(color="black",size=0.8)+  # 添加点
     geom_boxplot(outlier.size=0.7,outlier.color="white",size=0.3,
               width=0.2,fill="white")+  # 添加并设置箱线图和离群点参数
     scale_fill_brewer(palette="Set2")+
     stat_summary(fun=mean,geom="point",shape=21,size=2)+# 添加均值点
     guides(fill="none")+
     ggtitle("(a) 标准化小提琴图")

gridExtra::grid.arrange(p1,p2,ncol=2)        # 组合图形p1和p2

5.4 图形观察和代码编写的心得体会

  • 箱线图:直观展示了数据的中位数、四分位数、异常值等,适合快速了解数据的集中趋势与离散程度,是经典的分布可视化工具。
  • 小提琴图:在箱线图基础上结合了密度分布的形状信息,既展示了数据的中心与离群点,又提供了整体分布的对称性和多峰特征。

  • 箱线图绘制:使用geom_boxplot(),可搭配aes(fill=group)区分不同组,添加outlier.shape参数可定制异常值显示形式。

  • 小提琴图绘制:使用geom_violin(),可配合geom_boxplot(width = 0.2)叠加箱线信息,实现信息更丰富的视觉效果。

6 威尔金森点图、蜂群图和云雨图

6.1 绘图要求

  • 绘制eruptionswaiting 两个变量的威尔金森点图、蜂群图和云雨图。

  • 三种图形均采用标准化数据作图

  • 威尔金森点图采用geom_dotplot(binaxis="y",bins=30,dotsize = 0.3) ,要求作出居中堆叠和向上堆叠两种情况的图。

  • 蜂群图采用geom_beeswarm(cex=0.8,shape=21,size=0.8),要求作出不带箱线图和带有箱线图两种情况的图。

  • 云雨图采用geom_violindot(dots_size=0.7,binwidth=0.07) ,要求作出横向和纵向图两种情况的图。

6.2 威尔金森点图代码

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

mytheme<-theme_bw()+theme(legend.position="none")
#数据处理
df<-data |>
  gather(eruptions,waiting,key=指标,value=指标值) |>  # 融合数据
  ddply("指标",transform,标准化值=scale(指标值))    # 计算标准化值


p<-ggplot(df,aes(x=指标,y=标准化值,fill=指标))
p1<-p+geom_dotplot(binaxis="y",binwidth=0.075,stackdir="center")+ # 绘制点图
  mytheme+ggtitle("(a) 居中堆叠")

p2<-p+geom_dotplot(binaxis="y",binwidth=0.075)+ # 绘制点图
  mytheme+ggtitle("(b) 向上堆叠")

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

6.3 蜂群图代码

mytheme<-theme_bw()+theme(legend.position="none")
#数据处理
df<-data |>
  gather(eruptions,waiting,key=指标,value=指标值) |>  # 融合数据
  ddply("指标",transform,标准化值=scale(指标值))    # 计算标准化值

# 图(a)5项指标的蜂群图
mytheme<-theme_bw()+theme(legend.position="none")
p<-ggplot(df,aes(x=指标,y=标准化值))
p1<-p+geom_beeswarm(cex=1,shape=21,fill="black",size=0.8,aes(color=指标))+# 设置蜂群的宽度、点的形状、大小和填充颜色
mytheme+ggtitle("(a) 蜂群图")

# 图(b)箱线图+蜂群图
p2<-p+geom_boxplot(size=0.7,outlier.size=1,aes(color=指标))+
geom_beeswarm(shape=21,cex=1,size=1,aes(color=指标))+
mytheme+ggtitle("(b) 箱线图+蜂群图")

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

6.4 云雨图代码

library(see)  # 提供主题函数theme_modern
mytheme<-theme_modern()+
         theme(legend.position="none",
               plot.title=element_text(size=14,hjust=0.5))   # 调整标题位置
#数据处理
df<-data |>
  gather(eruptions,waiting,key=指标,value=指标值) |>  # 融合数据
  ddply("指标",transform,标准化值=scale(指标值))    # 计算标准化值

p1<-ggplot(df,aes(x=指标,y=标准化值,fill=指标))+
  geom_violindot(dots_size=1,binwidth=0.07)+ # 绘制云雨图并设置点的大小和箱宽
  mytheme+ggtitle("(a) 垂直排列(默认)")

p2<-ggplot(df,aes(x=指标,y=标准化值,fill=指标))+
  geom_violindot(dots_size=1,binwidth=0.06)+
  coord_flip()+mytheme+ggtitle("(b) 水平排列")

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

6.5 图形观察和代码编写的心得体会

  • 威尔金森点图:将每个数据点以紧凑方式堆叠显示,能够清晰反映每个观测值的位置,适用于样本量较小时的精确展示。
  • 蜂群图:通过geom_beeswarm()geom_quasirandom()排列数据点,避免重叠,展示密度分布同时保留离散结构,适合中等规模数据。
  • 云雨图(Raincloud Plot):结合小提琴图、箱线图与散点图于一体,既展示分布形态,又呈现数据离散程度,是现代化、信息量极大的可视化方式。
  • 威尔金森点图:可通过geom_dotplot()实现,参数如stackdir="center"binaxis="y"控制点堆叠方向与轴线,适合精细对齐。
  • 蜂群图:需加载扩展包如ggbeeswarm,使用geom_beeswarm()geom_quasirandom(),可以调节groupOnXcex等参数优化点间间距。
  • 云雨图:一般通过多个图层叠加(如geom_violin() + geom_boxplot() + geom_jitter()),也可使用现成函数如ggraincloud(需引入自定义模板或包),但需要对图层顺序和透明度精细控制。