I am plotting the mean, Stdev, skewness and autocorrelation of a dataset but have only been able to plot using xaxt='n'. When I try and add the x-axis my x and y lengths differ. Not sure if the rollapply function is changing the lengths in someway. length($year) and length($yield) are 157 but after I use rollapply the lengths of BK_W_Roll_Mean, SD, Skew and Auto all come up as 128. Trying to understand why rollapply is changing the length and also if there would be an easier way to plot this data then what I am doing. Just trying to get the x-axis label to be years from year1-year2
window.size = 30
BK_W_Roll_Mean <- rollapply(BK_W$Yield,window.size,mean, na.rm = T)
BK_W_Roll_SD <- rollapply(BK_W$Yield,window.size,StdDev, na.rm = T)
BK_W_Roll_Skew <- rollapply(BK_W$Yield,window.size,skewness, na.rm = T)
Moving windows with 'rollapply' function for autocorrelation of lag 1
BK_W_Roll_Auto <- rollapply(BK_W$Yield, window.size, FUN=function(x) acf(x,lag.max = 1, type = "correlation", na.action = na.pass, plot = FALSE)$acf[2])
Moving windows plots
x11(width=40,height=20)
par(mfrow=c(2,2))
plot(BK_W$Year, BK_W_Roll_Mean, type = "l", col = "orange", lwd=2, lty=1, main="example", xlab="Time", ylab="Mean")
plot(BK_W$Year, BK_W_Roll_SD, type = "l", col = "red", lwd=2, lty=1, main="example", xlab="Time", ylab="Std. Deviation")
plot(BK_W$Year, BK_W_Roll_Skew, type = "l", col = "purple", lwd=2, lty=1, main="example", xlab="Time", ylab="Skewness")
plot(BK_W$Year, BK_W_Roll_Auto, type = "l", col = "blue", lwd=2, lty=1, main="example", xlab="Time", ylab="Lag 1 Autocorrelation")
I tried harmonizing the data using [1:length(BK_W$year)] for each of the mean, sd, skew and auto sets which gave a graph with a labled x-axis but the data was off and not set to the right year values.
Also tried adding xlim(year1,year2) but the graph comes up without the trend line. I also tried just running it without xaxt='n' but it came up with a plot from 0-n data points instead of the desired time range in years.
Related
I have data sets containing daily precipitation and discharge data. Now I would like to plot everything in one plot. All data sets are of length 61, so they can share the same x axis. The discharge data should be plotted the "normal" way, meaning that the y axis starts at the bottom and is placed on the left side. The precipitation data should be plotted "from the top", meaning that the y axis is reversed and placed on the right side.
Here is some code for a minimal reproducible example:
precipitation <- runif(61, min=0, max=25)
discharge <- runif(61, min=370, max=2610)
The result should approximately look like this:
Anybody with an idea how to achieve this?
EDIT: thanks pascal for the answer that implies the usage of ggplot2.
I also found a way by myself to do it with Base R, in case it could help anybody in the future:
precipitation <- runif(61, min=0, max=25)
discharge <- runif(61, min=370, max=2610)
# plot with Base R
par(mar = c(5, 5, 3, 5), xpd = TRUE)
plot(precipitation, type= "l", ylim= c(0,80), ylab= "Precipitation [mm/day]", main= "Comparison",
xlab= "Day", col= "blue")
par(new = TRUE)
plot(discharge, type= "l", xaxt = "n", ylim= rev(c(0,5000)), yaxt = "n", ylab = "", xlab = "", col= "red", lty= 2)
axis(side = 4)
mtext("Discharge [m³/s]", side = 4, line = 3)
The ggplot2 way looks a bit fancier of course.
ggplot2 can be used to make plots with a second, inverted axis. One has to specify sec.axis in scale_y_continuous(). I'm using a transformation ((100-x)*100) for your data and apply it to the axis as well, so that it fits. This can be changed to any numbers.
ggplot() +
geom_line(aes(y=precipitation, x=1:61), col="orange") +
geom_line(aes(y=100-discharge/100, x=1:61), col="blue") +
scale_y_continuous(name="rain", sec.axis=sec_axis(~(100-.)*100, name= "discharge"))
Princomp has been used to summarise a large data set, the summary, screeplot and loadings are all functional and all of the code has been repeated from an earlier pca. The code for the plot is also very similar and when it is run, no error is returned but the plot is completely empty.
This happened initially with the original code but the problem seemed to be resolved by running princomp and summary again, this solution has not worked this time.
Plot_chars.abio.pca <-princomp(Plot_chars_standardised[,4:12])
summary(Plot_chars.abio.pca)
Plot_chars.abio.pca$loadings
screeplot(Plot_chars.abio.pca, type="lines")
Plot_chars.abio.pca.var <- Plot_chars.all.pca$sdev^2
Plot_chars.abio.pca.var[1:5]
plot(Plot_chars.abio.pca$x[,1], Plot_chars.abio.pca$x[,2],
bty = "n",
pch = Plot_chars$DomSpec -20,
cex =0.5,
col= Plot_chars$DomSpec -10,
xlim = c(-2,6),
ylim = c(-2,6),
xlab = "PCA1",
ylab = "PCA2")
I was expecting the PC1 & PC2 points plotted but nothing appears
The result from princomp does not contain a column named x. For the scores plot use Plot_chars.abio.pca$scores[, 1] for PC1 and Plot_chars.abio.pca$scores[, 2]. For the loadings plot use Plot_chars.abio.pca$loadings[, 1] for the loadings in PC1 and Plot_chars.abio.pca$loadings[, 2] for the loadings in PC2.
Your example:
plot(Plot_chars.abio.pca$scores[,1], Plot_chars.abio.pca$scores[,2],
bty = "n",
pch = Plot_chars$DomSpec -20,
cex =0.5,
col= Plot_chars$DomSpec -10,
xlim = c(-2,6),
ylim = c(-2,6),
xlab = "PCA1",
ylab = "PCA2")
I use following example code to plot an impulse response function:
# Load data and apply VAR
library("vars")
data(Canada)
data <- Canada
data <- data.frame(data[,1:2])
names(data)
var <- VAR(data, p=2, type = "both")
# Apply IRf
irf <- irf(var, impulse = "e", response = "prod", boot = T, cumulative = FALSE, n.ahead = 20)
str(irf)
plot(irf)
# Response
irf$irf
# Lower & Higher
irf$Lower
irf$Upper
#Create DataFrame and Plot
irf_df <- data.frame(irf$irf,irf$Lower,irf$Upper)
irf_df$T<-seq.int(nrow(irf_df)) #T
irf_df
plot(data.frame(irf_df$T, irf_df[1]), type="l", main="Impulse Response")
abline(h=0, col="blue", lty=2)
It looks like it works so far, though I sense that the code could be improved.
Would it be possible to add a confidence band for the Lower and Upper bounds of the confidence interval?
If you want to plot the Lower and Upper bands, you can use the lines() function, setting the y-limits of the plot if desired.
plot(irf_df$T, irf_df$prod, type="l", main="Impulse Response",
ylim = c(min(irf_df$prod.1), max(irf_df$prod.2)) * 1.1)
abline(h=0, col="blue", lty=2)
lines(irf_df$T, irf_df$prod.1, lty = 2)
lines(irf_df$T, irf_df$prod.2, lty = 2)
For a fancier plot with the confidence band filled in, use polygon. Here, we set up an empty plot, then plot the polygon, and finally overlay the line. Also note here that there's no need to set up a new data.frame: we can simply use values from the irf() output:
plot(irf$irf$e, type = "n", main = "Impulse Response",
ylim = c(min(irf$Lower$e), max(irf$Upper$e)))
polygon(x = c(seq_along(irf$irf$e), rev(seq_along(irf$irf$e))),
y = c(irf$Lower$e, rev(irf$Upper$e)),
lty = 0, col = "#fff7ec")
lines(irf$irf$e)
Output:
I would like to plot a time series (meaning line graph with x axis as time) and specify a plotting character to use. None of the following has worked
a1 = as.xts(ts(c(5,3,7,2,4,8,3), start=c(1980,1), freq=4))
library('lattice')
xyplot(a1, col="red", pch=2)
xyplot(a1, col="red", par.settings = list(superpose.symbol = list(col = 1, pch = 2)),)
ts.plot(ts(a1), pch=2)
plot(a1, phc=2)
I would prefer a lattice solution, but would accept any solution if lattice can not do this.
By default, time series plots in R use type = "l", which means that you get a line but no point characters. To get both, you can change your type to "b".
xyplot(a1, col = "red", pch = 2, type = "b")
This yields:
The same logic applies to the base plot function; simply add type = "b".
I have two columns of data, f.delta and g.delta that I would like to produce a scatter plot of in R.
Here is how I am doing it.
plot(f.delta~x, pch=20, col="blue")
points(g.delta~x, pch=20, col="red")
The problem is this: the values of f.delta vary from 0 to -7; the values of g.delta vary from 0 to 10.
When the plot is drawn, the y axis extends from 1 to -7. So while all the f.delta points are visible, any g.delta point that has y>1 is cut-off from view.
How do I stop R from automatically setting the ylims from the data values. Have tried, unsuccessfully, various combinations of yaxt, yaxp, ylims.
Any suggestion will be greatly appreciated.
Thanks,
Anjan
In addition to Gavin's excellent answer, I also thought I'd mention that another common idiom in these cases is to create an empty plot with the correct limits and then to fill it in using points, lines, etc.
Using Gavin's example data:
with(df,plot(range(x),range(f.delta,g.delta),type = "n"))
points(f.delta~x, data = df, pch=20, col="blue")
points(g.delta~x, data = df, pch=20, col="red")
The type = "n" causes plot to create only the empty plotting window, based on the range of x and y values we've supplied. Then we use points for both columns on this existing plot.
You need to tell R what the limits of the data are and pass that as argument ylim to plot() (note the argument is ylim not ylims!). Here is an example:
set.seed(1)
df <- data.frame(f.delta = runif(10, min = -7, max = 0),
g.delta = runif(10, min = 0, max = 10),
x = rnorm(10))
ylim <- with(df, range(f.delta, g.delta)) ## compute y axis limits
plot(f.delta ~ x, data = df, pch = 20, col = "blue", ylim = ylim)
points(g.delta ~ x, data = df, pch = 20, col = "red")
Which produces