Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to force splinefun values to be positive?

Tags:

r

ggplot2

spline

I have generated a ggplot using values from splinefun, but the values aren't supposed to be negative within the area near 0, as shown in the figure below.

I wonder how to force the values in splinefun to be 0 when they are negative? Thank you!

sigma <- c(0,1,2,3,4,5,6,7,8,9,10,11,12)
sigma <- matrix(sigma,ncol=1)

myFunc_sig <- function(sigma){
  exp(-2/sigma^2)
}

output_sigma <- apply(sigma, 1, myFunc_sig)
spl_fun <- splinefun(sigma, output_sigma)

ggplot(data.frame(x = sigma, y = output_sigma), aes(x, y))+ 
  stat_function(fun = spl_fun, color = "orange")+
  scale_x_continuous(expand = c(0, 0)) + 
  scale_y_continuous(expand = c(0, 0))

The image is in this link

like image 706
Lucifer Avatar asked Dec 15 '17 19:12

Lucifer


1 Answers

You can require the spline function to be monotonic by specifying method="monoH.FC" or method="hyman" in splinefun. For example:

library(tidyverse)

myFunc_sig <- function(sigma){
  exp(-2/sigma^2)
}

sigma = 0:12
output_sigma <- myFunc_sig(sigma)
spl_fun <- splinefun(sigma, output_sigma, "monoH.FC")

ggplot(data.frame(x=sigma,y=output_sigma),aes(x,y)) + 
  stat_function(fun = spl_fun, color = "orange") +
  geom_point() +
  scale_x_continuous(expand = c(0, 0.1)) + 
  scale_y_continuous(expand = c(0, 0.02)) +
  theme_bw()

enter image description here

And with method="hyman" the plot looks like this:

enter image description here

If, for some reason, you did want to make artificial adjustments to the values, you could calculate them outside ggplot and plot them with geom_line. For example:

x = seq(min(sigma),max(sigma),length=100)
y = spl_fun(x)

# Set negative values to zero
y[y<0] = 0

ggplot() + 
  geom_line(data=data.frame(x,y), aes(x,y), colour="orange") +
  geom_point(data=data.frame(x=sigma, y=output_sigma), aes(x,y)) +
  scale_x_continuous(expand = c(0, 0.1)) + 
  scale_y_continuous(expand = c(0, 0.02)) +
  theme_bw()

enter image description here

like image 167
eipi10 Avatar answered Nov 02 '22 21:11

eipi10