Repeating x axis R - r

I have data with the amount of radiation at a specific time (hour, minutes) for three repeating days. I want to plot this so the x-axis goes from 0 - 24 3 times. So the x axis repeats itself. And on the y axis the amount of radiation. I have tried the following script without any succes.
plot(gegevens[,1],gegevens[,2],type='l',col='red',xaxt='n',yaxt='n',xlab='',ylab='')
axis(1, at=(0:74),labels = rep.int(0:24,3), las=2)
mtext('Zonnetijd (u)', side=1,line=3)
The dataset was to big so I've selected the first two hours from 2 days. The first column is the time en the second is the radiation. The data then looks as followed:
structure(c(0, 0.083333333333333, 0.166666666666667, 0.25, 0.333333333333333,
0.416666666666667, 0.5, 0.583333333333333, 0.666666666666667,
0.75, 0.833333333333333, 0.916666666666667, 1, 1.08333333333333,
1.16666666666667, 1.25, 1.33333333333333, 1.41666666666667, 1.5,
1.58333333333333, 1.66666666666667, 1.75, 1.83333333333333, 1.91666666666667,
0.0158590638878904, 0.0991923972212234, 0.182525730554557, 0.26585906388789,
0.349192397221223, 0.432525730554557, 0.51585906388789, 0.599192397221223,
0.682525730554557, 0.76585906388789, 0.849192397221223, 0.932525730554557,
1.01585906388789, 1.09919239722122, 1.18252573055456, 1.26585906388789,
1.34919239722122, 1.43252573055456, 1.51585906388789, 1.59919239722122,
1.68252573055456, 1.76585906388789, 1.84919239722122, 1.93252573055456,
0.066, 0.066, 0.068, 0.068, 0.068, 0.066, 0.066, 0.066, 0.066,
0.066, 0.066, 0.066, 0.057, 0, 0, 0, -0.002, 0, 0, -0.002, 0,
-0.002, -0.009, -0.011, 0, -0.002, 0, -0.002, 0, -0.002, 0, 0.002,
0, 0, 0, 0, -0.002, -0.002, -0.007, 0, -0.002, 0, 0, 0, -0.002,
-0.002, -0.002, 0), .Dim = c(48L, 2L), .Dimnames = list(NULL,
c("t", "z")))

I think you would be better off to move towards a date/time class for your axis. Then you can have more control on what to plot etc. Below is an example:
# create example data
df <- data.frame(
T = seq.POSIXt(as.POSIXct("2000-01-01 00:00:00"),
by = "hours", length.out = 24*3)
)
df
df$St <- cumsum(rnorm(24*3))
# plot
png("test.png", width = 8, height = 4, units = "in", res = 200)
op <- par(mar = c(4,4,1,1), ps = 8)
plot(St ~ T, df, type="l",col='red',xaxt='n',yaxt='n',xlab='',ylab='')
axis(1, at=df$T, labels = format(df$T, "%H"), las=2)
mtext('Zonnetijd (u)', side=1,line=3)
par(op)
dev.off()
You Can see that you may have some space issues with the labels when you plot every one.
Here is another example with 3-hour increment labels:
# alt plot
AT <- seq(min(df$T), max(df$T), by = "3 hour") # 3 hour increments
LAB <- format(AT, "%H")
png("test2.png", width = 8, height = 4, units = "in", res = 200)
op <- par(mar = c(4,4,1,1), ps = 8)
plot(St ~ T, df, type="l",col='red', xlab='', ylab='', xaxt='n')
axis(1, at = AT, labels = LAB, las=2)
mtext('Zonnetijd (u)', side=2, line=3)
mtext('hour', side=1, line=3)
par(op)
dev.off()

Marc has good advice about using a datetime class. Overall, that is a good way to go. See this question for examples of converting decimal times in hours to POSIX datetime class.
If you want to continue with your numeric data we the data itself to indicate what day it occurs on. Here we create a new column identical to the first, but adding 24 every time the first column has a negative difference between successive rows:
gegevens = cbind(gegevens, gegevens[, 1] + 24 * c(0, cumsum(diff(gegevens[, 1]) < 0)))
Now when we plot using our new column, the hours are correctly spaced by day:
plot(gegevens[, 3], gegevens[, 2], type = 'l', col = 'red', xaxt = 'n', yaxt = 'n', xlab = '', ylab = '')
You have some axis issues as well. There is no 24 hour, we usually call this the 0 hour. And 24 * 3 = 72, not 74, so our maximum hour (starting at 0) is 71:
axis(1, at= 0:71, labels = rep.int(0:23,3), las = 2)
Here is the resulting plot on your sample data. It should "work" on your full data, but I agree with Marc that it is probably too many labels. Using a POSIXct date-time format is the best way to flexibly make adjustments.

Related

Getting the last number in a series before lowering it below threshold in R

I have the following data:
dat<- structure(list(Pentad = 1:73, RR = c(0, 0.014285714, 0, 0.088571429,
0.071428571, 0, 0.065714286, 0.028571429, 0.094285714, 0.011428571,
0, 0, 0, 0, 0, 0, 0.04, 0, 0.814285714, 0.285714286, 1.14, 5.334285714,
2.351428571, 1.985714286, 1.494285714, 2.005714286, 20.04857143,
25.00857143, 16.32, 11.06857143, 8.965714286, 3.985714286, 5.202857143,
7.802857143, 4.451428571, 9.22, 32.04857143, 19.50571429, 3.148571429,
2.434285714, 9.057142857, 28.70857143, 34.15142857, 33.02571429,
46.50571429, 70.61714286, 3.168571429, 1.928571429, 7.031428571,
0.902857143, 5.377142857, 11.35714286, 15.04571429, 11.66285714,
21.24, 11.43714286, 11.69428571, 2.977142857, 4.337142857, 0.871428571,
1.391428571, 0.871428571, 1.145714286, 2.317142857, 0.182857143,
0.282857143, 0.348571429, 0, 0.345714286, 0.142857143, 0.18,
4.894285714, 0.037142857), YY = c(0.577142857, 0, 1.282857143,
1.445714286, 0.111428571, 0.36, 0, 0, 0, 1, 0.011428571, 0.008571429,
0.305714286, 0, 0, 0, 0, 0.8, 0.062857143, 0, 0, 0, 0, 0.013333333,
0.043333333, 1.486666667, 0, 2.486666667, 1.943333333, 0.773333333,
8.106666667, 7.733333333, 0.5, 4.356666667, 2.66, 6.626666667,
4.404285714, 7.977142857, 12.94285714, 18.49428571, 7.357142857,
11.08285714, 9.034285714, 14.29142857, 34.61428571, 45.30285714,
6.66, 6.702857143, 5.962857143, 14.85428571, 2.1, 2.837142857,
7.391428571, 32.03714286, 9.005714286, 3.525714286, 12.32, 2.32,
7.994285714, 6.565714286, 4.771428571, 2.354285714, 0.005714286,
2.508571429, 0.817142857, 2.885714286, 0.897142857, 0, 0, 0,
0, 0.145714286, 0.434285714)), class = "data.frame", row.names = c(NA,
-73L))
There are three columns: Pentad, RR, and YY.
I would like to get the following:
(a) Get the first pentad when the precipitation exceeds the "annual mean" in "at least three consecutive pentads"
(b) Get the last pentad when the precipitation exceeds the "annual mean" in at least three consecutive pentads BEFORE lowering it below the annual mean.
I was able to do (a) using the following script:
first_exceed_seq <- function(x, thresh = mean(x), len = 3)
{
# Logical vector, does x exceed the threshold
exceed_thresh <- x > thresh
# Indices of transition points; where exceed_thresh[i - 1] != exceed_thresh[i]
transition <- which(diff(c(0, exceed_thresh)) != 0)
# Reference index, grouping observations after each transition
index <- vector("numeric", length(x))
index[transition] <- 1
index <- cumsum(index)
# Break x into groups following the transitions
exceed_list <- split(exceed_thresh, index)
# Get the number of values exceeded in each index period
num_exceed <- vapply(exceed_list, sum, numeric(1))
# Get the starting index of the first sequence where more then len exceed thresh
transition[as.numeric(names(which(num_exceed >= len))[1])]
}
first_exceed_seq(dat$RR)
Here's the plot of the time series:
The correct answer in (a) is 27.
I would like to ask how can I do this for (b). The correct answer for (b) should be 57.
I'll appreciate any help on in this in R.
I don't know if I got your problem right.
This is what I tried:
dat %>%
mutate(
anual_mean = mean(RR),
exceed_thresh = RR > anual_mean,
lag1 = lag(exceed_thresh, 1),
lag2 = lag(exceed_thresh, 2),
pick_3 = ifelse(exceed_thresh & lag1 & lag2, RR, NA)
)

Add value or percentage in contingency table plot

