使用ggplotly转换sf地图ggplot时出现sum(tickExists)类型错误
问题原因及解决办法
错误原因
这个错误是由于ggplotly解析使用geom_sf且完全隐藏坐标轴(比如theme_void())的ggplot对象时,内部用于判断坐标轴刻度的变量tickExists被误赋值为列表类型(来自sf对象的geometry列),而sum()函数无法处理列表,因此触发报错。单纯将sf转为data.frame无法解决问题——要么丢失空间几何信息,要么geom_sf仍依赖sf属性,没触及ggplotly的内部解析逻辑。
解决办法
办法1:替换theme_void()为精细化的主题隐藏
不要用theme_void()直接移除所有坐标轴相关元素,而是手动隐藏可见元素但保留坐标轴的基础框架,避免ggplotly触发错误的刻度判断:
library(tigris) library(ggplot2) library(plotly) # 获取并合并数据 states <- states(cb = TRUE) custom_data <- data.frame(state = states$NAME, value = rnorm(nrow(states))) states_merged <- merge(states, custom_data, by.x = "NAME", by.y = "state") # 绘制地图,替换theme_void为精细化隐藏 p <- ggplot(states_merged) + geom_sf(aes(fill = value, text = paste("州:", NAME, "\n值:", value))) + theme( axis.text = element_blank(), axis.title = element_blank(), axis.ticks = element_blank(), panel.grid = element_blank(), panel.background = element_blank() ) # 转换为交互式图形 ggplotly(p, tooltip = "text")
办法2:将sf转为普通数据框,用geom_polygon绘图
把sf对象的几何坐标提取出来,用普通的geom_polygon替代geom_sf,让ggplotly能正常解析:
library(tigris) library(ggplot2) library(plotly) library(tidyr) library(purrr) # 获取并合并数据 states <- states(cb = TRUE) custom_data <- data.frame(state = states$NAME, value = rnorm(nrow(states))) states_merged <- merge(states, custom_data, by.x = "NAME", by.y = "state") # 转换sf为带坐标的普通数据框 states_df <- states_merged %>% mutate(coords = map(geometry, ~as.data.frame(.x))) %>% unnest(coords) %>% rename(x = X, y = Y) # 用geom_polygon绘图 p <- ggplot(states_df) + geom_polygon(aes(x = x, y = y, group = NAME, fill = value, text = paste("州:", NAME, "\n值:", value))) + coord_fixed() + theme( axis.text = element_blank(), axis.title = element_blank(), axis.ticks = element_blank(), panel.grid = element_blank(), panel.background = element_blank() ) # 转换为交互式图形 ggplotly(p, tooltip = "text")
办法3:直接使用plotly原生空间绘图函数
绕过ggplotly转换,直接用plotly的add_sf函数处理sf对象:
library(tigris) library(plotly) # 获取并合并数据 states <- states(cb = TRUE) custom_data <- data.frame(state = states$NAME, value = rnorm(nrow(states))) states_merged <- merge(states, custom_data, by.x = "NAME", by.y = "state") # 直接绘制交互式地图 plot_ly(states_merged, sf = TRUE, hoverinfo = "text", text = ~paste("州:", NAME, "\n值:", value)) %>% add_sf(color = ~value) %>% layout( showlegend = TRUE, xaxis = list(visible = FALSE), yaxis = list(visible = FALSE) )
内容的提问来源于stack exchange,提问作者Clark
相关产品推荐
相关产品推荐

