controlling x-axis time stamp on filled.contour plot - R - r

I have been looking at the documentation but I cannot figure out how to control the time stamp on the x-axis of a filled.contour() plot in R. I have tried axis.POSIXct() and plot.axes = {}. But neither works for me.
Here is my simplified example:
x1 <- seq(as.Date("2016-01-01"),as.Date("2018-07-01"),by="month")
z1 <- c(0.45062130 ,0.51136174 ,0.6 ,0.8 ,0.29481738 ,0.6 ,0.27713756 ,0.62638512 ,0.23547530,0.29253901 ,0.75899501 ,0.67779756 ,0.51831742 ,0.08050147 ,0.71183739 ,0.13154414 ,0.79406706 ,0.13154414,0.03434758 ,0.59573892 ,0.22102821 ,0.13154414 ,0.13154414 ,0.13154414 ,0.13154414 ,0.13154414 ,0.23692593,0.95215104 ,0.38810846 ,0.17970580 ,0.05176054)
z2 <- z1^2
z3 <- z2^2
df <- data.frame(x1,z1,z2,z3)
time <- c(x1)
depths <- c(1,2,3)
temp2 <- as.matrix(data.frame(df$z1,df$z2,df$z3))
temp2<- matrix(temp2,ncol=ncol(temp2), dimnames = NULL)
filled.contour(time,depths,temp2, col=(matlab.like2(28)),
ylab="Depth", xlab="Time",
key.title=title(expression(' Temp ('*degree*'C)')),xaxs="i")
Which outputs:
X-axis labels are in year format. I would like the format to be %b-%y for every month (e.g. May-16, June-16 etc). How do I do this?

Here's how to do it using the plot.axes option with axis.Date.
filled.contour(time,depths,temp2, #col=(matlab.like2(28)),
ylab="Depth", xlab="Time",
plot.axes = { axis.Date(side=1,x=time,at=time,format="%b-%y"); axis(2) },
key.title=title(expression(' Temp ('*degree*'C)')),xaxs="i")

Related

R - Date Format in plots

My plot is displaying weird numbers instead of dates. When converting them I find today's date. The issue is that I'm studying past dates. I would like to display on the chart below, the dates corresponding to the values.
This is the Data Frame:
I already converted dates using:
dates <- lubridate::mdy(rv_data_USDC_DAILY$Date)
This is my code for the plot:
par(mfrow = c(1, 2))
plot.ts(x=df_peg$date, y=df_peg$BUSDPEG, type="l", main = "", col="#1F4690", ylab="USD")
abline(h=0)
mtext("BUSD Deviations from Peg")
hist(df_peg$BUSDPEG, xlim = c(-0.01,0.01), main="", col="#D61C4E")
Sample of Data:
date BUSDPEG USDCPEG DAIPEG GEMINIPEG HUSDPEG PAXPEG STASISPEG
1 2022-06-29 -2.383111e-03 0.00010 -0.0044920717 2.048424e-03 -1.543622e-04 1.639760e-02 -0.04452180
2 2022-06-28 -1.414367e-03 0.00005 -0.0020128418 1.531139e-03 -3.612265e-04 1.710005e-02 -0.03907985
Thanks
You can use the plot function only when you want to use dates. It works very well. Here is an example :
date <- seq(from = as.Date("2001-01-01"), to = as.Date("2020-01-01"), by = "quarter")
returns <- rnorm(n = length(date))
plot(x = date, y = returns, type = "l")

R Language, how to create a timeseries from dataframe with datetime and value columns

