第四章 数据分布可视化

Author

学号+姓名

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="blue")+
  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),2)),size=3)+
  geom_point(x=median(df$eruptions),y=0,shape=21,size=4,fill="yellow")+
  annotate("text",x=median(df$eruptions),y=0.1,label="中位数",size=3,color="red3")

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

  1. 数据分布特征

    • 图形显示的数据可能呈现右偏分布(偏度系数=0.4135 > 0),即右侧尾部较长,少数值较大。

    • 峰度系数=1.5116 > 0,表明数据分布比正态分布更陡峭,尾部更厚,可能存在异常值或集中趋势。

    • 均值线标注为3.49,结合横轴标签“eruptions”(可能指火山喷发持续时间),说明平均喷发时间约为3.49分钟。

  2. 图形形态

    • 纵轴从0.0到0.8,可能表示频率或密度(如直方图或密度图)。横轴为“eruptions”的数值范围(2到5)。

    • 图形可能为右偏的单峰分布,峰值在3附近(“中间数”或“中心数”可能指众数或中位数)。

  3. 标签提示

    • “中间数”“中心数”可能分别指中位数和众数,需与均值(3.49)对比分析数据的对称性。

    • 若中位数 < 均值,进一步验证右偏性。

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(指标值))

p1<-ggplot(df)+aes(x=指标值,y=..density..,fill=指标)+
  geom_histogram(position="identity",color="grey60",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)原始数据的叠加直方图")
List of 4
 $ legend.background     :List of 5
  ..$ fill         : chr "grey90"
  ..$ colour       : chr "grey"
  ..$ linewidth    : NULL
  ..$ linetype     : NULL
  ..$ inherit.blank: logi FALSE
  ..- attr(*, "class")= chr [1:2] "element_rect" "element"
 $ legend.position       : chr "inside"
 $ legend.position.inside: num [1:2] 0.8 0.8
 $ title                 : chr "(a)原始数据的叠加直方图"
 - attr(*, "class")= chr [1:2] "theme" "gg"
 - attr(*, "complete")= logi FALSE
 - attr(*, "validate")= logi TRUE
p2<-ggplot(df)+aes(x=标准化值,y=..density..,fill=指标)+
  geom_histogram(position="identity",color="grey60",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)标准化数据的叠加直方图")
List of 4
 $ legend.background     :List of 5
  ..$ fill         : chr "grey90"
  ..$ colour       : chr "grey"
  ..$ linewidth    : NULL
  ..$ linetype     : NULL
  ..$ inherit.blank: logi FALSE
  ..- attr(*, "class")= chr [1:2] "element_rect" "element"
 $ legend.position       : chr "inside"
 $ legend.position.inside: num [1:2] 0.8 0.8
 $ title                 : chr "(a)标准化数据的叠加直方图"
 - attr(*, "class")= chr [1:2] "theme" "gg"
 - attr(*, "complete")= logi FALSE
 - attr(*, "validate")= logi TRUE
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..),fill="red",alpha=0.3,bins=30)+
  geom_label(aes(x=20,y=0.1),label="eruptions",color="red")+
  geom_histogram(aes(x=waiting,y=..density..),fill="blue",alpha=0.3,bins=30)+
  geom_label(aes(x=60,y=0.075),label="waiting",color="blue")+
  xlab("指标值")+ggtitle("(a)原始数据镜像密度图")

