简体   繁体   中英

time display in clock with xy scatter plot in r

I would like to create the following type of plot. But do not know if there is any package already exists, as I could not find one. Data:

myd <- data.frame (X = 1:5, Y = c(0.8, 0.6, 0.7, 0.75,  0.1), 
     clockd = c(12.05, 12.25, 12.45, 1.30, 2.1))

clockd are time 12.05 is 12 Oclock past minutes. I do not know appropriate unit to enter time in R.

plot (myd$X, myd$Y)

Edit: The red and green arrow represents the hour and minitue position of clock arms in a clock. 在此输入图像描述

clockplot<-function(x, y, h, m, r, border="black", col="lightblue", 
                    col.hour="darkblue", col.min="red"){
#x and y are the coordinates of the clock
#h and m the hour (base 12) and minutes
# r the radius of the clock
    t<-seq(0,2*pi,by=0.01)
    x.c<-r*cos(t)+x
    y.c<-r*sin(t)+y

    t.h<-pi/2 - 2*pi*(h-m/60)/12
    x.h<-0.5*r*cos(t.h)+x
    y.h<-0.5*r*sin(t.h)+y

    t.m<-pi/2 - 2*pi*m/60
    x.m<-r*cos(t.m)+x
    y.m<-r*sin(t.m)+y

    polygon(x.c,y.c,col=col, border=border)
    segments(x,y,x.h,y.h,col=col.hour)
    segments(x,y,x.m,y.m,col=col.min)
    }

myd <- data.frame (X = 1:5, Y = c(0.8, 0.6, 0.7, 0.75,  0.1), 
                   clockd = c(12.05, 12.25, 12.45, 1.30, 2.1))
myd$hour<-myd$clockd%/%1
myd$min<-myd$clockd%%1 *100

plot(myd$X, myd$Y, type="l", asp=1)
apply(myd,1,function(x)clockplot(x[1],x[2],x[4],x[5], r=0.25))

在此输入图像描述

I'm using suggestion by @GregSnow here with my.symbols function from TeachingDemo package. This way you can do it with a small(ish) chunk of code but you can have quite big control over the graphical parametrs like size and fill of clock circles, look of arrows, the way you customize your plot, etc. For calculating location of arrows I modified @agstudy code so that it extracts minutes correctly.

myd <- data.frame (X = 1:5, Y = c(0.8, 0.6, 0.7, 0.75,  0.1), 
                   clockd = c(12.05, 12.25, 12.45, 1.30, 2.1))
hour <- round(myd$clockd)#takes hours by ignoring decimals
minute <- 100*(myd$clockd - trunc(myd$clockd,2))#takes decimals
#for getting the angle I'm subtracting from pi/2
#thats because pi/2 orients the arrow into 0 degree position, pointing up 
hourAngle <- pi/2 - (hour/12*2*pi)
minuteAngle <- pi/2 - (minute/60*2*pi)
#now all the plotting
plot(myd$X, myd$Y, type="l", xaxt="n", xlab="", ylab="", 
     xlim=c(0.5,5.5), ylim=c(0,1), col="gray")#standard plot, no x axis
axis(1, at=myd$X, labels=myd$X)#custom x-axis
require(TeachingDemo)
my.symbols(myd$X, myd$Y, ms.arrows, angle=hourAngle, add=T, 
           col="blue", symb.plots=TRUE, adj=0)
my.symbols(myd$X, myd$Y, ms.arrows, angle=minuteAngle, add=T, 
           col="red", symb.plots=TRUE, adj=0)
my.symbols(myd$X, myd$Y, ms.polygon, n=250, add=T, 
           r=1.1, col="gray")

在此输入图像描述

在此输入图像描述

Giving your data :

read.table(text = 'col1 col2
           0012 0001245',head=T,colClasses=c('character','numeric'))


myd <- data.frame (X = 1:5, 
                   Y = c(0.8, 0.6, 0.7, 0.75,  0.1), 
                   clockd = c(12.05, 12.25, 12.45, 1.30, 2.1))

Using lattice+grid we can do somethink like this :

library(lattice)
library(grid)
xyplot(Y~X,data=myd,
       panel=function(x,y,...)
       {

         panel.fill(col='yellow')
         panel.lines(x,y)

         h_min <- do.call(rbind,strsplit(as.character(myd$clockd),'[.]'))
         hours <- as.numeric(h_min[,1])
         minutes <- as.numeric(h_min[,2])
         lapply(seq_along(x),
                         function(i)drawClock(x[i],y[i],hour = hours[i], minute = minutes[i]))


       })

Where drawClock is adopted from this and trsnformed to the need of this question:

drawClock <- function(x0,y0,hour, minute) {
  t <- seq(0, 2*pi, length=13)[-13]
  x <- cos(t)
  y <- sin(t)
  # Circle with ticks
  grid.circle(x=x0, y=y0, default="native", 
              r=unit(0.4,'in'),gp=gpar(fill='blue',alpha=0.5))
  #         grid.segments(x, y, x*.9, y*.9, default="native")
  # Hour hand
  hourAngle <- pi/2 - (hour + minute/60)/12*2*pi
  grid.segments(x0, y0, 
                x0+.06*cos(hourAngle), y0+.06*sin(hourAngle), 
                default="native", gp=gpar(lex=4))
  # Minute hand
  minuteAngle <- pi/2 - (minute)/60*2*pi
  grid.segments(x0, y0, 
                x0+.08*cos(minuteAngle), y0+.08*sin(minuteAngle), 
                default="native", gp=gpar(lex=2))    
}

查看TeachingDemos包中的my.symbols函数,获取有助于创建此类绘图的工具。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM