第四章 数据分布可视化

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
  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.6,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.05,label="中位数",size=3,color="red3")# 添加注释文本

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

观察:

图形绘制了eruptions火山喷发持续时间的分布情况,使用直方图和核密度图表示数据不同时间的密度。同时使用地毯图直观呈现数据点的位置从而观察到数据分布区域的稀疏程度。同时添加了偏度系数,峰度系数,均值线,中位数四个数据分布特征。可以发现eruptions有两个峰一个谷,均值小于中位数(左偏分布)。

代码心得:

1利用annotate()在直方图标注峰度和偏度信息,这里使用了label=paste0进行字符串和变量值的拼接。

2利用annotate()对备注信息的位置进行控制

3通过不断往图片叠加元素从而完成对图形的绘制。

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

DT::datatable(df,rownames = FALSE)
# 图(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) eruptions和waiting的叠加直方图")
p2<-ggplot(df)+aes(x=scale_value,y=..density..,fill=指标)+
  geom_histogram(position="identity",color="gray60",alpha=0.5)+
  scale_fill_brewer(palette="Set3")+
  theme(legend.position=c(0.8,0.9),# 设置图例位置
       legend.background=element_rect(fill="grey90",color="grey"))+
                                                # 设置图例背景色和边框颜色
  ggtitle("(b) eruptions和waiting的标准化叠加直方图")
gridExtra::grid.arrange(p1,p2,ncol=2)        # 组合图形

3.3 镜像直方图代码

df <- data |>
  mutate(scale_eruptions = scale(eruptions),
         scale_waiting = scale(waiting))

# 图(b)镜像直方图
p1<-ggplot(df)+aes(x=x)+
   geom_histogram(aes(x=eruptions,y=..density..),color="grey50",fill="red",alpha=0.3)+ # 绘制eruptions的直方图(上图)
   geom_label(aes(x=3,y=0.1),label="eruptions",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.008),label="waiting",color="blue")+  # 添加标签
   xlab("指标值")+ggtitle("(b) eruptions和waiting的镜像直方图")

p2<-ggplot(df)+aes(x=x)+
   geom_histogram(aes(x=scale_eruptions,y=..density..),color="grey50",fill="red",alpha=0.3)+ # 绘制eruptions的直方图(上图)
   geom_label(aes(x=0,y=0.25),label="eruptions",color="red")+  # 添加标签
   geom_histogram(aes(x=scale_waiting,y=-..density..),color="grey50",fill="blue",alpha=0.3)+ # 绘制PM2.5的直方图(下图)
   geom_label(aes(x=0,y=-0.5),label="waiting",color="blue")+  # 添加标签
   xlab("指标值")+ggtitle("(b) eruptions和waiting的\n标准化镜像直方图")

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

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

3.4.1 叠加直方图

观察:

图形绘制了 eruptions 和 waiting 的分布情况,使用叠加直方图来表示数据不同指标值的密度。 在图 (a) 中,通过不同颜色的柱状条可以直观地看到 eruptions 和 waiting 在各个指标值上的分布密度。eruptions的时间较waiting短。 在图 (b) 中,展示了 eruptions 和 waiting 的标准化叠加直方图,纵轴为密度,横轴为 scale_value。

心得:

1使用gather()将宽数据转换为长格式,便于ggplot2绘制分组图形

2使用ddply()计算每个指标的标准化值(z-score)

3图(a)展示原始数据的叠加直方图,图(b)展示标准化后的叠加直方图,这种对比可以消除量纲差异,更好地比较两个变量的分布形状。

4使用半透明(alpha=0.5)的叠加直方图,便于观察重叠部分

5图例位置可以调整,避免遮挡图形主体。

6通过创建两个独立的ggplot对象(p1和p2),使用grid.arrange()实现并排对比

3.4.2 镜像直方图

观察:

这组图展示了eruptions和waiting的两种不同的直方图。与重叠直方图相似,waiting变量置于x轴下方。 在左侧的图中,标题为(b) eruptions和waiting的镜像,纵轴表示密度(density),横轴表示指标值。可以看到eruptions和waiting的分布集中区域。 在右侧的图中,标题为(b) eruptions和waiting的标准化镜像直方图。

心得:

  1. 通过设置y=..density..y=-..density..实现上下镜像效果

  2. 红色代表eruptions分布(上方)

  3. 蓝色代表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_value = scale(指标值))

DT::datatable(df,rownames = FALSE)
# 图(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) eruptions和waiting的叠加核密度图")
p2<-ggplot(df)+aes(x=scale_value,y=..density..,fill=指标)+
  geom_density(position="identity",color="gray60",alpha=0.5)+
  scale_fill_brewer(palette="Set3")+
  theme(legend.position=c(0.8,0.9),# 设置图例位置
       legend.background=element_rect(fill="grey90",color="grey"))+
                                                # 设置图例背景色和边框颜色
  ggtitle("(b) eruptions和waiting的\n标准化叠加核密度图")
gridExtra::grid.arrange(p1,p2,ncol=2)        # 组合图形

4.3 分面核密度图

p2<-ggplot(df)+aes(x=scale_value,y=..density..,fill=指标)+
  geom_density(position="identity",color="gray60",alpha=0.5)+
  facet_wrap(~指标,scale="free") +
  guides(fill = "none")+
  scale_fill_brewer(palette="Set3")+
  theme(legend.position=c(0.8,0.9),# 设置图例位置
       legend.background=element_rect(fill="grey90",color="grey"))
                                                # 设置图例背景色和边框颜色
 
p2

4.4 镜像核密度图

df <- data |>
  mutate(scale_eruptions = scale(eruptions),
         scale_waiting = scale(waiting))

# 图(b)镜像直方图
p1<-ggplot(df)+aes(x=x)+
   geom_density(aes(x=eruptions,y=..density..),color="grey50",fill="red",alpha=0.3)+ # 绘制eruptions的直方图(上图)
   geom_label(aes(x=3,y=0.1),label="eruptions",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.008),label="waiting",color="blue")+  # 添加标签
   xlab("指标值")+ggtitle("(b) eruptions和waiting的镜像直方图")

p2<-ggplot(df)+aes(x=x)+
   geom_density(aes(x=scale_eruptions,y=..density..),color="grey50",fill="red",alpha=0.3)+ # 绘制eruptions的直方图(上图)
   geom_label(aes(x=0.5,y=0.25),label="eruptions",color="red")+  # 添加标签
   geom_density(aes(x=scale_waiting,y=-..density..),color="grey50",fill="blue",alpha=0.3)+ # 绘制PM2.5的直方图(下图)
   geom_label(aes(x=0,y=-0.5),label="waiting",color="blue")+  # 添加标签
   xlab("指标值")+ggtitle("(b) eruptions和waiting的\n标准化镜像直方图")

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

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

4.5.1 分组核密度图

观察:与上文的分组直方图相似,通过核密度图去绘制其分布。

心得:将上文的直方图函数geom_histogram转化为geom_density

4.5.2 分面核密度图

观察:图形是关于eruptions和 waiting两个经过标准化的数值变量的分面核密度图。

心得:

  1. 分面设置facet_wrap(~指标, scale="free"):按指标变量分面显示,每个子图使用自由比例尺

  2. 图例控制guides(fill = "none"):隐藏填充图例(因为分面已经明确区分)

4.5.3 镜像核密度图

与上文原理相似,通过核密度图去绘制其分布。

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

df1 <- data %>% 
  select(c(eruptions,waiting)) %>% 
  gather(eruptions,waiting,key=指标,value=指标值) %>% 
  mutate(指标=fct_inorder(指标))

df2 <- data |>
  gather(eruptions,waiting,key=指标,value=指标值) %>%   # 融合数据
  mutate(指标=fct_inorder(指标)) %>% 
  ddply("指标",transform,scale_value = scale(指标值))
  
palette<-RColorBrewer::brewer.pal(6,"Set2")[1:2]      # 设置调色板
# 绘制箱线图
p1<-ggplot(df1,aes(x=指标,y=指标值))+     # y值取对数
  geom_boxplot(fill=palette,outlier.size=0.8)+  # 设置填充颜色和离群点大小
  scale_x_discrete(guide=guide_axis(n.dodge=2))+  # x轴标签为2行
  ylab("指标值")+ggtitle("(a) 原始数据箱线图")+
  stat_summary(fun="mean",geom="point",shape=21,size=2.5,fill="white")

p2<-ggplot(df2,aes(x=指标,y=scale_value))+
  geom_boxplot(fill=palette,outlier.size=0.8)+  # 设置填充颜色和离群点大小
  scale_x_discrete(guide=guide_axis(n.dodge=2))+ylab("标准化值")+ggtitle("(b) 标准化数据箱线图")+
  stat_summary(fun="mean",geom="point",shape=21,size=2.5,fill="white")

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

5.3 小提琴图代码

  • 通过d3r::d3_nest将数据框转化为层次数据“d3.js”作为绘图输入
df<-data |> select(c(eruptions,waiting)) |>             
  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 图形观察和代码编写的心得体会

5.4.1 箱线图

观察:
a:eruptions指标的箱体非常小,集中在较低的指标值区域,表明该指标的数据分布较为集中,且数值普遍较小。waiting指标的箱体较大,分布在较高的指标值区域,表明该指标的数据分布较为分散,且数值普遍较大。 两个指标的均值用白色圆点表示。 须线:从箱体上下两端延伸出的须线,表示数据的范围,须线末端的小横线表示数据的最小值和最大值。

b:“eruptions”指标的箱体位于标准化值的负区间,表明其原始数据经过标准化处理后,整体数值较小。 “waiting”指标的箱体位于标准化值的正区间,表明其原始数据经过标准化处理后,整体数值较大。

