使用ggplot2的geom_image自定义点图时遭遇UnableToOpenBlob错误求助
用自定义图片替代ggplot散点图点标记时出现文件找不到错误
问题背景
我想用自定义图片替代ggplot散点图中的普通点,数据表中有一列值为NY_Male、NY_Female、OK_Male或OK_Female,每个值对应一张特定图片。尝试了多种导入方式后仍报错,代码及错误信息如下:
原代码
#import library library(ggplot2) library(beeswarm) library(dunn.test) library(ggimage) library(png) library(RCurl) library(grid) #set working directory setwd("/Users/Documents//R") #import data data<-read.csv("parasite3_master.csv") # Image URL1 = "https://firebasestorage.googleapis.com/v0/b/tick-67255.appspot.com/o/Amblyomma_americanum_tick_blue_male.png?alt=media&token=fe30dc09-5a07-4fbd-b64e-7d90a8275eef" NY__Male = readPNG(getURLContent(URL1)) ## Image 2 URL2 = "https://firebasestorage.googleapis.com/v0/b/tick-67255.appspot.com/o/Amblyomma_americanum_tick_blue.png?alt=media&token=1e44e074-107b-4933-a6f5-9b1e81a17e9e" NY__Female = readPNG(getURLContent(URL2)) # Image 3 URL3 = "https://firebasestorage.googleapis.com/v0/b/tick-67255.appspot.com/o/Amblyomma_americanum_tick.png?alt=media&token=d8863d57-12d8-4eb1-b86b-00dd21b33f07" OK__Female = readPNG(getURLContent(URL3)) # Image 4 URL4 = "https://firebasestorage.googleapis.com/v0/b/tick-67255.appspot.com/o/Amblyomma_americanum_tick_green_male.png?alt=media&token=75519f09-30a6-4daa-b058-bf2430cc46d7" OK__Male = readPNG(getURLContent(URL4)) # Crop the mal image #NY_Male = NY_Male [40:250,,] ## Turn images into raster grobs NY_Male = rasterGrob(NY__Male) NY_Female = rasterGrob(NY__Female) OK_Male = rasterGrob(OK__Male) OK_Female = rasterGrob(OK__Female) attach(NY_Male) attach(NY_Female) attach(OK_Male) attach(OK_Female) #check work View(data) summary(data) #create data object attach(data) #Paste Function to combine location and sex Categories <- paste(Location, Sex, sep=" ") #Water Balance charts #plot QH WBplot <- ggplot(data , aes(y = DT, x = Categories , fill = Sex)) + stat_summary(fun=mean,geom="errorbar",aes(ymax=..y..,ymin=..y..)) + geom_dotplot(binaxis='y', stackdir='center', position=position_dodge(1), dotsize = .5)+ geom_image(aes(image=Image, size=0.015)) ylab("Dehydration Tolerance (%)") + ylim(5,40) + theme(axis.text = element_text(size = 12), axis.title = element_text(size = 15, face = "bold"), axis.title.x = element_blank(), strip.text.x = element_text(size = 15), strip.text.y = element_text(size = 15), legend.position = "top", panel.background = element_rect(fill = "white", colour = NA), panel.border = element_rect(fill = NA, colour = "black"), strip.background = element_rect(colour = "black")) WBplot
报错信息
Error in `geom_image()`: ! Problem while converting geom to grob. ℹ Error occurred in the 3rd layer. Caused by error: ! rsession-arm64: UnableToOpenBlob `NY_Male': No such file or directory @ error/blob.c/OpenBlob/2924
问题原因与解决方法
核心错误
geom_image()参数逻辑错误:该函数的image参数需要图片的URL、本地路径,或与数据绑定的图片对象引用,你手动创建的rasterGrob对象无法通过attach()映射到数据列。- 未建立数据与图片的映射:代码中
aes(image=Image)的Image列并未在数据表中定义,无法将分类值对应到图片。
修正步骤
1. 给数据表添加图片映射列
使用case_when根据Categories的值,给每条数据匹配对应的图片URL(如果用本地图片,替换为本地路径即可):
# 加载dplyr(未安装则先运行install.packages("dplyr")) library(dplyr) # 生成Categories列并添加图片URL映射 data <- data %>% mutate(Categories = paste(Location, Sex, sep = " "), Image_URL = case_when( Categories == "NY Male" ~ "https://firebasestorage.googleapis.com/v0/b/tick-67255.appspot.com/o/Amblyomma_americanum_tick_blue_male.png?alt=media&token=fe30dc09-5a07-4fbd-b64e-7d90a8275eef", Categories == "NY Female" ~ "https://firebasestorage.googleapis.com/v0/b/tick-67255.appspot.com/o/Amblyomma_americanum_tick_blue.png?alt=media&token=1e44e074-107b-4933-a6f5-9b1e81a17e9e", Categories == "OK Female" ~ "https://firebasestorage.googleapis.com/v0/b/tick-67255.appspot.com/o/Amblyomma_americanum_tick.png?alt=media&token=d8863d57-12d8-4eb1-b86b-00dd21b33f07", Categories == "OK Male" ~ "https://firebasestorage.googleapis.com/v0/b/tick-67255.appspot.com/o/Amblyomma_americanum_tick_green_male.png?alt=media&token=75519f09-30a6-4daa-b058-bf2430cc46d7" ))
2. 移除无效的attach()操作
删掉所有attach(NY_Male)、attach(data)这类代码,attach()会污染全局环境,且无法实现图片与数据的正确映射。
3. 修正ggplot代码
直接用数据中的Image_URL列映射图片,同时调整图层位置避免重叠:
WBplot <- ggplot(data, aes(y = DT, x = Categories, fill = Sex)) + stat_summary(fun = mean, geom = "errorbar", aes(ymax = ..y.., ymin = ..y..)) + # 若不需要原有的dotplot可删除该行,否则图片会覆盖点 # geom_dotplot(binaxis='y', stackdir='center', position=position_dodge(1), dotsize = .5)+ geom_image(aes(image = Image_URL), size = 0.015, position = position_dodge(1)) + ylab("Dehydration Tolerance (%)") + ylim(5, 40) + theme(axis.text = element_text(size = 12), axis.title = element_text(size = 15, face = "bold"), axis.title.x = element_blank(), strip.text.x = element_text(size = 15), strip.text.y = element_text(size = 15), legend.position = "top", panel.background = element_rect(fill = "white", colour = NA), panel.border = element_rect(fill = NA, colour = "black"), strip.background = element_rect(colour = "black")) WBplot
额外注意事项
- 确保
Categories的取值与case_when中的判断完全一致(包括空格、大小写),否则会出现映射缺失。 - 调整
geom_image()的size参数时,该值是相对于绘图区域的比例,0.015可能偏小,可根据实际显示效果微调。 - 如果使用本地图片,需确保图片路径正确,且工作目录设置无误(可通过
getwd()确认)。
内容的提问来源于stack exchange,提问作者L Trimm5
相关产品推荐
相关产品推荐

