Drawing geom_rect on facet_wrap plot

639 views
Skip to first unread message

stephen

unread,
Jan 27, 2010, 12:51:45 PM1/27/10
to ggplot2
I am trying to plot a series of test cases that I have run against a
storage array, and have collected metric data.

The first plot has IOPS has the metric.

There are 3 test cases, with 5 iterations per test case doing IO to 6
devices.

I can plot IOPS for each test case with the following code:

require(ggplot2)

iostat_SUM <- dget(file="http://saoconnell.com/ggplot2/
iostat_SUM.dput")

tcase <- dget(file="http://saoconnell.com/ggplot2/tcase.dput")

iterations <- unique(tcase$iter)

p <- ggplot(data=iostat_SUM, aes(date_POSIX, IOPS)) + geom_line() +
scale_x_datetime(major = "5 mins", format="%H:%M" ) +
facet_wrap(~ test, scale = "free_x", ncol = 1)

print(p)

http://saoconnell.com/ggplot2/iostat_SUM_2.png

I now want to add geom_rect of the plot to indicate when each test was
performed. I want to highlight the server level metric (IOPS) with the
time each device was being tested, during each test case. I have
attempted this with the following code:

p <- ggplot(data=iostat_SUM, aes(date_POSIX, IOPS)) + geom_line() +
scale_x_datetime(major = "5 mins", format="%H:%M" ) +
facet_wrap(~ test, scale = "free_x", ncol = 1)

p + geom_rect(aes(xmin=start_POSIX, xmax=end_POSIX, ymax=2000, ymin=0,
fill=iterations), data=tcase)

print(p)

However, I receive the following error:
Error in eval(expr, envir, enclos) : object 'date_POSIX' not found

I have tried to model this after the annotation example in the ggplot2
book on page 86 (which I realize is not faceted.)

Thanks,
Stephen...

hadley wickham

unread,
Jan 28, 2010, 9:26:45 AM1/28/10
to stephen, ggplot2

The problem is that the x and y aesthetics of geo_rect are inherited
from the base plot - and your new data doesn't have those variables.
Either don't set them in the defaults (just use in line layer) or set
x and y to NULL in the rect layer.

Hadley

--
http://had.co.nz/

stephen

unread,
Jan 28, 2010, 12:52:46 PM1/28/10
to ggplot2
Further hacking I was able to produce the following:

http://ggplot2.googlegroups.com/web/iostat_SUM_good.png?gsc=K-E-8QsAAAB-_nDSu5HbeRtfWau9D1gV

Two changes:
- I converted the start and end times in tcase to POSIXct, consistent
with the date_POSIX in iostat_SUM
- I started the plot with qplot instead of ggplot

The following code produces the above chart:

iostat_SUM <- dget(file="http://saoconnell.com/ggplot2/
iostat_SUM.dput")
tcase <- dget(file="http://saoconnell.com/ggplot2/tcase.dput")

tcase$start_POSIX <- as.POSIXct(tcase$start_POSIX)
tcase$end_POSIX <- as.POSIXct(tcase$end_POSIX)

(p <- qplot(date_POSIX, IOPS, data=iostat_SUM, geom="line", xlab="test
time", ylab="IOPS"))
p + geom_rect(aes(NULL,NULL, xmin=start_POSIX, xmax=end_POSIX,
fill=device), ymin=0,ymax=2000, data=tcase) + scale_x_datetime(major =
"5 mins", format="%H:%M" )+ scale_fill_manual(values = alpha(c("blue",
"red", "green", "pink", "darkblue","darkgreen"), 0.2)) + facet_wrap(~


test, scale = "free_x", ncol = 1)

Notes:
- The apparent blank space at the end of SANCOPY_SERIAL is due to the
test running longer than the metric collection, so there are start and
stop times for each device however the metric collection had already
stopped.
- I'm not sure I like this chart now that it is finished. With the
free_x this chart implies visually that the tests cases had the same
duration, which they did not. I think additional annotation may help,
however, I am not sure facet_wrap with free_x and a datetime scale is
a very good combination. Can the length of the facet be varied to
represent the elapsed time in each facet? Each facet would be scaled
in length based on the facet with the longest elapsed time.
- I am not sure why the entire syntax has to be on the same line,
maybe someone can explain that to me. I played with various
combinations but could only get the single line version to work.

Thanks,
Stephen...

On Jan 28, 6:26 am, hadley wickham <h.wick...@gmail.com> wrote:

Reply all
Reply to author
Forward
0 new messages