第四章 数据分布可视化

Author

221527109付楚妍

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")+    # 添加地毯图,须线的宽度为0.2
  geom_density(color="blue2",size=0.7)+ # 添加核密度曲线
  annotate("text",x=2.5,y=0.7,label=paste0("偏度系数 = ",round(skewness(df$eruptions),4)),size=3)+  # 添加注释文本
  annotate("text",x=2.5,y=0.65,label=paste0("峰度系数 = ",round(kurtosis(df$eruptions),4)),size=3)+  # 添加注释文本
  geom_vline(xintercept=mean(df$eruptions),linetype="twodash",size=0.6,color="red")+          # 添加均值垂线,并设置线形、线宽和颜色
  annotate("text",x=mean(df$eruptions),y=0.7,label=paste0("均值线= ",round(mean(df$eruptions),3)),size=3)+  # 添加注释文本
  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 图形观察和代码编写的心得体会

  • 均值线(Mean)3.488

    • 数据的平均喷发时间为 3.488 分钟。
  • 中位数(Median)

    • 中位数和均值的比较可以反映数据偏斜方向
  • 偏度系数(Skewness)-0.4135

    • 负偏度(左偏),说明数据分布左侧(较小值)有更长的尾巴,即更多短喷发时间的数据点。

    • 但偏度绝对值较小(接近 0),偏离对称性不显著。

  • 峰度系数(Kurtosis)-1.5116

    • 负峰度(低峰态),说明数据分布比正态分布更平坦,极端值较少,数据更分散。

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

3.1 绘图要求

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

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

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

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

3.2 叠加直方图代码

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

mytheme<-theme(plot.title=element_text(size="12"), # 设置主标题字体大小
   axis.title=element_text(size=10),               # 设置坐标轴标签字体大小
   axis.text=element_text(size=9),                # 设置坐标轴刻度字体大小
   legend.text=element_text(size="8"))            # 设置图例字体大小

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("(a) 原始数据的叠加直方图")

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("(b) 标准化数据的叠加直方图")

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

3.3 镜像直方图代码

std.eruptions=scale(data$eruptions)
std.waiting=scale(data$waiting)

mytheme<-theme(plot.title=element_text(size="12"), # 设置主标题字体大小
   axis.title=element_text(size=10),               # 设置坐标轴标签字体大小
   axis.text=element_text(size=9),                # 设置坐标轴刻度字体大小
   legend.text=element_text(size="8"))            # 设置图例字体大小

# 图(a)镜像直方图
p1<-ggplot(data)+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=50,y=-0.075),label="waiting",color="blue")+  # 添加标签
   xlab("指标值")+ggtitle("(a) 原始数据的镜像直方图")

# 图(b)镜像直方图
p2<-ggplot(data)+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=20,y=0.1),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=50,y=-0.075),label="waiting",color="blue",bins=30)+  # 添加标签
   xlab("指标值")+ggtitle("(b) 标准化数据的镜像直方图")

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

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

  • 叠加直方图:

    横轴(指标):表示原始数据的实际值范围

    纵轴(density):表示概率密度,反映数据在不同区间的集中程度。

    横轴(标准化值):表示经过标准化后的数值,标准化消除了原始数据的量纲差异,使得两组数据可直接比较分布形状。

    纵轴(density):概率密度

  • 镜像直方图:图表通过对称镜像的方式,将两组数据分别显示在中央轴的两侧,便于直观比较它们的频数或密度分布。左侧是eruptions的分布,右侧是waiting的镜像分布。原始数据:展示未处理的数据分布。标准化数据:通过标准化(如Z-score)消除量纲影响,突出分布形状的差异。

4 核密度图

4.1 绘图要求

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

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

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

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

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

4.2 分组核密度图

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

p1<-ggplot(df)+aes(x=指标值,y=..density..,fill=指标)+
   geom_density(position="identity",color="gray50",alpha=0.5)+
   scale_fill_brewer(palette="Set3")+           # 设置调色板
   mytheme+
   theme(legend.position="bottom")+
   guides(fill=guide_legend(title=NULL))+# 去掉图例标题
   scale_fill_discrete(labels=function(x) str_wrap(x,width=4))+ # 设置图例标签宽度
   ggtitle("(a)原始数据的分组核密度图")

p2<-ggplot(df)+aes(x=标准化值,y=..density..,fill=指标)+
   geom_density(position="identity",color="gray50",alpha=0.5)+
   scale_fill_brewer(palette="Set3")+           # 设置调色板
   mytheme+
   theme(legend.position="bottom")+
   guides(fill=guide_legend(title=NULL))+# 去掉图例标题
   scale_fill_discrete(labels=function(x) str_wrap(x,width=4))+ # 设置图例标签宽度
   ggtitle("(b)标准化数据的分组核密度图")

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

4.3 分面核密度图

df <- data |>  
  gather(eruptions,waiting,key=指标,value=指标值) #融合数据
 
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")+  # 按指标3列分面
  guides(fill="none")+
  theme(legend.position=c(0.8,0.8), 
        legend.background = element_rect(fill = "grey90",color = "grey"))  #设置图例位置、背景和边框                    

4.4 镜像核密度图

df<-data%>%
  mutate(
    std.eruptions=scale(eruptions),
    std.waiting=scale(waiting)
  )
# 图(a)eruption和waiting的镜像核密度图
p1<-ggplot(df,aes(x=x))+
   geom_density(aes(x=eruptions,y=..density..),fill="red",alpha=0.3,bins=30)+ # 绘制eruption的核密度图(上图)
   geom_label(aes(x=20,y=0.1),label="eruptions",color="red")+  # 添加标签
   geom_density(aes(x=waiting,y=-..density..),fill="blue",alpha=0.3,bins=30)+ # 绘制waiting的核密度图(下图)
   geom_label(aes(x=60,y=-0.075),label="waiting",color="blue")+
   xlab("指标值")+ggtitle("(a) 原始数据的镜像核密度图")

p2<-ggplot(df,aes(x=x))+
   geom_density(aes(x=std.eruptions,y=..density..),fill="red",alpha=0.3,bins=30)+ # 绘制eruption的核密度图(上图)
   geom_label(aes(x=-0.5,y=0.5),label="eruptions",color="red")+  # 添加标签
   geom_density(aes(x=std.waiting,y=-..density..),fill="blue",alpha=0.3,bins=30)+ # 绘制waiting的核密度图(下图)
   geom_label(aes(x=-0.5,y=-0.05),label="waiting",color="blue")+
   xlab("指标值")+ggtitle("(b) 标准化数据的镜像核密度图")
grid.arrange(p1,p2,ncol=2)

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

  • 分组核密度图:(a) 原始数据的分组核密度图

    • 横轴(指标值)

      • 表示原始数据的实际范围,对应时间单位。

      • eruptions(喷发时间)和 waiting(间歇时间)的数值分布直接显示。

    • 纵轴(density):概率密度值,峰值越高表示数据越集中。

    • 分布形态

      • eruptions:若峰值靠近左侧,表明喷发时间普遍较短;若右侧拖尾,则存在少量长时间喷发。

      • waiting:若峰值在右侧,说明间歇时间较长;分布宽度反映时间波动性。

        (b) 标准化数据的分组核密度图

    • 横轴(标准化值):数据经过标准化,消除了原始量纲差异。

    • 纵轴(density):与子图(a)一致,但分布形状更纯粹反映统计特性。

  • 分面核密度图:峰值位置:每个子图中的密度峰值反映该分组中数据最集中的区域。

    分布形状:多峰性。

    数据范围:分布的宽度(方差)展示数据的离散程度。

  • 镜像核密度图:(a)图:横轴(指标值):显示原始数据的实际范围。

    • eruptions的峰值更高(密度≈0.4),表明数据更集中;waiting的分布更平缓(密度≈0.1)。

    • 两者均为右偏分布(右侧尾部较长),可能暗示存在少数高值异常点。

      (b)组:横轴(指标值):显示标准化后的数据。

    • 两变量的峰值接近(密度≈0.6),表明标准化后集中程度相似。

    • eruptions的分布更陡峭,可能反映原始数据的方差较小;waiting的分布略宽。

    • 偏态仍存在但被缩放,说明标准化未完全消除分布形态差异。

    • 两变量在部分区间(如10-15)有重叠,但整体分布差异显著。

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<-RColorBrewer::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")+
  xlab("指标值")+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")+
  xlab("指标值")+ggtitle("(b) 标准化数据的箱线图")
                                                   # 添加均值点