代码心得:

  1. geom_boxplot():绘制箱线图

    • fill=palette:使用预设的调色板填充箱体,注意箱体只有两个要进行颜色选择。

    • outlier.size=0.8:调整离群点大小

  2. stat_summary():添加统计量

    • fun="mean":计算均值

    • geom="point":以点的形式展示

    • shape=21:使用带边框的圆形

    • fill="white":点内部填充白色

5.4.2 小提琴图

观察:

a这是一个展示原始数据的小提琴图。展示了“eruptions”和“waiting”两个指标的数据分布。“eruptions”数据用橙色表示,“waiting”数据用灰色表示。中间宽部分表示数据集中的区域,两端逐渐变细表示数据的稀疏区域。小提琴图内部包含一个矩形盒须图,显示了数据的中位数、四分位数等统计信息。图中可以看到一些离群值,用小圆点表示。

b与图(a)类似。采用的是标准化的数据。

心得:

  1. scale="width":使所有小提琴图宽度相同

  2. trim=FALSE(仅 p1):保留完整的数据分布尾部

  3. geom_point():添加原始数据点,调整点的大小和颜色增强可读性

  4. geom_boxplot():在小提琴图内部添加箱线图

    • outlier.size/outlier.color:定制离群点样式

    • width=0.2:控制箱线图宽度

  5. mytheme:应用统一的字体大小设置

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 威尔金森点图代码

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

df<-data |> select(c(eruptions,waiting)) |>             
  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) 

6.3 蜂群图代码

df<-data |> select(c(eruptions,waiting)) |>             
  gather(everything(),key=指标,value=指标值) |>  # 融合数据
  mutate(指标=fct_inorder(指标)) |> 
  ddply("指标",transform,标准化值=scale(指标值))
mytheme<-theme_bw()+theme(legend.position="none")
p<-ggplot(df,aes(x=指标,y=标准化值))
p1<-p+geom_beeswarm(cex=0.8,shape=21,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) 

6.4 云雨图代码

library(see)  # 提供主题函数theme_modern
mytheme<-theme_modern()+
         theme(legend.position="none",
               plot.title=element_text(size=14,hjust=0.5))   # 调整标题位置
df<-data |> select(c(eruptions,waiting)) |>             
  gather(everything(),key=指标,value=指标值) |>  # 融合数据
  mutate(指标=fct_inorder(指标)) |> 
  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 图形观察和代码编写的心得体会

6.5.1 威尔金森点图

观察:

a箱线须图变式(或称小提琴图变体),结合了箱线图和小提琴图的特性,能够展示数据的分布情况。“eruptions”和“waiting”,分别对应两个小提琴图。小提琴图内部有短横线和点,分别表示数据的中位数和离群值。

b向上堆叠,表明该图表采用向上堆叠的方式展示数据。与图表(a)相同,为箱线须图变式。

心得:

  1. geom_dotplot():绘制点图

    • binaxis="y":沿 y 轴(数值轴)进行分箱

    • bins=30:设置分箱数量为 30,控制分辨率

    • dotsize=0.3:调整点的大小,避免过于拥挤

    • stackdir="center"(仅 p1):将点居中堆叠,对称展示分布

    • stackdir="up"(p2 默认):将点向上堆叠,传统直方图样式

6.5.2 蜂群图

观察:

a这是一个蜂群图,主要用于展示数据的分布情况。图表展示了“eruptions”和“waiting”两个指标的数据分布,数据点以红色小圆圈的形式分布在垂直轴上,显示了每个指标的标准化值。通过数据点的分布,蜂群图直观地展示了“eruptions”和“waiting”两个指标的数据集中趋势和离散程度。

b这是一个结合了箱线图和蜂群图的复合图表。“eruptions”的数据点以红色显示,而“waiting”的数据点以浅蓝色显示。箱线图的框线和须线也分别以红色和浅蓝色显示,与数据点颜色相对应。数据点以小圆圈表示,箱线图由矩形框和须线组成,矩形框表示数据的四分位数范围,须线表示数据的范围。

心得:

  1. geom_beeswarm()

    • 核心功能:将数据点排列成不重叠的蜂群形状,保留了数据的单值信息
  2. geom_boxplot()

    • size=0.5:调整箱线图边框粗细

    • outlier.size=0.8:减小离群点大小,避免视觉干扰

    • 与蜂群图叠加时,箱线图提供了统计摘要信息(四分位数、中位数、离群点)

6.5.3 云雨图

观察:两个图形结合了散点图和密度图,可以观察两个指标的分布形状。

心得:

  1. geom_violindot()

    • 功能:结合小提琴图(显示概率密度)、箱线图(显示四分位数)和直方图(显示数据分布)

    • dots_size=0.7:调整直方图中点的大小

    • binwidth=0.07:控制直方图的分箱宽度,影响数据点聚合程度

  2. coord_flip()

    • 功能:翻转 x 轴和 y 轴,实现水平排列的云雨图

    • 适用场景:当类别名称较长或需要与其他水平图表保持一致时使用