Alsqer Alsqer - 2 months ago 44
R Question

Data Visualization on Time-Spiral graph Using R

is there any way to plot a graph like this in R and have the same 12 axes on it with thier name ?

here's a pic for the graph.
Photo for the graph

here's a piece of my data

Date1 Time TravelTime
1 2016-09-04 13:11 34
2 2016-09-04 13:12 34
3 2016-09-04 13:13 33
4 2016-09-04 13:14 33
5 2016-09-04 13:15 33
6 2016-09-04 13:16 43
7 2016-09-04 13:17 44
8 2016-09-04 13:18 44
9 2016-09-04 13:19 40
10 2016-09-04 13:20 39


here's the output from dput

structure(list(Date1 = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L), .Label = "2016-09-04", class = "factor"), Time = structure(1:10, .Label = c("13:11",
"13:12", "13:13", "13:14", "13:15", "13:16", "13:17", "13:18",
"13:19", "13:20"), class = "factor"), TravelTime = c(34L, 34L,
33L, 33L, 33L, 43L, 44L, 44L, 40L, 39L)), .Names = c("Date1",
"Time", "TravelTime"), row.names = c(NA, -10L), class = "data.frame")


here's my data for 5 days

Data1




here's another graph that shows the Time-Spiral ... May you please change your graph to spiral, not a circular ?

enter image description here

i got the graph from this link
here

Answer

Updated Answer

I've updated the code to use the data you provided. The data are summarized to get mean travel time in 15-minute segments for each day.

First, we load and process the data:

dat = readxl::read_excel("Data1.xlsx")

# Convert Date1 and Time to POSIXct
dat$time = with(dat, as.POSIXct(paste(Date1, Time), tz="GMT"))

# Get hour from time
dat$hour = dat$hour = as.numeric(dat$time) %% (24*60*60) / 3600

# Get date from time
dat$day =  as.Date(dat$time)

# Rename Travel Time and convert to numeric
names(dat)[grep("Travel",names(dat))] = "TravelTime"
dat$TravelTime = as.numeric(dat$TravelTime)

Now, summarize the data into 15-minute time-of-day bins with the mean travel time for each bin:

library(dplyr)

dat.smry = dat %>% 
  mutate(hour.group = cut(hour, breaks=seq(0,24,0.25), labels=seq(0,23.75,0.25), include.lowest=TRUE),
         hour.group = as.numeric(as.character(hour.group))) %>%
  group_by(day, hour.group) %>%
  summarise(meanTT = mean(TravelTime))

Finally, we plot the data. Each 15-minute hour-of-day bin gets its own segment, and we use travel time for the color gradient.

ggplot(dat.smry, aes(x=as.numeric(hour.group), xend=as.numeric(hour.group) + 0.25, 
                     y=day, yend=day, colour=meanTT)) +
  geom_segment(size=6) +
  scale_x_continuous(limits=c(0,24), breaks=0:23, minor_breaks=0:24,
                     labels=paste0(rep(c(12,1:11),2), rep(c("AM","PM"),each=12))) +
  scale_y_date(limits=range(dat$day) + c(-3,0), breaks=seq(min(dat$day),max(dat$day),"1 day"),
               date_labels="%b %e") +
  scale_colour_gradient2(low="green", mid="yellow", high="red", midpoint=35) +
  coord_polar() +
  theme_bw(base_size=10) + 
  labs(x="Hour",y="Day",color="Mean Travel Time") +
  theme(panel.grid.minor.x=element_line(colour="grey60", size=0.3))

enter image description here

Original Answer

I'm not sure what variable you want on the radial axis or whether you have a grouping variable that could be used for color, but hopefully this will get you started. I've created a fake data set that I hope is similar to your real data.

library(ggplot2)

# Fake data
set.seed(341)
dat = data.frame(date=sample(seq(as.POSIXct("2016-01-01"), as.POSIXct("2016-01-07"), length.out=100)),
                 TravelTime=sample(10:40, 100, replace=TRUE),
                 group=sample(LETTERS[1:4], 100, replace=TRUE))

# Get hour of day
dat$hour = as.numeric(dat$date) %% (24*60*60) / 3600

# Convert date to day on scale of 1 to N, where the first date in the data set is day 1
dat$day = as.numeric(as.Date(dat$date)) %% min(as.numeric(as.Date(dat$date))) + 1

ggplot(dat, aes(x=hour, xend=hour+TravelTime/60, y=day, yend=day, colour=group)) +
  geom_segment(size=2.5) +
  scale_x_continuous(limits=c(0,24), breaks=0:23, minor_breaks=0:24,
                     labels=paste0(rep(c(12,1:11),2), rep(c("AM","PM"),each=12))) +
  scale_y_continuous(limits=c(-4,7), breaks=1:7) +
  coord_polar() +
  theme_bw() + 
  theme(axis.text.x=element_text(size=8))

enter image description here