I would like to put in each box from the ploted contingency table, the value obtained by the table.
The following image represent the contingency table
Te following code is how to display the contingency table:
> svm.video.table2<-table(pred=svm.video.pred2, true= filteredDataFinal$rate)
> svm.video.table2
An this one is how to plot that table
plot(svm.video.table2)
And adhoc approach would be:
text(x = 0.23, y = 0.55, "10")
text(x = 0.23, y = 0.67, "2")
text(x = 0.64, y = 0.94, "1")
text(x = 0.64, y = 0.45, "9")
text(x = 0.92, y = 0.44, "4")
PS: I generated the data to make your example reproducible with svm.video.table2 <- as.table(matrix(c(10, 1, 0, 2, 9, 0, 0, 0, 4), ncol = 3))

sunflowerplot legend symbol with the correct number of segment

I wish create a good legend for a sunflowerplot in R with the symbol of multiple leaves with the correct number of "petals".
The "petals" was created in the function sunflowerplot by segments with different angles.
It is possible to recreate a figure with some segments but do you know if it's possible to insert a self created symbol in a legend? Or have you find a solution to create a legend symbol with the different levels of petals draw in the plot for the sunflowerplot function.
dat <- structure(c(0, 0, 0, 0.074, 0.074, 0.074, 0.22, 0.22, 0.22, 0.66,
0.66, 0.66, 18, 19, 19, 19, 19, 18, 16, 16, 18, 3, 3, 3), .Dim = c(12L,
2L))
sunflowerplot(dat[, 1], dat[, 2])
legend("right", c("1 rep", "4 rep", "8 rep"), pch = c(16, 3, 8))
I know it is possible to use pch 4 and 8 in the legend but I am not really agree with this method.
Ok My solution is to don't use the sunflowerplot function, but to create my own function inspired of the sunflowerplot code.
step 1 : calculate the number of point for each coordinate
tt <- xyTable(cbind(dat[,1], dat[,2]))
step 2: plot the tt object
plot(tt$x, tt$y, cex = tt$number, pch = 16)
step 3: add the legend only for existing points
legend("topright", pt.cex = sort(unique(tt$number)), pch = rep(16, length(unique(tt$number))), legend = paste(sort(unique(tt$number)), "replic.", sep = " "), bty = "n")

How to make a melted dataset greyscale in ggplot

This should be a pretty straightforward question. I have the following code, which forms the plot I want:
library(reshape)
library(ggplot2)
require(ggplot2)
split1_data<-structure(list(Loci = structure(1:8, .Label = c("Baez", "Blue",
"C147", "C204", "C21", "C278_PT", "C294", "C316"), class = "factor"),
All = c(0.3357, 0.4166, 0.0242, 0.9708, 0.4518, 0.0666, 0,
0.5925), X1_only = c(0.4758, 0.3188, 0.1465, 0.3209, 1, 0.0278,
0.2065, 0.6187), X78_only = c(0.3379, 0.4102, 0.2134, 0.6807,
0.8242, 1, 0.0046, 0.279), X8_removed = c(0.0967, 0.5831,
0.058, 0.9268, 0.3518, 0.0629, 0, 0.6229), X8_only = c(0.1169,
0.8327, 0.2169, 0.0907, 1, 1, 0.07, 0.486), X7_removed = c(0.2989,
0.7268, 0.0087, 0.8874, 0.5853, 0.0568, 0, 0.7622), X7_only = c(1,
0.5714, 0.2825, 0.8673, 0.5557, 0.6861, 0.0044, 0.1146),
X5_removed = c(1, 0.1453, 0.0176, 0.8428, 0.2277, 0.2563,
0, 0.5326), X5_only = c(0.0642, 0.631, 0.5193, 0.979, 0.5348,
0.1304, 0.02, 0.0217), X4_removed = c(0.4492, 0.3821, 0.0121,
0.9957, 0.5158, 0.0498, 0, 0.718), X4_only = c(0.6485, 0.0709,
0.1639, 0.6908, 1, 1, 0.4469, 0.639), X3_removed = c(0.3009,
0.3414, 0.02, 0.9935, 0.4216, 0.1273, 0, 0.6406), X3_only = c(1,
0.9325, 0.772, 0.5505, 1, 0.2068, 0.0829, 0.17), X2_removed = c(0.6335,
0.349, 0.2095, 0.9777, 0.8928, 0.0571, 0, 0.4285), X2_only = c(0.191,
0.4397, 0.0403, 0.3606, 0.0089, 1, 0.0033, 0.659), X1_removed = c(0.1653,
0.7658, 0.0718, 0.7705, 0.4193, 0.1894, 0, 0.5167)), .Names = c("Loci",
"All", "X1_only", "X78_only", "X8_removed", "X8_only", "X7_removed",
"X7_only", "X5_removed", "X5_only", "X4_removed", "X4_only",
"X3_removed", "X3_only", "X2_removed", "X2_only", "X1_removed"
), row.names = c(NA, 8L), class = "data.frame")
split1_datam<-melt(split1_data,id="Loci")
p1<- ggplot(split1_datam, aes(x =Loci, y = value, color = variable, width=.15)) +
scale_fill_grey() +
geom_bar(position="dodge")+
geom_hline(yintercept=0.05)+
opts(axis.text.x = theme_text(angle=90, size=8)) +
scale_y_discrete(breaks=seq(0,1)) +
ylab(NULL)
p1
However, I was hoping to make the plot greyscale, but can't seem to figure out how to accomplish this (note: the scale_fit_grey() depicted above is not working for me). Any suggestions? Thanks so much!
One thing that commonly trips people up at the start with ggplot2 is the difference between color and fill. For 2D objects like bars, rectangles, basically any filled area, color affects the border color and fill affects the interior color.
In your plot, you map color = variable, but there is no mapping for fill in aes. I wonder if you meant fill = variable inside aes() and then to use scale_fill_grey.
Otherwise, you'd use color = variable and scale_color_grey, but that would only "color" the borders of the bars, not the filled areas.
For instance, with fill = variable and scale_fill_grey() I get something like this:

Add 3D abline to cloud plot in R's lattice package

I want to add a 3D abline to a cloud scatterplot in R's lattice package. Here's a subset of my data (3 variables all between 0,1):
dat <- structure(c(0.413, 0.879, 0.016, 0.631, 0.669, 0.048, 1, 0.004, 0.523, 0.001,
0.271, 0.306, 0.014, 0.008, 0.001, 0.023, 0.670, 0.027, 0.291, 0.709,
0.002, 0.003, 0.611, 0.024, 0.580, 0.755, 1, 0.003, 0.038, 0.143, 0.214,
0.161, 0.008, 0.027, 0.109, 0.026, 0.229, 0.006, 0.377, 0.191, 0.724,
0.119, 0.203, 0.002, 0.309, 0.011, 0.141, 0.009, 0.340, 0.152, 0.545,
0.001, 0.217, 0.132, 0.839, 0.052, 0.745, 0.001, 1, 0.273), .Dim = c(20L, 3L))
Here's the cloud plot:
# cloud plot
trellis.par.set("axis.line", list(col="transparent"))
cloud(dat[, 1] ~ dat[, 2] + dat[, 3], pch=16, col="darkorange", groups=NULL, cex=0.8,
screen=list(z = 30, x = -70, y = 0),
scales=list(arrows=FALSE, cex=0.6, col="black", font=3, tck=0.6, distance=1) )
I want to add a dashed grey line between 0,0,0 and 1,1,1 (i.e., diagonally through the plot). I know I can change the points to lines using "type="l", panel.3d.cloud=panel.3dscatter", but I can't see a way to add extra points/lines to the plot using this.
Here's an example of what I want to achieve using scatterplot3d:
# scatterplot3d
s3d <- scatterplot3d(dat, type="p", color="darkorange", angle=55, scale.y=0.7,
pch=16, col.axis="blue", col.grid="lightblue")
# add line
s3d$points3d(c(0,1), c(0,1), c(0,1), col="grey", type="l", lty=2)
I want to do this with a cloud plot to control the angle at which I view the plot (scatterplot3d doesn't allow me to have the 0,0,0 corner of the plot facing). Thanks for any suggestions.
Inelegant and probably fragile, but this seems to work ...
cloud(dat[, 1] ~ dat[, 2] + dat[, 3], pch=16, col="darkorange",
groups=NULL, cex=0.8,
screen=list(z = 30, x = -70, y = 0),
scales=list(arrows=FALSE, cex=0.6, col="black", font=3,
tck=0.6, distance=1) ,
panel=function(...) {
L <- list(...)
L$x <- L$y <- L$z <- c(0,1)
L$type <- "l"
L$col <- "gray"
L$lty <- 2
do.call(panel.cloud,L)
p <- panel.cloud(...)
})
One thing to keep in mind is that this will not do hidden point/line removal, so the line will be either in front of all of the points or behind them all; in this (edited) version, do.call(panel.cloud,L) is first so the points will obscure the line rather than vice versa. If you want hidden line removal then I believe rgl is your only option ... very powerful but not as pretty and with a much more primitive interface.

Resources