问题
I want to plot the range of dates where a particular object is "active", as shown below:
This example is taken from Wikipedia. Here is the data:
df1 <- data.frame(
name = c("Eazy-E", "DJ Yella", "Dr. Dre",
"Ice Cube", "Arabian Prince", "MC Ren"),
from = as.Date(c("01/01/1986", "01/01/1986", "01/01/1986",
"01/01/1986", "01/01/1986","02/01/1988"), "%m/%d/%Y"),
to = as.Date(c("08/01/1991", "08/01/1991", "07/01/1991",
"12/01/1989", "07/01/1988", "08/01/1991"),"%m/%d/%Y"))
df1
name from to
1 Eazy-E 1986-01-01 1991-08-01
2 DJ Yella 1986-01-01 1991-08-01
3 Dr. Dre 1986-01-01 1991-07-01
4 Ice Cube 1986-01-01 1989-12-01
5 Arabian Prince 1986-01-01 1988-07-01
6 MC Ren 1988-02-01 1991-08-01
I can't figure out how to:
- Plot the value of dates
- Make floating bar charts
Thanks for any input.
回答1:
It doesn't appear to be a bar chart per se, more of a collection of lines or rectangles. As such, this can be tackled with lines()
, rect()
, or even polygon()
. I'll show the first, I hope you'll get the gist.
Your data:
dat <- structure(list(name = c("Eazy-E", "DJ Yella", "Dr. Dre", "Ice Cube", "Arabian Prince", "MC Ren"),
from = c("1986-01-01", "1986-01-01", "1986-01-01", "1986-01-01", "1986-01-01", "1988-02-01"),
to = c("1991-08-01", "1991-08-01", "1991-07-01", "1989-12-01", "1988-07-01", "1991-08-01")),
.Names = c("name", "from", "to"), row.names = c(NA, -6L), class = "data.frame")
dat$from <- as.POSIXct(dat$from)
dat$to <- as.POSIXct(dat$to)
dat
## name from to
## 1 Eazy-E 1986-01-01 1991-08-01
## 2 DJ Yella 1986-01-01 1991-08-01
## 3 Dr. Dre 1986-01-01 1991-07-01
## 4 Ice Cube 1986-01-01 1989-12-01
## 5 Arabian Prince 1986-01-01 1988-07-01
## 6 MC Ren 1988-02-01 1991-08-01
One solution:
par(mar=c(2,8,0,0) + 0.1)
plot(0, type='n', xlim=range(c(dat$from, dat$to)), ylim=c(1, nrow(dat)),
main='', xlab='', ylab='', xaxt='n', yaxt='n')
years <- seq.POSIXt(min(dat$from), max(dat$to), by='1 year')
abline(v=years, lty=3, col='gray')
axis(1, at=years, labels=format(years, '%Y'))
axis(2, at=1:nrow(dat), labels=rev(dat$name), las=2)
lines(x=as.POSIXct(c(apply(dat[,c('from','to')], 1, c, NA))),
y=rep(nrow(dat):1, each=3),
lwd=5)
Increase lwd
to get thicker lines. If you want more control over it, consider using rect
in the same fashion.
回答2:
Here's an approach using barchart
. First, plot a barchart where bar length is given by the end date, then plot over this with a white barchart with bar length given by start date. Use axis.date
to add the x-axis labels.
par(mar=c(5, 6, 2, 2))
b <- barplot(as.numeric(df$to), horiz=TRUE, border='transparent',
xlim=range(c(df$from, df$to)), xaxt='n', yaxs='i',
space=1)
barplot(as.numeric(df$from), horiz=TRUE, space=1, add=TRUE, col='white',
border='transparent', xaxt='n', names.arg=df$name, las=1,
cex.names=0.8)
axis(2, at=b[, 1], labels=FALSE, tick=FALSE)
box(bty='l')
axis.Date(1, pretty(df$from), cex.axis=0.8)
来源:https://stackoverflow.com/questions/32662606/floating-bar-chart-with-dates-as-the-plotted-values-in-r