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

如何对时间线上的点插值以绘制浓度随时间变化的平滑色块图

R ggplot实现X物质浓度时间序列水平插值平滑图

原代码使用geom_tile(interpolate = T)是图形渲染层面的双向插值,会同时在时间轴、样本位置两个方向做平滑,不符合仅沿时间方向水平插值的需求,同时y轴默认显示数值刻度,未映射到样本名称。以下是两种可行实现方案:


方案1:调整geom_tile参数快速实现

通过固定色块高度避免y轴方向的插值,仅保留时间方向的平滑效果,代码改动量最小:

library(tidyverse)

# 生成测试数据
df <- data.frame(Concentration = rnorm(30), 
                 Position = rep(c(0, 1), 15), 
                 Sample = rep(c("A", "B"), 15), 
                 Date = seq.Date(as.Date("2020-01-01"), as.Date("2020-01-30"), "days"))

df %>% 
  ggplot(aes(x = Date, y = Position)) +
  # 固定色块高度为0.9,避免上下两个样本的色块互相插值
  geom_tile(aes(fill = Concentration),
            height = 0.9,
            interpolate = T) +
  # 替换y轴刻度为样本名
  scale_y_continuous(breaks = c(0, 1), labels = c("A", "B")) +
  labs(x = "Day", y = "Sample", fill = "X物质浓度") +
  # 可选:调整为更易读的渐变色
  scale_fill_viridis_c()

该方案无需修改原始数据,适合快速出图场景。


方案2:数据层面先插值再绘图(平滑效果更可控)

如果需要自定义平滑精度,可先对每个样本的浓度时间序列做高密度插值后再绘图:

library(tidyverse)

df <- data.frame(Concentration = rnorm(30), 
                 Position = rep(c(0, 1), 15), 
                 Sample = rep(c("A", "B"), 15), 
                 Date = seq.Date(as.Date("2020-01-01"), as.Date("2020-01-30"), "days"))

# 按样本分组做时间插值,时间密度可按需调整,示例为间隔6小时一个插值点
interp_df <- df %>%
  group_by(Sample, Position) %>%
  summarise(
    Date = seq.Date(min(Date), max(Date), by = "6 hours"),
    # 线性插值,替换为splinefun可实现样条插值,平滑度更高
    Concentration = approx(Date, Concentration, xout = Date)$y,
    .groups = "drop"
  )

interp_df %>%
  ggplot(aes(x = Date, y = Position)) +
  geom_tile(aes(fill = Concentration), height = 0.9) +
  scale_y_continuous(breaks = c(0, 1), labels = c("A", "B")) +
  labs(x = "Day", y = "Sample", fill = "X物质浓度") +
  scale_fill_viridis_c()

该方案平滑效果完全由数据插值逻辑控制,不会出现渲染层异常插值问题,适合对精度要求高的场景。


内容的提问来源于stack exchange,提问作者Lee1010

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 14:06:03