I have a simple data frame, observations_df, with two columns DateTime and Value:
2002-03-28T19:30:00, 23.53, ...
How to create a time series from data frame observations_df and show time series in graph?
Tutorials are very rich and complex.I have tried different approaches unsuccessfully.
Does this answer your question?
library(tidyverse)
df <- tibble(
date = Sys.Date() + 0:10,
value = runif(n = 11)
)
df %>%
ggplot(aes(x = date, y = value)) +
geom_line()
First you may use ts to create a time series "ts" object.
dat.ts <- ts(dat[,2], start=dat[1,1], end=dat[nrow(dat),1])
# Time Series:
# Start = 18263
# End = 18292
# Frequency = 1
# [1] 0.16804153 0.80751640 0.38494235 0.32773432 0.60210067 0.60439405 0.12463344 0.29460092
# [9] 0.57760992 0.63097927 0.51201590 0.50502391 0.53403535 0.55724944 0.86791949 0.82970869
# [17] 0.11144915 0.70368836 0.89748826 0.27973255 0.22820188 0.01532989 0.12898156 0.09338193
# [25] 0.23688501 0.79114741 0.59973157 0.91014771 0.56042455 0.75570477
Then, actually there is a plot method and you could just do plot(dat.ts). However, "ts" objects store dates numerically, and we want to read "real" dates on the x-axis and therefore probably want to do a manual axis labeling with somewhat "thinned out" elements from the date column using e.g. modulo %%.
labs <- dat$datetime[as.numeric(substr(dat$datetime, 9, 10)) %% 7 == 0]
plot(dat.ts, xaxt="n", main="My Title", col=2, xlab="time", ylab="value")
axis(1, labels=F, at=dat$datetime, tck=-.01)
axis(1, labels=F, at=labs, tck=-.03)
mtext(as.character(labs), 1, 1, at=labs)
legend("topleft", lty=1, legend="time series xy", col=2)
Toy data used
set.seed(3)
dat <- data.frame(datetime=as.Date(seq(1:30), "2020-01-01"),
value=runif(30))

R: Generate sine wave with variable frequency

This might be more of a math question than an R question but here it goes...
I'm trying to generate a low frequency oscillator (LFO2) where the frequency is controlled by another low frequency oscillator (LFO1). LFO1 has a frequency of 0.02 Hz while I want LFO2 to have a frequency that oscillates between 0.00 and 0.11 Hz dependent on the output of LFO1.
# length in seconds
track_length <- 356
upsample <- 10 # upsample the signal
# LFO rates (Hz)
rate1 <- 0.02
rate2_range <- list(0.00, 0.11)
# make plot of LFO1
x1 <- 1:(track_length*upsample)/upsample
amp <- (rate2_range[[2]] - rate2_range[[1]])/2
y1 <- amp*cos(2*pi*rate1*x1) + amp
plot(x1, y1, type='l')
The variable frequency for LFO2 generated by LFO1 looks exactly as I expected.
So I go on to make LFO2 using the output of LFO1 like so..
# make plot of LFO2
x2 <- x1
y2 <- cos(2*pi*y1*x2)
plot(x2, y2, type='l')
However, the output of LFO2 is not what I expected... It seems to be continuously getting faster and also has some peaks that don't oscillate at the full range. I don't understand this as the only thing I'm adjusting is the frequency and it shouldn't be faster than 0.11 Hz. At first I thought it might be an under sampling issue but I get the same results when upsampling the time series to any degree.
Any idea what I'm missing here?
The "frequency" of cos(f(t)) is not f(t). It's the derivative of f(t).
You have:
y1(t) = A*cos(2πf1t) + A
y2(t) = cos(2πy1(t))
If the frequency you want is Acos(2πf1t) + A, then you need to integrate that to get the argument to cos:
y1(t) = A*sin(2πf1t)/2πf1 + At
y2(t) = cos(2πy1(t))
In R:
# length in seconds
track_length <- 356
upsample <- 10 # upsample the signal
# LFO rates (Hz)
rate1 <- 0.02
rate2_range <- list(0.00, 2)
# make integral of LFO1
x1 <- 1:(track_length*upsample)/upsample
amp <- (rate2_range[[2]] - rate2_range[[1]])/2
y1 <- amp*sin(2*pi*rate1*x1)/(2*pi*rate1) + amp*x1
plot(x1, y1, type='l')
# make plot of LFO2
x2 <- x1
y2 <- cos(2*pi*y1 / upsample)
plot(x2, y2, type='l')
You are not restricting the data by amp as you did at the first plot. So it is normal to see cos output altering around -1 and 1.You need to restrict the formula by the max(y1) and min(y1).
So the codes below,
y2 <- vector()
amp <- (max(y1) - min(y1))/2
for(i in 1:length(y1)) {
y2[i] <- amp * cos(2*pi* y1[i] * x2) + amp
}
plot(x2, y2, type='l',col="blue")
grid(nx = NULL, ny = NULL, col = "lightgray", lty = "dotted")
gives this plot,

