R语言新手求助:使用ggplot绘制盐度数据时遇报错问题
问题解决:R语言用ggplot绘制盐度栅格地图
错误原因分析
第一次错误
你误用了geom_sf()——这个函数专门用来绘制矢量地理数据(比如shapefile、sf格式对象),但你的数据是栅格格式的经纬度+数值,两者完全不匹配,因此会报错要求geometry参数。
第二次错误
直接把多维数组转成dataframe后,数据结构完全混乱:
correct.latlong[,,1]是66×164的矩阵,展开后长度为66×164=10824region.df是把66×164的盐度数组转成了66行164列的dataframe,ggplot默认只识别它的行数(66),导致x/y/fill的长度不匹配,触发报错。
正确处理步骤
核心是把多维数组转成长格式dataframe,让每一行对应一个网格点的纬度、经度、盐度值。
1. 处理单一层深度的数据(以深度1为例)
# 提取单一层的盐度、纬度、经度矩阵 salinity_layer <- vosaline[944:1009, 160:323, 1] lat_matrix <- nav_latlong[944:1009, 160:323, 1] lon_matrix <- nav_latlong[944:1009, 160:323, 2] # 把矩阵转成一维向量,再组合成标准dataframe plot_df <- data.frame( lat = as.vector(lat_matrix), lon = as.vector(lon_matrix), salinity = as.vector(salinity_layer) ) # 绘制栅格图 library(ggplot2) ggplot(plot_df, aes(x = lon, y = lat, fill = salinity)) + geom_raster() + scale_fill_viridis_c(name = "盐度") + # 用渐变颜色更直观 coord_fixed() # 保持地理坐标比例,避免失真
2. 处理所有75层深度(分面展示)
如果要一次性展示所有深度的盐度分布,可以把整个三维数组转成长格式,添加深度列后分面绘制:
# 加载工具包整理数据 library(tidyr) library(dplyr) # 提取所有深度的盐度数据 all_salinity <- vosaline[944:1009, 160:323, ] # 把盐度数组转成长格式,保留行列索引(对应经纬度的网格位置) salinity_long <- as.data.frame.table(all_salinity) %>% rename(row = Var1, col = Var2, depth = Var3, salinity = Freq) %>% mutate(depth = as.integer(depth)) # 把深度转成数值型 # 提取经纬度的一维向量,生成带行列索引的经纬度表 lat_vec <- as.vector(nav_latlong[944:1009, 160:323, 1]) lon_vec <- as.vector(nav_latlong[944:1009, 160:323, 2]) latlon_df <- data.frame( row = rep(1:66, each = 164), col = rep(1:164, 66), lat = lat_vec, lon = lon_vec ) # 合并盐度与经纬度数据 full_df <- left_join(salinity_long, latlon_df, by = c("row", "col")) # 分面绘制所有深度的盐度图 ggplot(full_df, aes(x = lon, y = lat, fill = salinity)) + geom_raster() + scale_fill_viridis_c(name = "盐度") + coord_fixed() + facet_wrap(~depth, ncol = 10) # 按深度分面,每行展示10个图
关键注意点
- 多维数组直接转dataframe会打乱结构,必须先将每个维度的元素转成一维向量,再对应组合。
- 栅格数据用
geom_raster()或geom_tile(),geom_sf()仅适用于矢量地理数据。 - 地理绘图务必添加
coord_fixed(),避免坐标比例失真。
内容的提问来源于stack exchange,提问作者Fish_Person
相关产品推荐
相关产品推荐

