1

To preface the question, I am aware that it is discouraged to plot 2 separate y-axes on a single plot, and that it can be confusing and misleading. However, I have to do it in this case, and am having some trouble having things line up. This area is commonly asked about, but I haven't seen any questions about how to do this when the x-indices are slightly off. Part of this may be due to my handling of POSIX & date objects, so if that fixes it please let me know.

I am trying to plot a time-series of soil moisture data, and compare it with precipitation and other parameters. I've tried to use ggplot2, but it doesn't appear very friendly to doing 2 y-axis plots. The data comes in 2 minute intervals, but processes on annual or larger time-scales are being used. An example of the dataset is below. There is some duplication, since the data comes with Year, Julian Day, and Minute but I combine them into a POSIXlt object for plotting and manipulation.

>to.analyze[1:10,] Rowname Year Julian_Day Minute T_.C. Rel_Humid Precip_.mm. T_5cm T_10cm T_20cm T_50cm T_100cm Moist_5cm Moist_10cm Moist_20cm Moist_50cm Moist_100cm TOD Year.Month cumRain 2015.137.1 2015 137 0 18.85 19.83 0 31.88 30.08 25.66 21.36 20.6 0.046 0.054 0.07 0.125 0.134 5/17/2015 12:00:00 AM 2015.May 0 2015.137.2 2015 137 2 18.99 19.15 0 31.8 30.06 25.66 21.37 20.6 0.047 0.054 0.07 0.125 0.134 5/17/2015 12:02:00 AM 2015.May 0 2015.137.3 2015 137 4 19.12 20.3 0 31.72 30.03 25.69 21.37 20.6 0.047 0.054 0.07 0.125 0.134 5/17/2015 12:04:00 AM 2015.May 0 2015.137.4 2015 137 6 18.99 21.65 0 31.64 30.01 25.7 21.37 20.6 0.046 0.054 0.07 0.125 0.134 5/17/2015 12:06:00 AM 2015.May 0 2015.137.5 2015 137 8 18.68 22.59 0 31.55 29.98 25.72 21.37 20.6 0.046 0.054 0.07 0.125 0.134 5/17/2015 12:08:00 AM 2015.May 0 2015.137.6 2015 137 10 18.16 23.69 0 31.47 29.96 25.72 21.37 20.6 0.046 0.054 0.07 0.125 0.134 5/17/2015 12:10:00 AM 2015.May 0 2015.137.7 2015 137 12 17.69 24.8 0 31.38 29.93 25.75 21.37 20.6 0.047 0.054 0.07 0.125 0.134 5/17/2015 12:12:00 AM 2015.May 0 2015.137.8 2015 137 14 18.06 23.73 0 31.3 29.9 25.75 21.37 20.6 0.046 0.054 0.07 0.125 0.134 5/17/2015 12:14:00 AM 2015.May 0 2015.137.9 2015 137 16 18.39 22.97 0 31.2 29.88 25.77 21.37 20.6 0.046 0.054 0.07 0.125 0.134 5/17/2015 12:16:00 AM 2015.May 0 2015.137.10 2015 137 18 18.47 22.96 0 31.11 29.84 25.77 21.37 20.6 0.047 0.054 0.07 0.125 0.134 5/17/2015 12:18:00 AM 2015.May 0 

EDIT: full data found here: http://dropcanvas.com/#Bl4hJG9Y4yfg5j (to large to paste)

The Year.Month value is a factor with n values, where n are the number of unique month/year combinations selected. I'm using this to get boxplots of monthly groups. I want to plot the raw data for soil moisture at a depth, then the boxplots of the monthly data on top of it, and then add on monthly precipitation bins. Monthly bins for precipitation come from:

short.sumRain <- aggregate(Precip_.mm. ~ Year.Month, to.analyze, sum) 

The issue can be seen in the following plot.