How to create custom indicator? Slope of the line of 50 day EMA

I have been creating a few technical indicators using Quantmod's NewTa function.
I've been trying to create a custom indicator that ideally should be charted using ChartSeries. This indicator should show the slope of the line of the 50 day EMA of the adjusted closing price.
getSymbols("NOVO-B.CO")
p <- na.omit('NOVO-B.CO')
FiftyEMA <- function(x){
MA <- removeNA((EMA(p[,6],n=50)))
}
SlopeFiftyEMA <- function(x){
run=(FiftyEMA(y)/FiftyEMA(x))
}
Slope.Indicator <- newTA(SlopeFiftyEMA,legend.name = "50 Day EMA Slope of Line Indicator")
Slope.Indicator()
This gives me the error: Error in get.current.chob() : improperly set or missing graphics device
I also tried a new code that gives me an actual INDICATOR! Please let me know what you think (if you think it looks correct or not):
First I export the data to excel: (the stock data is still denoted as p)
write.csv(p,"data")
import data
x <- data[,1]
y <- data[,7]
MA <- removeNA(EMA(y,n=50))
length(MA)
length of MA = 1923
l=1:1923
SlopeFiftyEMA <- function(x){
(diff(MA)/diff(l))
}
Slope.Indicator <- newTA(SlopeFiftyEMA,legend.name = "50 Day EMA Slope of Line Indicator")
twelvemonths="last 12 months"
chartSeries(p,subset = twelvemonths,theme = 'white',up.col = 'blue',dn.col = 'grey',name ="Custom Indicators")
Slope.Indicator()
Any Input anyone? Last time I posted there was no indicator
Thanks in advance!
Your first error seems to exist because you don't call chartSeries before calling Slope.indicator(). But your code is a bit messy, including not defining y (maybe you introduce it later in import data).
The approach presented here will plot the slope of the MA according to linear regression, using chart_Series (arguably cleaner plots than the original chartSeries). Two types of slopes are computed, including the one you proposed, which is the differences of the EMA.
getSymbols(c("NOVO-B.CO"))
x <- `NOVO-B.CO`
x[, c(1:4, 6)] <- na.locf(x[, c(1:4, 6)])
x$EMA <- EMA(Cl(x), n = 50)
x <- merge(x, rollSFM(Ra = x[, "EMA"], Rb = 1:NROW(x), n = 20))
x <- merge(x, setNames(diff(x$EMA), "diff1"))
chart_Series(x, subset = "2016/")
add_TA(x$EMA, on = 1, col = "purple")
# Plot the slope of the MA:
add_TA(x$beta, col = "green")
# Plot the 1 lag diff of the moving average:
add_TA(x$diff1, lty = 2)

Change axis and mirror graph to complete non-linear surface in R

