1

I have two time series of data, each with a different range of values. I would like to plot one as a dotplot and the other as a line over the dotplot. (I would settle for a decent-looking barplot and a line over the barplot, but my preference is a dotplot.)

#make some data
require(lubridate)
require(ggplot)

x1 <- sample(1990:2010, 10, replace=F)
x1 <- paste(x1, "-01-01", sep="")
x1 <- as.Date(x1)
y1 <- sample(1:10, 10, replace=T)
data1 <- cbind.data.frame(x1, y1)

year <- sample(1990:2010, 10, replace=F)
month <- sample(1:9, 10, replace=T)
day <- sample(1:28, 10, replace=T)

x2 <- paste(year, month, day, sep="-")
x2 <- as.Date(x2)
y2 <- sample(100:200, 10, replace=T)
data2 <- cbind.data.frame(x2, y2)
data2 <- data2[with(data2, order(x2)), ]

# frequency data for dot plot
x3 <- sample(1990:2010, 25, replace=T)
data2 <- as.data.frame(x3)

I can make a dotplot or barplot with one data set in ggplot:

ggplot() + geom_dotplot(data=data2, aes(x=x3))

dotplot

ggplot() + geom_bar(data=data, aes(x=x1, y=y1), stat="identity")

barplot

But I can't overlay the second data set because ggplot doesn't permit a second y-axis.

I can't figure out how to plot a time series using barplot().

I can plot the first set of data as an "h" type plot, using plot(), and add the second set of data as a line, but I can't make the bars any thicker because each one corresponds to a single day over a stretch of many years, and I think it's ugly.

plot(data$x1, data$y1, type="h")
par(new = T)
plot(data2$x2, data2$y2, type="l", axes=F, xlab=NA, ylab=NA)
axis(side=4)

plotplot

Any ideas? My only remaining idea is to make two separate plots and overlay them in a graphics program. :/

fredtal
  • 571
  • 4
  • 16
  • possible duplicate of [How to use ggplot2 make plot with 2 y axes, one y axis on the left, and another y axis on the right?](http://stackoverflow.com/questions/3099219/how-to-use-ggplot2-make-plot-with-2-y-axes-one-y-axis-on-the-left-and-another) –  Jan 28 '15 at 04:40
  • I know already that ggplot can't do two separate y-axes, but wanted to show what I had tried. I would be down to use stripchart or barplot or any other plotting function if it could do what I wanted. – fredtal Jan 28 '15 at 04:54
  • You also can read the answer by hadley and check whether what you are trying to achieve is a good idea or not. –  Jan 28 '15 at 04:57
  • I've read that post (and others like it), and I understand the downsides to using two y-axes. I've thought carefully about why I want to create this plot in this way. Even Hadley agrees that in some cases it can be useful. – fredtal Jan 28 '15 at 05:03
  • Thus, you can try with the `lattice` probably. –  Jan 28 '15 at 05:05

2 Answers2

2

An easy workaround is to follow your base plotting instinct and beef up lwd for type='h'. Be sure to set lend=1 to prevent rounded lines:

par(mar=c(5, 4, 2, 5) + 0.1)
plot(data1, type='h', lwd=20, lend=1, las=1, xlab='Date', col='gray',
     xlim=range(data1$x1, data2$x2))
par(new=TRUE)
plot(data2, axes=FALSE, type='o', pch=20, xlab='', ylab='', lwd=2,
     xlim=range(data1$x1, data2$x2))
axis(4, las=1)
mtext('y2', 4, 3.5)

enter image description here

jbaums
  • 27,115
  • 5
  • 79
  • 119
-1

I removed the original answer.


To answer your question about making a dot plot, you can rearrange your data so that you can use the base plotting function. An example:

use the chron package for plotting:

library(chron)

dummy data:

count.data <- data.frame("dates" = c("1/27/2000", "3/27/2000", "6/27/2000", "10/27/2000"), "counts" = c(3, 10, 5, 1), stringsAsFactors = F) 

replicate the dates in a list:

rep.dates <- sapply(1:nrow(count.data), function(x) rep(count.data$dates[x], count.data$counts[x]))

turn the counts into a sequence:

seq.counts <- sapply(1:nrow(count.data), function(x) seq(1, count.data$counts[x], 1))

plot it up:

plot(as.chron(rep.dates[[1]]), seq.counts[[1]], xlim = c(as.chron("1/1/2000"), as.chron("12/31/2000")),
 ylim = c(0, 20), pch = 20, cex = 2)
for(i in 2:length(rep.dates)){
   points(as.chron(rep.dates[[i]]), seq.counts[[i]], pch = 20, cex = 2)
}
ken
  • 325
  • 3
  • 7
  • I know how to plot two time series data sets with separate y-axes. But I don't know how to make one of those data sets a frequency dot plot while the other is a line (or points). – fredtal Jan 28 '15 at 05:21
  • Ohhhhh. Reconfigure the data so each dot is a point on the plot. Yes. Thank you. – fredtal Jan 28 '15 at 18:15