How to make 3-D time series plots - r

I have time series data on 10 individuals, similar to what is created below. I am looking for a way to make a 3-D plot similar to this example:
Except I want each unique ID to be where year is in the picture
set.seed(123)
ID <- rep(1:10, each = 500)
Time = rep(c(1:500),10)
Var <- rnorm(5000)
data <- data.frame(
ID = factor(ID),
Time = Time,
Variable = Var
)

As a very quick, and ugly start, try
library(plot3D)
## rearrange data into matrix form
m <- matrix(
data$Variable,
nrow=length(unique(data$ID)))
hist3D(z = m)
This doesn't look at all like your example plot; on the other hand, your data don't look much like the data in this plot. Things I haven't played around with yet:
axis labels
making sure the matrix is actually oriented in the right way (this will be a lot easier with real data!)
changing aspect ratio

Related

Create horizon chart on R using ggplot2: show percentage change

I am a beginner at this and am really lost about it.
I would like to create a horizon chart that shows the percentage change in sales for the different towns using ggplot2 and R. Would anyone guide me in the approach I can take to create the chart?
The data that I have looks like this.
This is the type of chart I would like to do.
(source: https://harmoniccode.blogspot.com/2017/11/friday-fun-li-horizon-charts.html)
Thanks in advance for any help given!
Edit: here's a sample code of the data:
x <- data.frame(
"town" =c('sad','sad','sad','sad','happy','happy','happy','happy'),
"month"=c("2017-01","2017-02","2017-03","2017-04","2017-01","2017-02","2017-03","2017-04"),
"median_sales" = c(336500,355000,375000,395000,359000,361500,36000,375000),
"percentage_change" = c(NA,5.4977712,5.6338028,5.3333333,NA,0.6963788,-0.4149378, 4.1666667
))
x <-
x %>%
mutate(month = floor_date(as_date(as.yearmon(month)), "month"))
It would be helpful to give an example that will result in a reasonable plot, and to provide your example data as data rather than an image.
If you google 'horizon plot' the first answer should give you what you need.
Here is a simple example based on the data you gave:
library(latticeExtra)
sales.ts <- ts(matrix(sales$median_sales, ncol=2), names = c("sad", "happy"),
start = c(2017, 1), frequency = 365)
horizonplot(sales.ts)
I think this is correctly presenting your results, but again hard to tell as you haven't given a realistic dataset.
UPDATE: based on the data provided, this is the answer. Again, as you've only provided one time point a horizonplot is probably not what you want. They are designed to plot time series.
x.ts <- ts(matrix(x$median_sales, ncol=2), names = c("sad", "happy"),
start = c(2015, 1), frequency = 12)
horizonplot(x.ts)

R language how to make an animation map for several image plotted by ggmap and animation packages

I have a .csv file of devices positions with columns "Date","time","lat","lon","radius",
"position_method". I want to plot the points data on Google map and make animation to reflect points changes by hour.
I used the powerful animation package ( http://cran.r-project.org/web/packages/animation/animation.pdf. ) and a demo (http://xccds1977.blogspot.fi/2012/06/ggmap.html).
The codes are as following:
all <- read.csv("C:/probes/2014-04-07.csv",header=T)
#convert the time format to standard hour-min-sec format
th < -strptime(all$time,"%H:%M:%OS")
#select the hour part of time
byhour <- th$h
#plot map by hours
plotfunc <- function(x) {
df <- subset(all,byhour <= x)
p <- ggmap(get_googlemap (center = 'Tampere', zoom=10,maptype = 'terrain'),,extent='device')+
geom_point(data = df,aes(x = lon, y = lat),colour = 'red',alpha=0.7)
}
#get the hours of probes
time <- sort(unique (byhour))
#generate and save the animation in HTML
saveHTML({
for( i in time) print (plotfunc(i))
ani.options(interval = 0.5)
},
img.name = "probes_hour_plot", title = "Visualization of probes from Pirkanmmaa changing by time in a day",
description=c("the numbers of devices receiveing from 12am")
)
By the loop for( i in time) print(plotfunc(i) I got an animation but it overlay new points on old ones, so the points are increasing. It could not reflect the changes of distribution. Do you know how to make the animation just show the points in each hour one by one rather than any overlay and accumulation? Only what I need is just making animation combining independent images.
The animation I got is like the gif in the demo from Kai Xiao, but it is not what I wish.
The problem isn't the animation program, it's simply the function you are using to plot your data, right now you are doing
df <- subset(all,byhour <= x)
which selects more and more data as x increases. Try
df <- subset(all,byhours>=x-1 & byhour<= x)
instead to use more of a rolling window rather than a cumulative subset.

How to create an animation of geospatial / temporal data

I have a set of data which contains around 150,000 observations of 800 subjects. Each observation has: subject ID, latitude, longitude, and the time that the subject was at those coordinates. The data covers a 24-hour period.
If I plot all the data at once I just get a blob. Is anyone able to give me some tips as to how I can animate this data so that I can observe the paths of the subjects as a function of time?
I've read the spacetime vignette but I'm not entirely sure it will do what I want. At this point I'm spending a whole lot of time googling but not really coming up with anything that meets my needs.
Any tips and pointers greatly appreciated!
Here my first use of animation package. It was easier than I anticipated and especially the saveHTML is really amazing. Here my scenario(even I think that my R-code will be clearer:)
I generate some data
I plot a basic plot for all persons as a background plot.
I reshape data to get to a wide format in a way I can plot an arrow between present and next position for each person.
I loop over hours , to generate many plots. I put the llop within the powerful saveHTML function.
You get a html file with a nice animation. I show here one intermediate plot.
Here my code:
library(animation)
library(ggplot2)
library(grid)
## creating some data of hours
N.hour <- 24
dat <- data.frame(person=rep(paste0('p',1:3),N.hour),
lat=sample(1:10,3*N.hour,rep=TRUE),
long=sample(1:10,3*N.hour,rep=TRUE),
time=rep(1:N.hour,each=3))
# the base plot with
base <- ggplot() +
geom_point(data=dat,aes(x=lat, y=long,colour = person),
size=5)+ theme(legend.position = "none")
## reshape data to lat and long formats
library(plyr)
dat.segs <- ddply(dat,.(person),function(x){
dd <- do.call(rbind,
lapply(seq(N.hour-1),
function(y)c(y,x[x$time %in% c(y,y+1),]$lat,
x[x$time %in% c(y,y+1),]$long)))
dd
})
colnames(dat.segs) <- c('person','path','x1','x2','y1','y2')
# a function to create the animation
oopt <- ani.options(interval = 0.5)
saveHTML({
print(base)
interval = ani.options("interval")
for(hour in seq(N.hour-1)){
# a segment for each time
tn <- geom_segment(aes(x= x1, y= y1, xend = x2,
yend = y2,colour = person),
arrow = arrow(), inherit.aes = FALSE,
data =subset(dat.segs,path==hour))
print(base <- base + tn)
ani.pause()
}
}, img.name = "plots", imgdir = "plots_dir",
htmlfile = "random.html", autobrowse = FALSE,
title = "Demo of animated lat/long for different persons",
outdir=getwd())
Your question is a bit vague, but I will share how I have done this kind of animation in the past.
Create a function that plots all the subject locations for one time slice:
plot_time = function(dataset, time_id) {
# make a plot with your favorite plotting package (e.g. `ggplot2`)
# Save it as a file on disk (e.g. using `ggsave`), under a regular name,
# frame001.png, frame002.png, see sprintf('frame%03d', time_index)
}
Call this function on each of your timeslices, e.g. using lapply:
lapply(start_time_id:stop_time_id, plot_time)
leading to a set of graphics files on the hard drive called frame001 to framexxx.
Use a tool to render those frames into a movie, e.g. using ffmpeg, see for example.
This is a general workflow, which has been already implemented in the animation package (thanks for reminding me #mdsummer). You can probably leverage that package to get your animation.

Long vector-plot/Coverage plot in R

I really need your R skills here. Been working with this plot for several days now. I'm a R newbie, so that might explain it.
I have sequence coverage data for chromosomes (basically a value for each position along the length of every chromosome, making the length of the vectors many millions). I want to make a nice coverage plot of my reads. This is what I got so far:
Looks alright, but I'm missing y-labels so I can tell which chromosome it is, and also I've been having trouble modifying the x-axis, so it ends where the coverage ends. Additionally, my own data is much much bigger, making this plot in particular take extremely long time. Which is why I tried this HilbertVis plotLongVector. It works but I can't figure out how to modify it, the x-axis, the labels, how to make the y-axis logged, and the vectors all get the same length on the plot even though they are not equally long.
source("http://bioconductor.org/biocLite.R")
biocLite("HilbertVis")
library(HilbertVis)
chr1 <- abs(makeRandomTestData(len=1.3e+07))
chr2 <- abs(makeRandomTestData(len=1e+07))
par(mfcol=c(8, 1), mar=c(1, 1, 1, 1), ylog=T)
# 1st way of trying with some code I found on stackoverflow
# Chr1
plotCoverage <- function(chr1, start, end) { # Defines coverage plotting function.
plot.new()
plot.window(c(start, length(chr1)), c(0, 10))
axis(1, labels=F)
axis(4)
lines(start:end, log(chr1[start:end]), type="l")
}
plotCoverage(chr1, start=1, end=length(chr1)) # Plots coverage result.
# Chr2
plotCoverage <- function(chr2, start, end) { # Defines coverage plotting function.
plot.new()
plot.window(c(start, length(chr1)), c(0, 10))
axis(1, labels=F)
axis(4)
lines(start:end, log(chr2[start:end]), type="l")
}
plotCoverage(chr2, start=1, end=length(chr2)) # Plots coverage result.
# 2nd way of trying with plotLongVector
plotLongVector(chr1, bty="n", ylab="Chr1") # ylab doesn't work
plotLongVector(chr2, bty="n")
Then I have another vector called genes that are of special interest. They are about the same length as the chromosome-vectors but in my data they contain more zeroes than values.
genes_chr1 <- abs(makeRandomTestData(len=1.3e+07))
genes_chr2 <- abs(makeRandomTestData(len=1e+07))
These gene vectors I would like plotted as a red dot under the chromosomes! Basically, if the vector has a value there (>0), it is presented as a dot (or line) under the long vector plot. This I have not idea how to add! But it seems fairly straightforward.
Please help me! Thank you so much.
DISCLAIMER: Please do not simply copy and paste this code to run off the entire positions of your chromosome. Please sample positions (for example, as #Gx1sptDTDa shows) and plot those. Otherwise you'd probably get a huge black filled rectangle after many many hours, if your computer survives the drain.
Using ggplot2, this is really easily achieved using geom_area. Here, I've generated some random data for three chromosomes with 300 positions, just to show an example. You can build up on this, I hope.
# construct a test data with 3 chromosomes and 100 positions
# and random coverage between 0 and 500
set.seed(45)
chr <- rep(paste0("chr", 1:3), each=100)
pos <- rep(1:100, 3)
cov <- sample(0:500, 300)
df <- data.frame(chr, pos, cov)
require(ggplot2)
p <- ggplot(data = df, aes(x=pos, y=cov)) + geom_area(aes(fill=chr))
p + facet_wrap(~ chr, ncol=1)
You could use the ggplot2 package.
I'm not sure what exactly you want, but here's what I did:
This has 7000 random data points (about double the amount of genes on Chromosome 1 in reality). I used alpha to show dense areas (not many here, as it's random data).
library(ggplot2)
Chr1_cov <- sample(1.3e+07,7000)
Chr1 <- data.frame(Cov=Chr1_cov,fil=1)
pl <- qplot(Cov,fil,data=Chr1,geom="pointrange",ymin=0,ymax=1.1,xlab="Chromosome 1",ylab="-",alpha=I(1/50))
print(pl)
And that's it. This ran in less than a second. ggplot2 has a humongous amount of settings, so just try some out. Use facets to create multiple graphs.
The code beneath is for a sort of moving average, and then plotting the output of that. It is not a real moving average, as a real moving average would have (almost) the same amount of data points as the original - it will only make the data smoother. This code, however, takes an average for every n points. It will of course run quite a bit faster, but you will loose a lot of detailed information.
VeryLongVector <- sample(500,1e+07,replace=TRUE)
movAv <- function(vector,n){
chops <- as.integer(length(vector)/n)
count <- 0
pos <- 0
Cov <-0
pos[1:chops] <- 0
Cov[1:chops] <- 0
for(c in 1:chops){
tmpcount <- count + n
tmppos <- median(count:tmpcount)
tmpCov <- mean(vector[count:tmpcount])
pos[c] <- tmppos
Cov[c] <- tmpCov
count <- count + n
}
result <- data.frame(pos=pos,cov=Cov)
return(result)
}
Chr1 <- movAv(VeryLongVector,10000)
qplot(pos,cov,data=Chr1,geom="line")

Aligning multiple xts time series plots

I have an xts object with 4 columns. The first 3 columns are the mean and lower and upper confidence bounds for a proportion. The 4th column is the sample size. Since the scales are different, I thought it would make sense to plot the first 3 columns on one graph, and plot the 4th on a separate graph, right below it. Any suggestions on how to do this?
Here's code to build an xts object that's like the one I have:
startTime = Sys.time()
n = 10
d = seq(startTime,startTime+n*24*60*60,by="1 day")
a = sample(10000,length(d),replace=TRUE)
p = runif(length(d))
l = p/2
u = p+(p+1)/2
x= xts(p,d)
x = cbind(x,l,u,a)
colnames(x) = c("prop","low","high","size")
It's easy to do if you use plot.zoo. Something like this will get you started:
library(xts)
data(sample_matrix)
x <- as.xts(sample_matrix)
plot.zoo(x, screens=c(1,1,1,2))
There are tons of examples in ?plot.zoo; make sure to check them out.

Resources