grid.arrange(p1,p2,ncol=2)

5.3 小提琴图代码

  • 通过d3r::d3_nest将数据框转化为层次数据“d3.js”作为绘图输入
df <- data |>  
  gather(eruptions,waiting,key=指标,value=指标值)%>% #融合数据
  ddply("指标",transform,标准化值=scale(指标值))#计算标准化并返回数据框

# 图(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")+
     #geom_point(color="black",size=1)+
     geom_boxplot(,outlier.size=0.7,outlier.color="black",size=0.3,
          width=0.2,fill="white")+
     scale_fill_brewer(palette="Set2")+
     guides(fill="none")+
     ggtitle("(b) 标准化小提琴图")

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

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

  • 箱线图:中位数(箱体内的线):反映数据的中心位置。

    四分位数(箱体边界):

    • Q1(第25百分位,箱体下端)

    • Q3(第75百分位,箱体上端)

    • 四分位距(IQR = Q3 - Q1):箱体高度代表数据的离散程度。

  • 小提琴图:eruptions:分布可能集中在较低值(左侧),右侧尾部较长,表明存在右偏(少数高值)。

    waiting:分布范围更广(如横跨0到90),可能呈现近似对称或轻微左偏。

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(指标值))#计算标准化并返回数据框

# 绘制图形
mytheme<-theme_bw()+theme(legend.position="none")
p<-ggplot(df,aes(x=指标,y=标准化值,fill=指标))
p1<-p+geom_dotplot(binaxis="y",bins=30,dotsize = 0.3,stackdir="center")+ # 绘制点图
  mytheme+ggtitle("(a) 居中堆叠")

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

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

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=0.8,shape=21,fill="black",size=0.8,aes(color=指标))+# 设置蜂群的宽度、点的形状、大小和填充颜色
mytheme+ggtitle("(a) 蜂群图")

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

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

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=0.7,binwidth=0.07)+ # 绘制云雨图并设置点的大小和箱宽
  mytheme+ggtitle("(a) 垂直排列(默认)")

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

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

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

  • 威尔金森点图:横轴表示数据值,纵轴表示点的堆叠高度(无实际数值意义,仅避免重叠)。每个数据点用一个圆点表示,相同值时会垂直堆叠。优点:保留原始数据细节,避免分箱偏差。直观显示数据密度和离群值。缺点:数据量大时点会重叠。

  • 蜂群图:蜂群图通过将数据点沿一条轴(通常是横轴或纵轴)分散排列,避免重叠,直观显示数据的密集区域和稀疏区域。密集区域:数据点堆积较多,表示该区间内数值出现频率高。稀疏区域:数据点分散,表示该区间数值出现频率低。数据点的纵向分布范围反映了数据的离散程度。

  • 云雨图:通过小提琴图的宽度展示数据的概率密度分布,可以直观看出数据的集中区域、偏态或多峰分布。底部的散点显示每个数据点的实际值。传统箱线图会隐藏数据分布形态,而小提琴图可能掩盖个体数据,云雨图结合二者优点。