第四章 数据分布可视化

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="blue3")+    # 添加地毯图,须线的宽度为0.2
  annotate("text",x=3,y=0.6,label=paste0("偏度系数 =",round(skewness(df$eruptions),4)),size=3)+  # 添加注释文本

  annotate("text",x=3,y=0.7,label=paste0("峰度系数 =",round(kurtosis(df$eruptions),4)),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")+ # 添加注释文本
  ggtitle("(b) 添加频数多边形和中位数点")+


# 图(c) 添加核密度曲线
geom_density(color="blue2",size=0.7)+ # 添加核密度曲线
geom_vline(xintercept=mean(df$eruptions),linetype="twodash",size=0.6,color="red")+
annotate("text",x=3.5,y=0.2,label="均值线",size=3)

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

  • 这段代码使用ggplot2绘制了eruptions数据的分布直方图,并叠加核密度曲线、地毯图和关键统计量标记,直观展示了数据的左偏(偏度系数-0.4135)和低峰(峰度系数-1.5116)特征。通过黄色点标记中位数、红色虚线标记均值,并直接在图形上标注统计数值,实现了数据分布形态与统计指标的有效结合。代码体现了ggplot2分层绘图的灵活性,但部分语法(如..density..)可更新为现代写法。整体而言,这种可视化方式将统计分析与图形呈现紧密结合,通过多元素叠加(直方图、密度曲线、rug plot、统计线)和智能标注,使数据分布特征一目了然,是探索性数据分析的优秀范例。

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

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

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


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

3.3 镜像直方图代码

df <- data |>
  mutate(std.eruptions = scale(eruptions),std.waiting = scale(waiting))



# 图(b)镜像直方图
p1<-ggplot(df)+aes(x=x)+
   geom_histogram(aes(x=eruptions,y=..density..),color="grey50",fill="red",bins = 30,alpha=0.3)+ # 绘制指标值的直方图(上图)
   geom_label(aes(x=50,y=0.1),label="指标值",color="red")+  # 添加标签
   geom_histogram(aes(x=waiting,y=-..density..),color="grey50",fill="blue",alpha=0.3)+ # 绘制PM2.5的直方图(下图)
   geom_label(aes(x=50,y=-0.1),label="PM2.5",color="blue")+  # 添加标签
   xlab("指标值")+ggtitle("原来数据的镜像直方图")

# 图(b)镜像直方图
p2<-ggplot(df)+aes(x=x)+
   geom_histogram(aes(x=std.eruptions,y=..density..),color="grey50",fill="red",bins = 30,alpha=0.3)+ # 绘制指标值的直方图(上图)
   geom_label(aes(x=-1,y=0.1),label="指标值",color="red")+  # 添加标签
   geom_histogram(aes(x=std.waiting,y=-..density..),color="grey50",fill="blue",alpha=0.3)+ # 绘制PM2.5的直方图(下图)
   geom_label(aes(x=-1,y=-0.1),label="PM2.5",color="blue")+  # 添加标签
   xlab("指标值")+ggtitle("标准数据的镜像直方图")



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

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

  • 这段R代码使用ggplot2创建了两个镜像直方图,分别展示原始数据和标准化后的eruptions与waiting变量的分布对比。第一个图形(p1)使用红色和蓝色分别显示eruptions和waiting的原始分布,x轴范围为0-100;第二个图形(p2)则展示标准化后的数据分布,x轴范围集中在-2到2之间。代码通过geom_histogram叠加两个变量的直方图,并配以半透明填充(alpha=0.3)和颜色区分,同时用geom_label添加标识标签。虽然实现了基本的镜像对比效果,但存在几个问题:y轴标签重复、图例缺失、过时的..density..语法应改为after_stat(density),且gqtitle应为ggtitle。最终使用grid.arrange将两图并排显示,有效对比了数据标准化前后的分布变化,但图形标注和坐标轴设计有待优化以提升可读性。这种镜像直方图的设计能直观比较两个变量的分布形态差异,特别适合展示标准化处理前后的数据变化特征。

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

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

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


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

4.3 分面核密度图

df <- data |>
  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)+
  facet_wrap(~指标,scale="free")+
  scale_fill_brewer(palette = 'Set3')+
  theme(legend.position=c(0.8,0.8),# 设置图例位置
       legend.background=element_rect(fill="grey90",color="grey"))+
                                                # 设置图例背景色和边框颜色
  ggtitle("(a) 原来数据叠加直方图")

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


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

4.4 镜像核密度图

df <- data |>
  mutate(std.eruptions = scale(eruptions),std.waiting = scale(waiting))



# 图(b)镜像直方图
p1<-ggplot(df)+aes(x=x)+
   geom_density(aes(x=eruptions,y=..density..),color="grey50",fill="red",bins = 30,alpha=0.3)+ # 绘制指标值的直方图(上图)
   geom_label(aes(x=50,y=0.1),label="指标值",color="red")+  # 添加标签
   geom_density(aes(x=waiting,y=-..density..),color="grey50",fill="blue",alpha=0.3)+ # 绘制PM2.5的直方图(下图)
   geom_label(aes(x=50,y=-0.1),label="PM2.5",color="blue")+  # 添加标签
   xlab("指标值")+ggtitle("原来数据的镜像直方图")

# 图(b)镜像直方图
p2<-ggplot(df)+aes(x=x)+
   geom_density(aes(x=std.eruptions,y=..density..),color="grey50",fill="red",bins = 30,alpha=0.3)+ # 绘制指标值的直方图(上图)
   geom_label(aes(x=-1,y=0.1),label="指标值",color="red")+  # 添加标签
   geom_density(aes(x=std.waiting,y=-..density..),color="grey50",fill="blue",alpha=0.3)+ # 绘制PM2.5的直方图(下图)
   geom_label(aes(x=-1,y=-0.1),label="PM2.5",color="blue")+  # 添加标签
   xlab("指标值")+ggtitle("标准数据的镜像直方图")



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

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

  • 这段R代码通过ggplot2创建了两个镜像密度图,对比展示eruptions和waiting变量在原始和标准化状态下的分布特征。代码首先对数据进行标准化处理生成std.eruptions和std.waiting列,然后分别绘制原始数据(p1)和标准化数据(p2)的镜像密度曲线:红色代表eruptions/指标值,蓝色代表waiting/PM2.5,通过y轴正负方向实现镜像效果。虽然实现了基本的分布对比功能,但存在多处问题:1)aes(x=x)未定义x变量;2)过时的..density..语法;3)nco1应为ncol;4)y轴标签重复且方向相反缺乏说明;5)标签位置固定可能导致重叠。最终使用grid.arrange并排显示两图,有效对比了数据标准化前后的分布变化(原始数据范围0-100,标准化后集中在-2到2),但镜像设计导致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 箱线图代码

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 图形观察和代码编写的心得体会

  • 这段R代码展示了两种火山喷发数据(eruptions和waiting)的可视化方法:箱线图和小提琴图。代码首先定义统一的主题样式(mytheme),然后通过数据转换(gather和mutate)准备长格式数据。箱线图版本使用geom_boxplot展示数据分布,叠加均值点(stat_summary)并使用Set2调色板区分变量;小提琴图则结合geom_violin展示密度分布,同时保留箱线图(geom_boxplot)和原始数据点(geom_point)增强信息量。两个图形都清晰地揭示了waiting变量的值域(约40-100)显著高于eruptions(约1-5),小提琴图进一步展现了waiting呈双峰分布的特征。虽然可视化效果良好,但代码存在若干问题:1)%s%应为%>%管道操作符;2)fi11/fi11_manual应为fill/fill_manual拼写错误;3)转义字符使用不当(如[f_r]);4)箱线图代码中a1pha应为alpha。这些图形通过统一的设计主题和配色方案保持了视觉一致性,有效对比了两个变量的分布差异,特别是小提琴图综合了分布形状、离散度和集中趋势的多维信息,比单纯箱线图更具表现力。

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 图形观察和代码编写的心得体会

  • 这段代码展示了两种创新的数据可视化方法:威尔金森点图和云雨图,用于比较火山喷发数据中eruptions和waiting两个变量的分布。威尔金森点图采用居中堆叠的点阵设计(使用geom_dotplot),通过点密度直观显示数据分布,标准化处理后使两变量具有可比性,绿色填充(#66C2A5)的点阵配合简洁的theme_bw主题,突出了数据点的分布模式。云雨图则通过see包的geom_violindot将小提琴图与点图结合,同时展示数据密度分布和原始数据点,使用双色填充(#66C2A3和#FC8D62)区分变量,并标注中位数线,配合现代风格的theme_modern主题,实现了更丰富的视觉表达。两种方法都基于数据标准化和长格式转换(pivot_longer)的预处理,但云雨图通过violin-dot的混合几何对象提供了更多分布信息,包括密度轮廓、数据离散度和集中趋势。代码中存在少量语法问题(如括号不匹配、注释符号错误等),但核心可视化逻辑清晰,展现了如何通过创新图表设计增强传统分布比较的表现力,特别是云雨图的多层可视化方法,比单一图表能更全面地揭示数据特征。