曲线下的渐变填充区域

Posted

技术标签:

【中文标题】曲线下的渐变填充区域【英文标题】:Gradient fill area under curve 【发布时间】:2021-12-23 22:12:55 【问题描述】:

我想用光谱颜色填充曲线下的区域,得到这样的图。

这是我尝试过的

 ggplot(bq, aes(x=w.length, y=s.e.irrad)) +
  geom_segment(aes(xend=w.length, yend=0, colour=abs(w.length)^0.7*sign(w.length))) +
  geom_line() +
  scale_colour_gradient2(low=scales::muted("blue"), 
                         mid=scales::muted("green"), 
                         high=scales::muted("red"))

得到这个

也尝试使用 geom_area

ggplot(bq, aes(x = w.length, y = s.e.irrad))+
  geom_area(fill = "steelblue") #steelblue is for example

但不能用渐变填充

我的数据框在 x 中具有波长,在 y 中具有辐照度

【问题讨论】:

scale_colour_gradientn(colours = c("#0325ff", "#4afd00", "#ff0005")) 这样的东西怎么样? 我认为,如果您想尝试在某种程度上准确地可视化您的光谱颜色,则不应仅在三种颜色之间进行插值,而应以更密集的方式进行插值。无论如何,请提供一些示例数据并提出可重复的问题,否则很难帮助您,更重要的是,将来的人不会从这个问题中受益。 ***.com/help/how-to-ask 有R包ggspectra 【参考方案1】:

以下内容应该与您要查找的内容相近。诀窍是将scale_color_identity 用于geom_segment,并将代表数据帧中每个波长的RGB 字符串传递给颜色美学。

ggplot(bq, aes(x=w.length, y=s.e.irrad)) +
  geom_segment(aes(xend=w.length, yend=0, colour = nm_to_RGB(w.length)),
               size = 1) +
  geom_line() +
  scale_colour_identity()

或者,如果您想要更柔和的外观:

ggplot(bq, aes(x=w.length, y=s.e.irrad)) +
  geom_area(fill = "black") +
  geom_segment(aes(xend=w.length, yend=0, 
                   colour = nm_to_RGB(w.length)),
               size = 1, alpha = 0.3) +
  geom_line() +
  scale_colour_identity()

唯一的缺点是您需要定义nm_to_RGB:将光的波长转换为十六进制字符串以表示颜色的函数。我不确定是否有一种“正确”的方法可以做到这一点,但一种可能的实现方式(我从 javascript 函数 here 翻译而来)是:

nm_to_RGB <- function(wavelengths)
  sapply(wavelengths, function(wavelength) 
  red <- green <- blue <- 0  
  if((wavelength >= 380) & (wavelength < 440))
    red <- -(wavelength - 440) / (440 - 380)
    blue <- 1
  else if((wavelength >= 440) & (wavelength<490))
    green <- (wavelength - 440) / (490 - 440)
    blue <- 1
  else if((wavelength >= 490) && (wavelength<510))
    green <- 1
    blue = -(wavelength - 510) / (510 - 490)
  else if((wavelength >= 510) && (wavelength<580))
    red = (wavelength - 510) / (580 - 510)
    green <- 1
  else if((wavelength >= 580) && (wavelength<645))
    red = 1
    green <- -(wavelength - 645) / (645 - 580)
  else if((wavelength >= 645) && (wavelength<781))
    red = 1
  
  if((wavelength >= 380) && (wavelength<420))
    fac <- 0.3 + 0.7*(wavelength - 380) / (420 - 380)
  else if((wavelength >= 420) && (wavelength<701))
    fac <- 1
  else if((wavelength >= 701) && (wavelength<781))
    fac <- 0.3 + 0.7*(780 - wavelength) / (780 - 700)
  else
    fac <- 0
  
  do.call(rgb, as.list((c(red, green, blue) * fac)^0.8))
  )

显然,我没有您的数据集,但以下代码在正确的范围内创建了一组合理的数据:


数据

set.seed(10)

bq <- setNames(as.data.frame(density(sample(rnorm(5, 600, 120)))[c("x", "y")]),
               c("w.length", "s.e.irrad"))

bq$s.e.irrad <- bq$s.e.irrad * 1e5

【讨论】:

以上是关于曲线下的渐变填充区域的主要内容,如果未能解决你的问题,请参考以下文章

怎么用条件格式将一个区域设置为渐变填充蓝色(标准色)数据条?

30.QT-渐变之QLinearGradient QConicalGradientQRadialGradient

数据可视化应用区域渐变填充折线图(R语言&Python实现)

数据可视化应用区域渐变填充折线图(R语言&Python实现)

如何在R中制作渐变颜色填充时间序列图

Qt 绘图渐变填充