p2<-ggplot(df,aes(x=x))+
  geom_histogram(aes(x=std.eruptions,y=..density..),fill="red",alpha=0.3,bins=30)+
  geom_label(aes(x=-0.5,y=0.5),label="eruptions",color="red")+
  geom_histogram(aes(x=std.waiting,y=..density..),fill="blue",alpha=0.3,bins=30)+
  geom_label(aes(x=-0.5,y=-0.5),label="waiting",color="blue")+
  xlab("指标值")+ggtitle("(a)标准化数据镜像密度图")

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

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

  1. 图形类型与内容

    • 图中包含多个子图,可能为核密度估计(KDE)图直方图,纵轴标注“density”(密度),横轴为“eruptions”和“waiting”两个指标。

    • 第一组子图(上部分)的密度范围在0.2到0.3之间,第二组子图(中部分)的密度范围在0.5到0.75之间,可能表示不同指标或不同数据集的分布。

    • 最下方的子图横轴为“标准化值”(-1到2),纵轴为“指标值”(0到100),可能展示标准化后的数据分布或分位数图(如QQ图)。

  2. 分布特征

    • “eruptions”和“waiting”

      • 密度峰值位置不同,表明两个指标的集中趋势存在差异(如“waiting”的持续时间可能更长)。

      • 若密度曲线右尾较长,可能暗示右偏分布(与前一文件中的偏度系数=0.4135一致)。

    • 标准化值子图

      • 标准化后的数据集中在-1到2之间,且指标值从0到100均匀分布,可能用于验证数据是否符合正态分布(如QQ图)。
  3. 潜在信息

    • 多子图对比可能用于分析“eruptions”(喷发持续时间)和“waiting”(两次喷发的间隔时间)的关系,或检查数据标准化后的正态性。

      3.4.1 心得体会:

      1. 图形解读

        • 多子图布局能高效对比不同指标的分布特征,适合探索性数据分析(EDA)。

        • 标准化子图需结合统计检验(如Shapiro-Wilk)判断正态性,避免仅依赖视觉判断。

      2. 代码优化方向

        • 若数据量较大,可使用seaborn.FacetGrid分面绘制多个分布图。

        • 添加交互式工具(如plotly)动态探索数据分布。

      3. 实际应用

        • 对于火山喷发数据(如Old Faithful数据集),分析“eruptions”和“waiting”的关系可预测喷发模式。

        • 右偏分布提示需谨慎使用均值作为代表值,建议结合中位数和四分位数描述。

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="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("(a) 标准化数据的叠加直方图")            # 添加标题

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

4.3 分面核密度图

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列分面
  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)
  )
p_waiting <- ggplot(df, aes(x = std.waiting)) +
  geom_density(fill = "skyblue", alpha = 0.7, color = NA) +  # 原数据
  geom_density(aes(x = -std.waiting), fill = "salmon", alpha = 0.7, color = NA) +  # 镜像数据
  labs(title = "Mirror Density Plot: std.waiting",
       x = "Standardized Waiting Time",
       y = "Density") +
  theme_minimal()

# 2. 对std.eruptions绘制镜像核密度图
p_eruptions <- ggplot(df, aes(x = std.eruptions)) +
  geom_density(fill = "lightgreen", alpha = 0.7, color = NA) +  # 原数据
  geom_density(aes(x = -std.eruptions), fill = "orchid", alpha = 0.7, color = NA) +  # 镜像数据
  labs(title = "Mirror Density Plot: std.eruptions",
       x = "Standardized Eruption Duration",
       y = "Density") +
  theme_minimal()

# 并排显示两个图(需安装patchwork包)
library(patchwork)
p_waiting + p_eruptions

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