plot(to.analyze$TOD,to.analyze[, "Moist_10cm"], xlab = "Time", ylab = "Volumetric Water Content", type = "l", xaxt = "n", main = main, ylim = c(0, .3)) r <- as.POSIXct(range(to.analyze$TOD)) axis.POSIXct(1, at = seq(r[1],r[2], by = "months"), labels = TRUE, format = "%Y-%m", las = 1, cex = 0.1) # Add boxplot par(new = TRUE) boxplot(to.analyze$Moist_10cm ~ to.analyze$Year.Month, range = 0, type = "l", xaxt = "n", yaxt = "n", ylim = c(0, .3), boxwex = 0.3) # Add monthly rainfall sums par(new = TRUE) plot(short.sumRain$Precip_.mm., type = "o", col = "blue", xaxt = "n", yaxt = "n", xlab = "", ylab = "", pch = 1) axis(4) mtext("Precip (mm)", side = 4, line = 1.5) 

Which produces the following plot: VWC plot

The precipitation label gets cut off a bit (not sure why R is doing that, but if line gets smaller it just appears on top of the labels), and the precipitation points don't match up with the tick-marks from the points plot. I think it is because the first plot is being drawn with a POSIX x-axis, and the other is not, but how can I get those 2 to line-up?

2
  • Could you provide that data in a reproducible format or use built in data for your example? Commented Jun 23, 2016 at 17:54
  • 1
    I put up the full dataset. Commented Jun 23, 2016 at 18:07

1 Answer 1

1

I think the back ground of your problem is POSIXct class. as.numeric( as.POSIXct("2011-01-01", "GMT") ) is 1293840000 and this is the real coordinate value.
In default, boxplot() changes xy-coordinates and uses 1, 2, ~ as x-positions of them. Argument add=T makes boxplot() uses current coordinates and argument at gives the locations.
When you use 2 separate y-axes, it's safer to use the same xlim.

to.analyze <- read.csv("FMS.to.analyze.csv") # read the data to.analyze$r <- as.POSIXct(to.analyze$TOD) # do class change first and add it as a new column levels(to.analyze$Year.Month) # I didn't use Year.Month because of alphabetical levels. to.analyze$Year.Month2 <- substr(to.analyze$r, 1, 7) # make a new column, Year.Month2 by extracting POSIXct class data short.sumRain <- aggregate(Precip_.mm. ~ Year.Month2, to.analyze, sum) x.range <- as.POSIXct(c("2013-05-01", "2013-09-01")) # decide the x-range on plot x.month <- as.numeric( as.POSIXct(paste0( unique(to.analyze$Year.Month2), "-15")) ) # decide the day where boxplot and short.sumRain's points are. (I used 15th of every month) # (paste0() joins year-month to -day. as.numeric(as.POSIXct()) calculate the real value.) par(mar=c(4, 4.2, 2.5, 4.2)) # set margin (down, left, up, right) plot(Moist_10cm ~ r, to.analyze, xlab = "Time", xaxt = "n", ylab = "Volumetric Water Content", main = "FMS", type = "l", ylim = c(0, .3), xlim = x.range) # set xlim = x.range axis.POSIXct(1, at = seq(x.range[1], x.range[2], by = "months"), labels = TRUE, format = "%Y-%m", las = 1, cex = 0.1) # you can draw additional other depth data by succeeding code. # lines(Moist_100cm ~ r, to.analyze, col = "gray") # use boxplot()'s arguments add=T and at. (If you don't want transparency, please delete col = "#00000020") boxplot(Moist_10cm ~ Year.Month2, to.analyze, boxwex = 900000, at = x.month, axes = F, col = "#00000020", add = T) par(new = TRUE) ### HERE, the first xy-coordinates are reset. plot(short.sumRain$Precip_.mm. ~ x.month, type = "o", col = "blue", axes=F, ann=F, xlim = x.range) # use the same xlim axis(4) mtext("Precip (mm)", side = 4, line = 2) # If you needn't keep TOD and/or Year.Mont, you can overwrite it # (e.g., to.analyze$TOD <- as.POSIXct(to.analyze$TOD) ) instead of making a new column. 

enter image description here

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.