在R交互式会话中批量绘制矩形时出现DisplayList重复键致命错误
解决M1 Mac上R交互式会话批量绘制矩形时的崩溃问题
问题描述
在搭载M1芯片的MacBook Pro(系统Sonoma 14.5,R版本4.2.3)上,通过for循环批量绘制矩形时,交互式R会话偶尔会崩溃,抛出如下Swift相关致命错误:
Fatal error: Duplicate keys of type 'DisplayList' were found in a Dictionary.
This usually means either that the type violates Hashable's requirements, or
that members of such a dictionary were mutated after insertion.
Trace/BPT trap: 5
该问题仅在交互式会话中绘制数千个矩形时偶发,使用Rscript运行相同代码无异常。可复现的代码如下:
pal <- c("coral", "dodgerblue", "darkseagreen2") table_with_data <- data.frame(left = 0:9, right = 1:10, bot = rep(0:999, each = 10), top = rep(1:1000, each = 10), col = sample(pal, replace = T, 10000)) plot(NULL, xlim = c(0, 10), ylim = c(0,1000)) for (i in 1:nrow(table_with_data)){ rect(table_with_data$left[i], table_with_data$bot[i], table_with_data$right[i], table_with_data$top[i], col = table_with_data$col[i], border = NA) }
原因分析
这是Apple Silicon芯片(M1/M2等)Mac上,R交互式绘图后端(依赖Swift库)的兼容性问题:当频繁循环调用绘图函数时,DisplayList字典出现哈希冲突或并发修改,触发Swift层面的致命错误。
解决方案
- 改用向量化绘图替代循环:R的绘图函数原生支持向量输入,无需逐个调用,能大幅降低绘图后端的压力,避免触发bug。修改后的代码:
pal <- c("coral", "dodgerblue", "darkseagreen2") table_with_data <- data.frame(left = 0:9, right = 1:10, bot = rep(0:999, each = 10), top = rep(1:1000, each = 10), col = sample(pal, replace = T, 10000)) plot(NULL, xlim = c(0, 10), ylim = c(0,1000)) # 直接传入整列向量,无需循环 rect(table_with_data$left, table_with_data$bot, table_with_data$right, table_with_data$top, col = table_with_data$col, border = NA)
- 更新R到最新版本:R 4.3.x及后续版本针对Apple Silicon的绘图后端做了修复,升级后可解决该问题。
- 切换绘图后端:在交互式会话中切换到非Swift依赖的后端,比如使用Cairo:
install.packages("Cairo") library(Cairo) Cairo() # 启动Cairo绘图设备 # 再执行绘图代码
- 继续使用Rscript运行:如果仅需生成图形文件,保持用Rscript执行代码,避开交互式会话的bug。
内容的提问来源于stack exchange,提问作者Kamil S Jaron
相关产品推荐
相关产品推荐