分组核密度图

  1. 图形类型与内容

    • 图中包含两个子图,均为叠加直方图,分别展示原始数据和标准化后的数据分布。

    • 原始数据子图

      • 横轴为“eruptions”和“waiting”两个指标,纵轴为“density”(密度),范围0.0到0.4。

      • 两个指标的密度分布重叠显示,可能通过颜色区分(图中未明确,需假设)。

    • 标准化数据子图

      • 横轴为标准化后的“指标值”(0到100),纵轴为“density”,范围0.0到0.4。

      • 分布形态与原始数据子图类似,但数值范围经过标准化处理(如Z-score或Min-Max标准化)。

  2. 分布特征

    • 原始数据

      • “eruptions”和“waiting”的密度峰值位置不同,表明两者的集中趋势不同(如“waiting”可能集中在更高值区域)。

      • 若直方图右尾较长,可能暗示右偏分布(与之前观察的偏度系数一致)。

    • 标准化数据

      • 标准化后,两指标的分布形态更易直接对比,但保留原始数据的偏态或峰态特征。

      • 横轴标注“指标值”为0到100,可能采用Min-Max标准化(缩放到[0,100]区间)。

  3. 潜在信息

    • 叠加直方图的设计适合对比两指标的分布差异,但需确保颜色或图例清晰区分。

    • 标准化子图可能用于验证数据缩放效果,或为后续模型训练(如聚类、回归)做准备。

      分面核密度图

      1. 图形类型与结构

        • 图中包含三个子图或三个部分,分别标注为 graphendpointswaiting

        • graph 部分的纵轴范围为 0.0 到 0.5,可能表示某种密度或频率分布。

        • endpointswaiting 部分的纵轴范围较小(0.00 到 0.03),横轴范围均为 50 到 90,可能表示某种指标的分布或时间序列数据。

      2. 数据分布特征

        • graph 部分的分布较为平缓,峰值可能在 0.2 到 0.3 之间,可能对应某种全局数据的密度分布。

        • endpointswaiting 部分的分布较为集中,峰值较低(0.01 到 0.02),可能表示局部数据或特定条件下的分布。

        • waiting 部分的标签为“指标”,可能表示某种等待时间或延迟时间的分布。

      3. 潜在信息

        • 图形可能用于对比全局数据(graph)与局部数据(endpoints 和 waiting)的分布差异。

        • endpointswaiting 的横轴范围一致(50 到 90),可能表示两者在同一尺度下的对比。

          镜像核密度图

          1. std.waiting 分布

            • 密度峰值在 -0.5 到 0 之间(可能是原始数据)

            • 镜像部分(红色)在 0 到 0.5 之间对称出现

            • 整体范围覆盖 -2 到 2 个标准差

          2. std.eruptions 分布

            • 主峰高度约 -0.4(原始数据)

            • 镜像峰高度约 0.4

            • 分布范围 -1 到 1 标准差,比waiting更集中

          3. 对称性对比

            • waiting的镜像对称性较好,两侧曲线形状接近

            • eruptions的原始分布和镜像分布存在轻微不对称(-0.4 vs 0.4)

              4.5.1 关键收获

              1. 数据理解:镜像图能直观揭示分布的偏态特征

              2. 技术实现:ggplot2的图层叠加非常灵活强大

              3. 分析思维:可视化+统计量结合(图形观察后建议用skewness()计算验证)

              这种分析方法特别适用于需要检验数据对称性的场景(如线性模型的正态性假设检查)。

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 箱线图代码

mytheme<-theme(
  plot.title = element_text(size = 11, hjust = 0.5), 
  axis.title = element_text(size = 10),               
  axis.text = element_text(size = 9),                
  legend.text = element_text(size = 8),
  legend.position = "bottom"
)
# 准备数据
df <- data %>%
  gather(key = "指标", value = "指标值") %>%
  mutate(指标 = fct_inorder(指标))

# 设置调色板(使用Set2的前两种颜色)
palette <- RColorBrewer::brewer.pal(6, "Set2")[1:2]

# 绘制箱线图
ggplot(df, aes(x = 指标, y = 指标值, fill = 指标)) +
  geom_boxplot(alpha = 0.7) +                 # 绘制箱线图并设置透明度
  stat_summary(fun = "mean", geom = "point",  # 添加均值点
               shape = 21, size = 2.5, fill = "white") +
  scale_fill_manual(values = palette) +      # 设置填充颜色
  labs(
    title = "火山喷发数据箱线图",
    x = "变量",
    y = "值"
  ) +
  mytheme                                

5.3 小提琴图代码

  • 通过d3r::d3_nest将数据框转化为层次数据“d3.js”作为绘图输入
ggplot(data = df, aes(x = 指标, y = 指标值, fill = 指标)) +
  geom_violin(alpha = 0.7) +
  geom_boxplot(width = 0.1, alpha = 0.7) +
  geom_point(alpha = 0.3, size = 1) +
  stat_summary(fun = "mean", geom = "point",  
               shape = 21, size = 2.5, fill = "white") +
  scale_fill_manual(values = palette) +
  labs(
    title = "火山喷发数据小提琴图",
    x = "变量",
    y = "值"
  ) +
  mytheme

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

箱线图

  1. eruptions变量

    • 中位数大约在4分钟左右

    • 数据分布较为集中,四分位距(IQR)较小

    • 存在较多上边缘的离群值(上方的圆圈点)

    • 整体喷发持续时间在1.5-5.5分钟之间

  2. waiting变量

    • 中位数大约在75-80分钟之间

    • 数据分布比eruptions更分散

    • 存在上下边缘的离群值

    • 主要数据范围在40-95分钟之间

      心得体会

      1. 数据理解:箱线图是展示数据分布特征的有效工具,能直观显示中位数、四分位数和离群值。

      2. 可视化选择:对于连续变量的分布比较,箱线图比直方图或密度图更节省空间且便于比较。

      3. 离群值处理:图中显示的离群值可能需要进一步分析,决定是否保留或处理。

      4. 图形美化:可以添加颜色、调整坐标轴标签使图形更易读,如示例代码所示。

      5. 多变量展示:当比较不同变量的分布时,确保它们使用相同的y轴尺度或明确指出尺度差异很重要。

