第四章 数据分布可视化

Author

221527229 方景鑫

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.6,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=paste0("中位数 = ",round(median(df$eruptions),2)),size=3,color="red3") # 添加注释文本

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

  • 图形观察:从密度曲线来看,数据呈现左偏分布(负偏度-0.4135),意味着数据左侧有较长的尾部。峰度系数为-1.5116,表明分布比正态分布更平坦。均值(3.49)小于中位数(4),这进一步证实了分布的左偏特性。变量理解:图形显示的是”eruptions”(喷发)变量的分布情况。大部分喷发持续时间集中在3-4分钟之间。有少量持续时间较长的喷发(右侧尾部)

  • 统计量标注实践:图形中成功标注了关键的统计量:偏度、峰度、均值和中位数。这些标注使图形更具信息量,便于读者理解数据特征。可以考虑使用geom_vline()添加均值和中位数的垂直线。

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

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

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

3.3 镜像直方图代码

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

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

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

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

  • 图形观察:一.原始数据直方图:显示”eruptions”和”waiting”两个变量的原始分布。密度曲线与直方图叠加,显示数据实际分布与理论分布的对比。“eruptions”变量呈现多峰分布,可能包含不同子群体;“waiting”变量分布相对集中,但有右偏迹象。二.标准化数据直方图:数据被转换到均值为0、标准差为1的标准尺度,便于比较不同量纲的变量(“eruptions”和”waiting”),标准化后两变量的分布形态差异更加明显。三.镜像直方图:创新性地使用镜像显示,增强分布对比效果,可清晰看到”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("(b) 标准化数据核密度图")

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")+
  guides(fill="none")+
  theme(legend.position=c(0.8,0.8),# 设置图例位置
  legend.background=element_rect(fill="grey90",color="grey"))+ # 设置图例背景色和边框颜色
  facet_wrap(~指标,scale="free")

4.4 镜像核密度图

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

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


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

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

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

  • 图形观察:一.原始数据视图:镜像直方图清晰展示了eruptions(喷发时间)和waiting(等待时间)的原始分布,eruptions呈现双峰特征(2-3分钟和4-5分钟两个集中区间),waiting呈现右偏分布(集中在50-80分钟)。二.标准化视图:将不同量纲的变量统一到相同尺度比较,更明显看出eruptions的波动性大于waiting,两变量的标准化分布均偏离标准正态。三.核密度图补充:平滑展示分布特征,避免直方图分箱的主观性,确认eruptions的双峰特征不是分箱artifact,waiting在标准化后仍保持右偏特性。

  • length分布相对集中(主要3-4区间),width分布更分散且含异常值(70-90区间),两变量可能需不同分析方法。eruptions的双峰可能对应不同喷发模式,waiting与eruptions的分布差异暗示复杂的地质过程。

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

library(tidyr)

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

df<-data |>
  gather(everything(),key=指标,value=指标值) |> 
  mutate(指标=fct_inorder(指标))

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")+
  ggtitle("(a) 原始数据箱线图")

df<-data |> 
  gather(everything(),key=指标,value=指标值) |> 
  mutate(指标=fct_inorder(指标)) |> 
  ddply("指标",transform,标准化值=scale(指标值)) # 计算标准化值并返回数据框
# 绘制箱线图
p2<-ggplot(df,aes(x=指标,y=标准化值))+
  geom_boxplot(fill=palette,outlier.size=0.8)+  # 设置填充颜色和离群点大小
  scale_x_discrete(guide=guide_axis(n.dodge=2))+
ggtitle("(b) 标准化变换箱线图")

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

5.3 小提琴图代码

  • 通过d3r::d3_nest将数据框转化为层次数据“d3.js”作为绘图输入