I hope you can help me to solve this issue, I've been trying different things but nothing work so far:
I have a 3D graph that is using a squared term (x2) on the x axis (values go from 0 to 100). The original x has positive and negative values (values go from -10 to 10). In x2 and therefore in the X axis of my 3D graph the values are all positive. Thinking that x2=100 is the value obtained from x=-10^2 and x=10^, x2=25 comes from x= -5^2 and x=5^2 and so on. I have only "half" of the graph and I would like to:
1) Have the graph with the original scale going from -10 to 10 on the X axis.
2) Complete the other half of the graph to have the non-linear relationship (i.e. to complete the surface that corresponds from -10 to 0, which I assume should be a mirror of the one I have right now).
Using different colours you can see better the nonlinear relationship, but I didn't include them here to simplify the code.
Since it is not possible to get the negative values back to plot x because the square root will be always positive, I duplicated the data in Excel. I added negative values (values now go from -100 to 100), I made an R list again. This is not a solution because it still has the same scale of x2, but anyways it doesn’t work.
This is how I plot the graph:
Data: https://www.dropbox.com/s/fv943jf35eqtkd8/NSSH.csv?dl=0
link function code:
logexp <- function(days = 1)
{
linkfun <- function(mu) qlogis(mu^(1/days))
linkinv <- function(eta) plogis(eta)^days
mu.eta <- function(eta) days * plogis(eta)^(days-1) *
.Call("logit_mu_eta", eta, PACKAGE = "stats")
valideta <- function(eta) TRUE
link <- paste("logexp(", days, ")", sep="")
structure(list(linkfun = linkfun, linkinv = linkinv,
mu.eta = mu.eta, valideta = valideta, name = link),
class = "link-glm")
}
The 3D graph:
library(akima)
x <- NSSH$reLDM
x2<- x^2
y <- NSSH$yr
y2 <-y^2
n <-NSSH$AgeDay1
z <- NSSH$survive
m <- glm(z~x2+y+y2+x2:y+n,family=binomial(link=logexp(NSSH$exposure)))
# interaction
i <- 25
xtemp <- seq(min(x),max(x),length.out=i)
xrange <- rep(xtemp,times=i)
x2temp <- seq(min(0),max(100),length.out=i)
x2range <- rep(x2temp,times=i)
ytemp <- seq(min(y),max(y),length.out=i)
yrange <- rep(ytemp,each=i)
y2temp <- seq(min(y2),max(y2),length.out=i)
y2range <- rep(y2temp,each=i)
ntemp <- rep(mean(n),times=i)
nrange <- rep(ntemp,times=i)
newdata <- data.frame(x2=x2range,y=yrange,y2=y2range,n=nrange)
zhat <- predict(m,newdata=newdata)
NS <- zhat^27
xyz <- interp(x2range,yrange,NS)
quartz()
persp(xyz,
theta = 35, phi = 50,col="blue", border="grey40", ticktype = "detailed", zlim=c(0,1)) -> res2
Is there a way I can copy the "half" graph I have as a “mirror” and put it next to the part I already have and use the original scale from x?
Thanks a lot for your help!
UPDATE:
The 3D graph is perfect!
But when I use the "half graph" to make a contour plot it looks like this:
And now with the new graph it looks like this, I wonder why the origin around 0 next to the value 0.7 (area in the red circle) doesn't look the same as the first contour plot. Do you have any idea? is it possible to fix it? Thanks again.
this is the code of the contour plot:
image(xyz2,col = "white")
contour(xyz2,add=T)
I think you don't have to worry about the small things with the exception that make X and Y increase and dim(Z) are c(length(X), length(Y)) .
xyz2 <- interp(sqrt(x2range), yrange, NS) # change scale before interpolate
xyz2$x <- c(rev(xyz2$x)*-1, xyz2$x) # reverse and combine
xyz2$x[41] <- 1.0E-8 # because [40] = [41] = 0 (40 is interp's nx value)
xyz2$z <- rbind(apply(xyz2$z, 2, rev), xyz2$z) # reverse and combine
persp(xyz2,xlab="Relative laying date",ylab="Year",zlab="Nest success",
theta = 35, phi = 50,col="blue", border="grey40", ticktype = "detailed")
[EDITED]
I can't reproduce your additional question.
origin <- list(x = unique(x2range),
y = unique(yrange),
z = matrix(NS, ncol=length(unique(yrange))))
xyz <- interp(x2range,yrange,NS) # OP's code
image(origin, col = "white", xlim=c(-10,10), ylim=c(7, 24))
contour(origin, add=T, lwd=1.5, drawlabels=F) # no interp : black
contour(xyz, add=T, col=2, drawlabels=F) # OP's code : red
contour(x=sqrt(xyz$x), y=xyz$y, z=xyz$z, add=T, col=3, drawlabels=F) # only scale change : green
contour(xyz2, add=T, col=4, drawlabels=F) # my code : blue

Resources