第四章 数据分布可视化

Author

221527135 徐锦辉

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 作图代码

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"))            # 设置图例字体大小

skew <- round(skewness(faithful$eruptions), 2)
kurt <- round(kurtosis(faithful$eruptions), 2)
mean_eruptions <- mean(faithful$eruptions)
median_eruptions <- median(faithful$eruptions)

ggplot(data = faithful, aes(x = eruptions)) +
  geom_histogram(aes(y = ..density..), bins = 30, fill = "lightblue", color = "black") +
  geom_rug() +geom_density(color = "red", linewidth = 1) +annotate("text", x = Inf, y = Inf, 
           label = paste("Skewness =", skew, "\nKurtosis =", kurt), 
           hjust = 1.1, vjust = 1.1, size = 4, color = "black") +geom_vline(xintercept = mean_eruptions, color = "blue", linetype = "dashed", linewidth = 1) +geom_point(aes(x = median_eruptions, y = 0), color = "green", size = 4) +annotate("text", x = median_eruptions, y = 0.05, 
           label = "中位数",
          size = 4, color = "red3") +
  mytheme

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

  • 直方图显示 eruptions 数据呈现双峰分布(bimodal),主要集中在 2 和 4 附近,反映了老忠实泉喷发时间的两种模式。核密度曲线(红色)平滑地捕捉了双峰特性,与直方图的密度分布一致。偏度 (Skewness = -0.41) 表明分布略左偏(负值),但接近对称。峰度 (Kurtosis = -1.51) 表示分布比正态分布更平坦(负峰度),这与双峰分布的特性相符。

    使用 ggplot2 的分层方法(逐个添加 geom_* 和 annotate)便于调试和修改。例如,先绘制直方图和密度曲线,再添加参考线和标注,逐步验证每个元素的效果。

    每次添加新元素(如 geom_vline 或 geom_point)后,检查图形是否保持清晰,避免颜色或位置冲突。

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

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)+ # 绘制PM2.5的直方图(下图)
   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)+ # 绘制PM2.5的直方图(下图)
   geom_label(aes(x=-0.5,y=-0.5),label='waiting',color="blue")+  # 添加标签
   xlab("指标值")+ggtitle("(b) 标准化的镜像直方图")
grid.arrange(p1,p2,ncol=2)  

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

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和p2
p1<-ggplot(df)+aes(x=指标值,y=..density..,fill=指标)+
   geom_density(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)eruptions ")

p2<-ggplot(df)+aes(x=标准化值,y=..density..,fill=指标)+
   geom_density(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) waiting")

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

4.3 分面核密度图

p1<-ggplot(df)+aes(x=指标值,y=..density..,fill=指标)+
   geom_density(color="gray50",alpha=0.5)+
   scale_fill_brewer(palette="Set3")+facet_wrap(~指标,scales = "free")+ theme(legend.position=c(0.8,0.8),legend.background = element_rect(fill = "grey90",color = "grey"))

p1

4.4 镜像核密度图

p1<-ggplot(df,aes(x=x))+
   geom_density(aes(x=指标值,y=..density..),fill="red",alpha=0.3)+ 
   geom_label(aes(x=160,y=0.0065),label="eruptions",color="red")+  
   geom_density(aes(x=标准化值,y=-..density..),fill="blue",alpha=0.3)+ 
   geom_label(aes(x=120,y=-0.0065),label="waiting",color="blue")+
   xlab("指标值")+ggtitle("(a)镜像核密度图")

p1

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

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

# 定义颜色(使用 Set2 调色板的前两种颜色)
box_fill_colors <- brewer.pal(6, "Set2")[1:2]  # 提取前两种颜色

# 1. 原始数据图
p1 <- ggplot(df, aes(x = 指标, y = 指标值, fill = 指标)) +  # fill 映射到指标
  geom_violin(alpha = 0.3, width = 0.8, color = "gray50") +  # 小提琴图(透明,灰色边框)
  geom_boxplot(width = 0.2, outlier.shape = NA, alpha = 0.8) +  # 箱线图(无离群点,半透明)
  scale_fill_manual(values = box_fill_colors) +  # 使用 Set2 前两种颜色填充箱线图
  geom_jitter(width = 0.1, size = 1.5, alpha = 0.4, color = "blue") +  # 点图(蓝色)
  stat_summary(fun = "mean", geom = "point", shape = 18, size = 3, color = "red") +  # 均值点(红点)
  labs(title = "原始数据", x = "变量", y = "值") +
  theme_minimal() +
  theme(legend.position = "none")  # 隐藏图例(避免重复)

# 2. 标准化数据图
p2 <- ggplot(df, aes(x = 指标, y = 标准化值, fill = 指标)) +
  geom_violin(alpha = 0.3, width = 0.8, color = "gray50") +
  geom_boxplot(width = 0.2, outlier.shape = NA, alpha = 0.8) +
  scale_fill_manual(values = box_fill_colors) +  # 使用相同的颜色方案
  geom_jitter(width = 0.1, size = 1.5, alpha = 0.4, color = "blue") +
  stat_summary(fun = "mean", geom = "point", shape = 18, size = 3, color = "red") +
  labs(title = "标准化数据", x = "变量", y = "标准化值") +
  theme_minimal() +
  theme(legend.position = "none")  # 隐藏图例



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

5.3 小提琴图代码

  • 通过d3r::d3_nest将数据框转化为层次数据“d3.js”作为绘图输入

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

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

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

library(ggplot2)
library(patchwork)

# 居中堆叠
p1 <- ggplot(df, aes(x = 指标, y = 标准化值, fill = 指标)) +
  geom_dotplot(
    binaxis = "y", 
    stackdir = "center",  # 居中堆叠
    dotsize = 0.3,
    alpha = 0.7
  ) +
  scale_fill_brewer(palette = "Set2") +
  labs(title = "威尔金森点图(居中堆叠)", x = NULL, y = "标准化值") +
  theme_minimal()

# 向上堆叠
p2<- ggplot(df, aes(x = 指标, y = 标准化值, fill = 指标)) +
  geom_dotplot(
    binaxis = "y", 
    stackdir = "up",      # 向上堆叠
    dotsize = 0.3,
    alpha = 0.7
  ) +
  scale_fill_brewer(palette = "Set2") +
  labs(title = "威尔金森点图(向上堆叠)", x = NULL, y = "标准化值") +
  theme_minimal()

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

6.3 蜂群图代码

# 不带箱线图
p1 <- ggplot(df, aes(x = 指标, y = 标准化值, color = 指标)) +
  geom_beeswarm(
    cex = 0.8, 
    shape = 21, 
    size = 0.8,
    alpha = 0.6
  ) +
  scale_color_brewer(palette = "Set2") +
  labs(title = "蜂群图(不带箱线图)", x = NULL, y = "标准化值") +
  theme_minimal()

# 带箱线图
p2<- ggplot(df, aes(x = 指标, y = 标准化值, fill = 指标)) +
  geom_boxplot(
    width = 0.2, 
    outlier.shape = NA, 
    alpha = 0.5
  ) +
  geom_beeswarm(
    cex = 0.8, 
    shape = 21, 
    size = 0.8,
    alpha = 0.6
  ) +
  scale_fill_brewer(palette = "Set2") +
  labs(title = "蜂群图(带箱线图)", x = NULL, y = "标准化值") +
  theme_minimal()

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))   # 调整标题位置

# 纵向云雨图
p1<- ggplot(df, aes(x = 指标, y = 标准化值, fill = 指标)) +
  geom_violindot(
    dots_size = 0.7, 
    binwidth = 0.07,
    alpha = 0.5
  ) +
  scale_fill_brewer(palette = "Set2") +
  labs(title = "云雨图(纵向)", x = NULL, y = "标准化值") +
  theme_minimal()

# 横向云雨图(交换 x/y 轴)
p2<- ggplot(df, aes(y = 指标, x = 标准化值, fill = 指标)) +
  geom_violindot(
    dots_size = 0.7, 
    binwidth = 0.07,
    alpha = 0.5
  ) +
  scale_fill_brewer(palette = "Set2") +
  labs(title = "云雨图(横向)", x = "标准化值", y = NULL) +
  theme_minimal()
gridExtra::grid.arrange(p1,p2,ncol=2)

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