Skip to content

ggplot2: Don’t Try This With Excel (Revised)

May 1, 2009

A few posts ago an attempt was made to reproduce the plot from a Charts & Graphs blog. Each of the four individual plots was first drawn and then combined into one with the help of grid.layout(). The final layout also required several manual tweaking adjustments of individual plot margins to align the plots and their axes. Considering the overall flexibility of ggplot2 there had to be another, less complicated way to achieve the same result. This post shows how to combine different chart types into one plot, without using grid.layout(). As you can see the code is much easier to read and more compact to edit/make changes to.

Each ggplot2 plot consists of a number of layers, allowing to separate the raw data from its visual presentation, as well as to use different datasets on different layers of the same plot. Utilising the grammar of graphics ggplot2 is built on, first the layout of the final plot is drawn using a dummy dataframe, and then, one by one layers showing a different representation of the same data are added. Faceting variable specified in the layout object is used to position the plots in the right place on the final graph.

> library(ggplot2)
> rdata <- read.table("cities.txt", header = F,
     col.names = c("City", "X", "Y"))
> rdata <- rdata[with(rdata, order(City, Y)),
     ]

Create dummy dataframe

> dummy <- data.frame(X = 1:4, Y = 1:4, City = unique(rdata$City),
     id = factor(1:4, labels = c("Simple XY Plot",
         "Conditional Format", "City Averages",
         "City Hulls")))

Draw layout and specify theme

> theme_set(theme_bw())
> p <- ggplot(dummy, aes(X, Y, colour = City,
     fill = City, shape = City)) + xlim(0, 20) +
     ylim(0, 20) + facet_grid(id ~ .) + xlab(NULL) +
     ylab(NULL) + opts(legend.position = "none") +
     opts(panel.margin = unit(0, "lines")) +
     opts(panel.grid.major = theme_blank()) +
     geom_blank()
https://learnr.files.wordpress.com/2009/05/donttry2-p0.png

Plot 1 – Simple X Y Plot

> df1 <- data.frame(rdata, id = levels(dummy$id)[1])
> p1 <- p + geom_point(data = df1, colour = "black",
     shape = 16, stat = "identity")
https://learnr.files.wordpress.com/2009/05/donttry2-p1.png

Plot 2

> df2 <- data.frame(rdata, id = levels(dummy$id)[2])
> p2 <- p1 + geom_point(data = df2) + geom_text(data = df2,
     aes(label = City, hjust = -0.1, vjust = 0.5),
     size = 4.5)
https://learnr.files.wordpress.com/2009/05/donttry2-p2.png

Plot 3 – Averages

> df3 <- data.frame(recast(rdata, City ~ variable,
     mean), id = levels(dummy$id)[3])
> p3 <- p2 + geom_point(data = df3) + geom_text(data = df3,
     aes(label = City, hjust = -0.1, vjust = 0.5),
     size = 4.5)
https://learnr.files.wordpress.com/2009/05/donttry2-p3.png

Final Plot

> df4 <- data.frame(rdata, id = levels(dummy$id)[4])
> df4t <- ddply(df4, .(City), function(df) {
     with(df, data.frame(X = X[which.max(Y)],
         Y = max(Y), id = levels(id)[id[which.max(Y)]]))
 })
> p4 <- p3 + geom_polygon(data = df4, aes(group = City)) +
     geom_path(data = df4, aes(group = City)) +
     geom_point(data = df4) + geom_text(data = df4t,
     aes(label = City, hjust = -0.1, vjust = 0.5),
     size = 4.5)
https://learnr.files.wordpress.com/2009/05/donttry2-p4.png

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: