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

如何使用ggplot2绘制平滑的等高线图?

如何使用ggplot2绘制平滑的等高线图?

嗨,我完全懂你的困扰——你用geom_contour_filled画出来的不是平滑等高线,核心问题在于你的原始数据是稀疏的离散网格点,ggplot的等高线函数没法直接从这么少的点生成流畅的曲线,得先对数据做插值处理,把稀疏点转换成密集网格,才能画出平滑的效果。

下面给你两种简单好用的解决方法:

方法一:用akima包做二维插值(最直观)

这个包专门处理二维数据插值,操作非常简单:

  1. 先安装并加载需要的包:
install.packages("akima")  # 首次使用需要安装
library(ggplot2)
library(akima)
library(tidyr)  # 用来整理数据格式
  1. 对原始数据插值,生成密集网格:
# 用interp生成插值后的密集数据,n参数控制网格密度,数值越大越平滑
interp_result <- interp(x = NigerianData$Nweight, 
                        y = NigerianData$Pweight, 
                        z = NigerianData$Yield,
                        n = 100)  # 生成100×100的密集网格

# 把插值结果转换成ggplot能识别的数据框格式
interp_df <- as.data.frame(interp_result)
# 把宽格式数据转成长格式,方便ggplot调用
interp_df <- pivot_longer(interp_df, cols = -x, names_to = "y", values_to = "Yield")
# 把y列的字符标签转换成数值
interp_df$y <- as.numeric(gsub("V", "", interp_df$y))
  1. 用插值后的数据绘制平滑等高线:
ggplot() +
  geom_contour_filled(data = interp_df, aes(x = x, y = y, z = Yield)) +
  geom_contour(data = interp_df, aes(x = x, y = y, z = Yield), color = "black", size = 0.3) +  # 加黑色等高线线条
  scale_fill_viridis_c(option = "plasma") +  # 可选:用更美观的渐变配色
  labs(title = "Contourplot of Yield at different fertilizer concentrations",
       x = "Nitrogen Rates",
       y = "Phosphate Rates",
       fill = "Yield") +
  theme_minimal()

方法二:用mgcv包拟合曲面(适合复杂数据)

如果你的数据不是规则网格,或者想要更精准的曲面拟合,可以试试这个方法:

  1. 安装加载包:
install.packages("mgcv")
library(mgcv)
  1. 生成密集网格并拟合预测:
# 创建覆盖所有N、P浓度范围的密集网格
new_grid <- expand.grid(Nweight = seq(min(NigerianData$Nweight), max(NigerianData$Nweight), length.out = 100),
                        Pweight = seq(min(NigerianData$Pweight), max(NigerianData$Pweight), length.out = 100))

# 用gam模型拟合曲面
gam_model <- gam(Yield ~ s(Nweight, Pweight), data = NigerianData)
# 预测每个网格点的产量值
new_grid$Yield <- predict(gam_model, newdata = new_grid)
  1. 绘制平滑等高线图:
ggplot(new_grid, aes(x = Nweight, y = Pweight, z = Yield)) +
  geom_raster(aes(fill = Yield), interpolate = TRUE) +  # 平滑填充底色
  geom_contour(color = "black", size = 0.3) +
  scale_fill_viridis_c(option = "magma") +
  labs(title = "Smooth Contourplot of Yield",
       x = "Nitrogen Rates",
       y = "Phosphate Rates",
       fill = "Yield") +
  theme_bw()

为什么原始代码没效果?

你手里的NigerianData只有12个点,是3个氮水平×4个磷水平的稀疏网格,geom_contour_filled只能基于这些离散点生成生硬的分段线条,没有足够的数据点支撑平滑效果。插值后生成的密集网格(比如100×100=10000个点)就能让等高线变得流畅自然啦。

备注:内容来源于stack exchange,提问作者Karim Kahtaoui

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.17 08:55:33