小提琴图

从提供的小提琴图来看,这是关于火山喷发数据中eruptions(喷发持续时间)和waiting(喷发间隔时间)两个变量的可视化展示:

  1. eruptions变量

    • 分布呈双峰形态,表明可能存在两种不同类型的喷发模式

    • 主要峰值集中在1.5-2分钟和4-4.5分钟附近

    • 整体分布范围在1-5分钟之间

    • 密度在3分钟附近有明显低谷

  2. waiting变量

    • 分布也呈现双峰特征,与eruptions对应

    • 主要峰值在50-55分钟和80-85分钟两个区间

    • 整体分布范围在40-100分钟之间

    • 密度在65-75分钟区间较低

  3. 两变量关系

    • 两个变量的双峰分布暗示可能存在某种关联性

    • 等待时间短的喷发往往持续时间也短,反之亦然

      心得体会

      1. 可视化选择:小提琴图结合了箱线图和密度图的优点,能同时展示数据的分布形状和统计量,特别适合揭示多峰分布。

      2. 数据转换:使用pivot_longer将数据从宽格式转为长格式是ggplot2绘制多变量比较图的常用技巧。

      3. 图形增强

        • 添加半透明填充色(alpha)提高美观性

        • 内置boxplot补充显示具体统计量

        • 移除图例避免冗余(当x轴已明确标注时)

      4. 分布解读:双峰分布暗示数据可能存在潜在分组,后续可考虑聚类分析或分组建模。

      5. 代码结构

        • 清晰的代码分段(数据准备、绘图、美化)

        • 使用管道操作符提高可读性

        • 适当的注释说明关键步骤

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")

data_scaled <- as.data.frame(scale(data))
df_long <- tidyr::pivot_longer(
 data_scaled, 
  cols = c("eruptions", "waiting"), 
  names_to = "variable", 
  values_to = "value"
)

# 居中堆叠点图(分变量展示)
ggplot(df_long, aes(x = variable, y = value)) +
  geom_dotplot(
    binaxis = "y",          # 沿y轴分箱
    bins = 30,              # 分箱数30
    dotsize = 0.3,          # 点大小
    stackdir = "center",    # 居中堆叠
    fill = "#66C2A5"        # 填充颜色(Set2调色板第一种)
  ) +
  labs(
    title = "威尔金森点图(居中堆叠)",
    x = "变量",
    y = "标准化值"
  ) +
  mytheme  # 应用自定义主题

6.3 蜂群图代码

mytheme<-theme_bw()+theme(legend.position="none")

df_long <- tidyr::pivot_longer(
  data_scaled, 
  cols = c("eruptions", "waiting"), 
  names_to = "variable", 
  values_to = "value"
)

# 不带箱线图的蜂群图
ggplot(df_long, aes(x = variable, y = value)) +
  geom_beeswarm(
    cex = 0.8,          # 点大小缩放
    shape = 21,         # 带填充的圆形
    size = 0.8,         # 点大小
    fill = "#66C2A5",   # 填充颜色(Set2调色板第一种)
    color = "black"     # 边框颜色
  ) +
  labs(
    title = "蜂群图(不带箱线图)",
    x = "变量",
    y = "标准化值"
  ) +
  mytheme  # 应用自定义主题

6.4 云雨图代码

library(see)  # 提供主题函数theme_modern
mytheme<-theme_modern()+
         theme(legend.position="none",
               plot.title=element_text(size=14,hjust=0.5))   # 调整标题位置

df_long <- tidyr::pivot_longer(
  data_scaled, 
  cols = c("eruptions", "waiting"), 
  names_to = "variable", 
  values_to = "value"
)

# 纵向云雨图
ggplot(df_long, aes(x = variable, y = value, fill = variable)) +
  geom_violindot(
    dots_size = 0.7,      # 点大小
    binwidth = 0.07,      # 分箱宽度
    alpha = 0.7,          # 透明度
    draw_quantiles = 0.5  # 显示中位数
  ) +
  scale_fill_manual(values = c("#66C2A5", "#FC8D62")) +  # Set2调色板前两种颜色
  labs(
    title = "纵向云雨图",
    x = "变量",
    y = "标准化值"
  ) +
  mytheme  # 应用自定义主题

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