1

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")))
Gregor Thomas
  • 136,190
  • 20
  • 167
  • 294
  • Data (and code) posted as images is a really bad idea, it forces us to type it if we want to have a test dataset. Can you post sample data in the much better `dput` format? Please edit **the question** with the output of `dput(gegevens)`. Or, if it is too big with the output of `dput(head(gegevens, 20))`. – Rui Barradas Nov 26 '18 at 15:34
  • Your approach seems to be good, but maybe has problems due to your data format? Like, what is the range of the first column? Can you share a little sample data in a reproducible format? (Your image shows some stuff, but it doesn't make it easy to import into R, or see what's going on.) `dput()` is a great way to share a copy/pasteable version of an R object. – Gregor Thomas Nov 26 '18 at 15:35
  • Thanks for the `dput` - this clears up a lot. Is there anything in the data to indicate which row belongs to which day? Or just the order of the rows - when the first column goes back to 0 that is the start of the next day? – Gregor Thomas Nov 26 '18 at 16:20
  • row 1-24 are from day 1 and row 25-48 are from day 2 – Ellen Ghyselbrecht Nov 26 '18 at 16:32

2 Answers2

2

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()

enter image description here

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()

enter image description here

Marc in the box
  • 11,769
  • 4
  • 47
  • 97
1

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.

enter image description here

Gregor Thomas
  • 136,190
  • 20
  • 167
  • 294