You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ggplot2小提琴图绘制异常:数据集中于左侧问题排查

问题:小提琴图数据集中在左侧,x轴未按年份分布

我有一个名为masterlist的数据框,合并了2013-2021年的事件统计Excel数据集(比如data2013记录某公司2013年停电次数),数据结构如下:

structure(list(DataYear = c("2013", "2013", "2013", "2013", "2013", 
"2013"), UtilityNumber = c("97", "108", "155", "162", "195", 
"207"), UtilityName = c("Adams Electric Coop", "Adams-Columbia Electric Coop", 
"Agralite Electric Coop", "Aiken Electric Coop Inc", "Alabama Power Co", 
"City of Alameda"), State = c("IL", "WI", "MN", "SC", "AL", "CA"
), Ownership = c("Cooperative", "Cooperative", "Cooperative", 
"Cooperative", "Investor Owned", "Municipal"), SAIDIWithMed = c("223", 
"143", "1142", NA, NA, "16.48"), SAIFIWithMed = c("1.81", "1.093", 
"3", NA, NA, "6.8000000000000005E-2"), CAIDIWithMed = c("123.20442", 
"130.83257", "380.66667000000001", NA, NA, "242.35293999999999"
), SAIDIWithoutMed = c("158", "58", "141", NA, NA, NA), SAIFIWithoutMed = c("1.35", 
"0.69099999999999995", "1", NA, NA, NA), CAIDIWithoutMed = c("117.03704", 
"83.936323999999999", "141", NA, NA, NA), SAIDIWithMedMinusLOS = c("191", 
"139", "1134", NA, NA, NA), SAIFIWithMedMinusLOS = c("1.39", 
"1.028", "2", NA, NA, NA), CAIDIMinusMed = c("137.41006999999999", 
"135.21401", "567", NA, NA, NA), NumberOfCustomers = c("8715", 
"36014", "5122", NA, NA, "34347"), OutagesAutomaticallyRecorded = c("N", 
"Y", "N", NA, NA, "N")), row.names = c(NA, -6L), class = c("tbl_df", 
"tbl", "data.frame"))

我尝试用以下代码绘制SAIDIWithMed列的小提琴图:

p <- ggplot(masterlist_test, aes(x=DataYear, y=SAIDIWithMed)) + geom_violin()
p

但生成的图中所有数据都集中在左侧区域,本该分布在2013至2021的x轴区间内。


问题原因

  1. DataYear是字符型而非有序因子:从数据结构能看到,DataYear的取值是带引号的字符串(如"2013")。ggplot对字符型离散变量默认按字符序排序,若年份未被识别为有序类别,会导致所有数据挤在第一个显示的年份下。
  2. SAIDIWithMed是字符型而非数值型:该列的取值也是带引号的字符串(如"223"、"16.48"),ggplot无法对字符型数据进行数值分布统计,这是数据集中在一侧的核心原因——字符型y轴无法正确映射数值的分布规律。

解决步骤

1. 修复数据类型

先把关键列转换成正确的类型:

# 将DataYear转为有序因子,确保年份按2013-2021的顺序排列
masterlist_test$DataYear <- factor(masterlist_test$DataYear, 
                                   levels = as.character(2013:2021), 
                                   ordered = TRUE)

# 将SAIDIWithMed转为数值型,自动处理NA值
masterlist_test$SAIDIWithMed <- as.numeric(masterlist_test$SAIDIWithMed)

2. 重新绘制小提琴图

library(ggplot2)
p <- ggplot(masterlist_test, aes(x=DataYear, y=SAIDIWithMed)) + 
  geom_violin(na.rm = TRUE)  # na.rm=TRUE忽略NA值,避免绘图报错
p

3. 可选优化:添加箱线图辅助

如果部分年份数据量较少,小提琴图形态不明显,可以叠加箱线图更清晰展示数据分布:

p <- ggplot(masterlist_test, aes(x=DataYear, y=SAIDIWithMed)) + 
  geom_violin(na.rm = TRUE) +
  geom_boxplot(width = 0.1, na.rm = TRUE)  # 箱线图宽度设小,避免遮挡小提琴图
p

内容的提问来源于stack exchange,提问作者Rohan Buch

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 19:39:58