# 数据处理
df<-data |>               # 删除不需要的变量
  gather(everything(),key=指标,value=指标值) |>  # 融合数据
  mutate(指标=fct_inorder(指标)) |> 
  ddply("指标",transform,标准化值=scale(指标值))    # 计算标准化值

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

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

  • 图形观察:一.镜像核密度图:创新性地将两个变量的核密度估计对称展示,形成”镜像”效果,允许直观比较eruptions和waiting的分布形状差异,密度曲线平滑程度反映数据波动特征。二.标准化小提琴图:结合箱线图与核密度估计的优势,中位数、四分位数等统计量清晰可见,标准化处理使不同量纲变量可比。

  • 一.多峰性检测:核密度图清晰显示eruptions的双峰特征,waiting呈现右偏单峰分布,小提琴图的宽度变化反映数据密度分布。二.异常值识别:小提琴图的”触须”长度揭示异常值范围,核密度图的尾部延伸指示极端值存在

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(everything(),key=指标,value=指标值) |>  # 融合数据
  mutate(指标=fct_inorder(指标)) |> 
  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)     # 按2列组合图形

6.3 蜂群图代码

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

df<-data |>  
  gather(everything(),key=指标,value=指标值) |>  # 融合数据
  mutate(指标=fct_inorder(指标)) |> 
  ddply("指标",transform,标准化值=scale(指标值))    # 计算标准化值

# 绘制图形
mytheme<-theme_bw()+theme(legend.position="none")
p<-ggplot(df,aes(x=指标,y=标准化值,fill=指标))

# 图(a)蜂群图
p1<-p+geom_beeswarm(cex=0.8,shape=21,size=0.8)+# 设置蜂群的宽度、点的形状、大小和填充颜色
mytheme+ggtitle("(a) 蜂群图")

# 图(b)箱线图+蜂群图
p2<-p+geom_boxplot(size=0.5,outlier.size=0.8,aes(color=指标))+
geom_beeswarm(cex=0.8,shape=21,size=0.8)
mytheme+ggtitle("(b) 箱线图+蜂群图")
List of 136
 $ line                            :List of 6
  ..$ colour       : chr "black"
  ..$ linewidth    : num 0.5
  ..$ linetype     : num 1
  ..$ lineend      : chr "butt"
  ..$ arrow        : logi FALSE
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_line" "element"
 $ rect                            :List of 5
  ..$ fill         : chr "white"
  ..$ colour       : chr "black"
  ..$ linewidth    : num 0.5
  ..$ linetype     : num 1
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_rect" "element"
 $ text                            :List of 11
  ..$ family       : chr ""
  ..$ face         : chr "plain"
  ..$ colour       : chr "black"
  ..$ size         : num 11
  ..$ hjust        : num 0.5
  ..$ vjust        : num 0.5
  ..$ angle        : num 0
  ..$ lineheight   : num 0.9
  ..$ margin       : 'margin' num [1:4] 0points 0points 0points 0points
  .. ..- attr(*, "unit")= int 8
  ..$ debug        : logi FALSE
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ title                           : chr "(b) 箱线图+蜂群图"
 $ aspect.ratio                    : NULL
 $ axis.title                      : NULL
 $ axis.title.x                    :List of 11
  ..$ family       : NULL
  ..$ face         : NULL
  ..$ colour       : NULL
  ..$ size         : NULL
  ..$ hjust        : NULL
  ..$ vjust        : num 1
  ..$ angle        : NULL
  ..$ lineheight   : NULL
  ..$ margin       : 'margin' num [1:4] 2.75points 0points 0points 0points
  .. ..- attr(*, "unit")= int 8
  ..$ debug        : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ axis.title.x.top                :List of 11
  ..$ family       : NULL
  ..$ face         : NULL
  ..$ colour       : NULL
  ..$ size         : NULL
  ..$ hjust        : NULL
  ..$ vjust        : num 0
  ..$ angle        : NULL
  ..$ lineheight   : NULL
  ..$ margin       : 'margin' num [1:4] 0points 0points 2.75points 0points
  .. ..- attr(*, "unit")= int 8
  ..$ debug        : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ axis.title.x.bottom             : NULL
 $ axis.title.y                    :List of 11
  ..$ family       : NULL
  ..$ face         : NULL
  ..$ colour       : NULL
  ..$ size         : NULL
  ..$ hjust        : NULL
  ..$ vjust        : num 1
  ..$ angle        : num 90
  ..$ lineheight   : NULL
  ..$ margin       : 'margin' num [1:4] 0points 2.75points 0points 0points
  .. ..- attr(*, "unit")= int 8
  ..$ debug        : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ axis.title.y.left               : NULL
 $ axis.title.y.right              :List of 11
  ..$ family       : NULL
  ..$ face         : NULL
  ..$ colour       : NULL
  ..$ size         : NULL
  ..$ hjust        : NULL
  ..$ vjust        : num 1
  ..$ angle        : num -90
  ..$ lineheight   : NULL
  ..$ margin       : 'margin' num [1:4] 0points 0points 0points 2.75points
  .. ..- attr(*, "unit")= int 8
  ..$ debug        : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ axis.text                       :List of 11
  ..$ family       : NULL
  ..$ face         : NULL
  ..$ colour       : chr "grey30"
  ..$ size         : 'rel' num 0.8
  ..$ hjust        : NULL
  ..$ vjust        : NULL
  ..$ angle        : NULL
  ..$ lineheight   : NULL
  ..$ margin       : NULL
  ..$ debug        : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ axis.text.x                     :List of 11
  ..$ family       : NULL
  ..$ face         : NULL
  ..$ colour       : NULL
  ..$ size         : NULL
  ..$ hjust        : NULL
  ..$ vjust        : num 1
  ..$ angle        : NULL
  ..$ lineheight   : NULL
  ..$ margin       : 'margin' num [1:4] 2.2points 0points 0points 0points
  .. ..- attr(*, "unit")= int 8
  ..$ debug        : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ axis.text.x.top                 :List of 11
  ..$ family       : NULL
  ..$ face         : NULL
  ..$ colour       : NULL
  ..$ size         : NULL
  ..$ hjust        : NULL
  ..$ vjust        : num 0
  ..$ angle        : NULL
  ..$ lineheight   : NULL
  ..$ margin       : 'margin' num [1:4] 0points 0points 2.2points 0points
  .. ..- attr(*, "unit")= int 8
  ..$ debug        : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ axis.text.x.bottom              : NULL
 $ axis.text.y                     :List of 11
  ..$ family       : NULL
  ..$ face         : NULL
  ..$ colour       : NULL
  ..$ size         : NULL
  ..$ hjust        : num 1
  ..$ vjust        : NULL
  ..$ angle        : NULL
  ..$ lineheight   : NULL
  ..$ margin       : 'margin' num [1:4] 0points 2.2points 0points 0points
  .. ..- attr(*, "unit")= int 8
  ..$ debug        : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ axis.text.y.left                : NULL
 $ axis.text.y.right               :List of 11
  ..$ family       : NULL
  ..$ face         : NULL
  ..$ colour       : NULL
  ..$ size         : NULL
  ..$ hjust        : num 0
  ..$ vjust        : NULL
  ..$ angle        : NULL
  ..$ lineheight   : NULL
  ..$ margin       : 'margin' num [1:4] 0points 0points 0points 2.2points
  .. ..- attr(*, "unit")= int 8
  ..$ debug        : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ axis.text.theta                 : NULL
 $ axis.text.r                     :List of 11
  ..$ family       : NULL
  ..$ face         : NULL
  ..$ colour       : NULL
  ..$ size         : NULL
  ..$ hjust        : num 0.5
  ..$ vjust        : NULL
  ..$ angle        : NULL
  ..$ lineheight   : NULL
  ..$ margin       : 'margin' num [1:4] 0points 2.2points 0points 2.2points
  .. ..- attr(*, "unit")= int 8
  ..$ debug        : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ axis.ticks                      :List of 6
  ..$ colour       : chr "grey20"
  ..$ linewidth    : NULL
  ..$ linetype     : NULL
  ..$ lineend      : NULL
  ..$ arrow        : logi FALSE
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_line" "element"
 $ axis.ticks.x                    : NULL
 $ axis.ticks.x.top                : NULL
 $ axis.ticks.x.bottom             : NULL
 $ axis.ticks.y                    : NULL
 $ axis.ticks.y.left               : NULL
 $ axis.ticks.y.right              : NULL
 $ axis.ticks.theta                : NULL
 $ axis.ticks.r                    : NULL
 $ axis.minor.ticks.x.top          : NULL
 $ axis.minor.ticks.x.bottom       : NULL
 $ axis.minor.ticks.y.left         : NULL
 $ axis.minor.ticks.y.right        : NULL
 $ axis.minor.ticks.theta          : NULL
 $ axis.minor.ticks.r              : NULL
 $ axis.ticks.length               : 'simpleUnit' num 2.75points
  ..- attr(*, "unit")= int 8
 $ axis.ticks.length.x             : NULL
 $ axis.ticks.length.x.top         : NULL
 $ axis.ticks.length.x.bottom      : NULL
 $ axis.ticks.length.y             : NULL
 $ axis.ticks.length.y.left        : NULL
 $ axis.ticks.length.y.right       : NULL
 $ axis.ticks.length.theta         : NULL
 $ axis.ticks.length.r             : NULL
 $ axis.minor.ticks.length         : 'rel' num 0.75
 $ axis.minor.ticks.length.x       : NULL
 $ axis.minor.ticks.length.x.top   : NULL
 $ axis.minor.ticks.length.x.bottom: NULL
 $ axis.minor.ticks.length.y       : NULL
 $ axis.minor.ticks.length.y.left  : NULL
 $ axis.minor.ticks.length.y.right : NULL
 $ axis.minor.ticks.length.theta   : NULL
 $ axis.minor.ticks.length.r       : NULL
 $ axis.line                       : list()
  ..- attr(*, "class")= chr [1:2] "element_blank" "element"
 $ axis.line.x                     : NULL
 $ axis.line.x.top                 : NULL
 $ axis.line.x.bottom              : NULL
 $ axis.line.y                     : NULL
 $ axis.line.y.left                : NULL
 $ axis.line.y.right               : NULL
 $ axis.line.theta                 : NULL
 $ axis.line.r                     : NULL
 $ legend.background               :List of 5
  ..$ fill         : NULL
  ..$ colour       : logi NA
  ..$ linewidth    : NULL
  ..$ linetype     : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_rect" "element"
 $ legend.margin                   : 'margin' num [1:4] 5.5points 5.5points 5.5points 5.5points
  ..- attr(*, "unit")= int 8
 $ legend.spacing                  : 'simpleUnit' num 11points
  ..- attr(*, "unit")= int 8
 $ legend.spacing.x                : NULL
 $ legend.spacing.y                : NULL
 $ legend.key                      : NULL
 $ legend.key.size                 : 'simpleUnit' num 1.2lines
  ..- attr(*, "unit")= int 3
 $ legend.key.height               : NULL
 $ legend.key.width                : NULL
 $ legend.key.spacing              : 'simpleUnit' num 5.5points
  ..- attr(*, "unit")= int 8
 $ legend.key.spacing.x            : NULL
 $ legend.key.spacing.y            : NULL
 $ legend.frame                    : NULL
 $ legend.ticks                    : NULL
 $ legend.ticks.length             : 'rel' num 0.2
 $ legend.axis.line                : NULL
 $ legend.text                     :List of 11
  ..$ family       : NULL
  ..$ face         : NULL
  ..$ colour       : NULL
  ..$ size         : 'rel' num 0.8
  ..$ hjust        : NULL
  ..$ vjust        : NULL
  ..$ angle        : NULL
  ..$ lineheight   : NULL
  ..$ margin       : NULL
  ..$ debug        : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ legend.text.position            : NULL
 $ legend.title                    :List of 11
  ..$ family       : NULL
  ..$ face         : NULL
  ..$ colour       : NULL
  ..$ size         : NULL
  ..$ hjust        : num 0
  ..$ vjust        : NULL
  ..$ angle        : NULL
  ..$ lineheight   : NULL
  ..$ margin       : NULL
  ..$ debug        : NULL
  ..$ inherit.blank: logi TRUE
  ..- attr(*, "class")= chr [1:2] "element_text" "element"
 $ legend.title.position           : NULL
 $ legend.position                 : chr "none"
 $ legend.position.inside          : NULL
 $ legend.direction                : NULL
 $ legend.byrow                    : NULL
 $ legend.justification            : chr "center"
 $ legend.justification.top        : NULL
 $ legend.justification.bottom     : NULL
 $ legend.justification.left       : NULL
 $ legend.justification.right      : NULL
 $ legend.justification.inside     : NULL
 $ legend.location                 : NULL
 $ legend.box                      : NULL
 $ legend.box.just                 : NULL
 $ legend.box.margin               : 'margin' num [1:4] 0cm 0cm 0cm 0cm
  ..- attr(*, "unit")= int 1
 $ legend.box.background           : list()
  ..- attr(*, "class")= chr [1:2] "element_blank" "element"
 $ legend.box.spacing              : 'simpleUnit' num 11points
  ..- attr(*, "unit")= int 8
  [list output truncated]
 - attr(*, "class")= chr [1:2] "theme" "gg"
 - attr(*, "complete")= logi TRUE
 - attr(*, "validate")= logi TRUE

6.4 云雨图代码

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

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

  • 一、图形类型特性解析​

    1. 威尔金森点图
    • 居中堆叠模式:聚焦于标准化值的集中趋势呈现,适用于对比不同指标的基准水平。其数值范围限定在 1-100,意味着数据已完成标准化处理。重复出现的 “100” 或为指标截断值,或是特定标记。​
    • 向上堆叠模式:侧重于展现数据的累积效应,适合用于剖析构成比例。数据的堆叠方式直观反映层级关系,若增添颜色区分(虽当前未体现,但推荐使用),可显著提升多变量的辨识度。​
    1. 蜂群图:数据点围绕中轴线智能排列,有效规避重叠问题,同时精准保留原始值位置。通过点的密度分布,能够直观判断数据的集中程度,如 eruptions 变量在 - 1 到 1 区间分布密集,而 waiting 变量分布较为离散,且右侧存在少量高值离群点。平行展示 eruptions 和 waiting 变量,配合统一的 y 轴尺度(-2 到 1),确保对比结果客观公正。若添加颜色区分,可进一步增强变量识别效果。​
    1. 云雨图:创新融合两种可视化形式,上半部分类似小提琴图,呈现数据密度分布;下半部分如同散点图,展示具体数据点。这种组合设计,让观察者既能把握数据整体分布态势,又能洞悉个体数据特征。​

    二、数据可视化关键要点​

    1. 图形类型适配:不同图形类型各有所长,需依据数据类型与分析目标灵活选择。例如,散点图用于揭示两个变量间的关联,箱线图擅长展示数据分布,蜂群图则是呈现分类数据分布的理想之选。​
    1. 图形布局策略:图形的排列与布局直接影响信息传达效果。垂直或水平的不同排列方式,能够提供多样化视角,助力更全面深入地理解数据。​
    1. 细节优化处理:图形细节(如颜色、点大小、标签等)的精细处理,可大幅提升图形的可读性与美观度。利用不同颜色区分类别,合理设置点大小并添加标签,能够有效突出关键信息。