Skip to content

ggplot2: Marimekko Replacement – 2 by 2 Panel

April 1, 2009

Jon Peltier suggests yet one more alternative to the Marimekko chart – a 2 x 2 Panel chart.

https://learnr.files.wordpress.com/2009/04/mekko2x2chart15.png

Tweaking the method described in my previous post allows to quickly reproduce this chart in ggplot2.



List of Changes

A few things have changed compared to the previous post:

  • New Layout – 6 plots used instead of 3
https://learnr.files.wordpress.com/2009/04/marimekko3-layout1.png
  • Removal of x-axis labels in the upper row
  • Small tweaks to the plot margins
  • Separate y-axes limits for upper and lower row

ggplot2 version

https://learnr.files.wordpress.com/2009/04/marimekko3-21.png

Create dataframe

> df <- read.csv(textConnection("
 Segment,Alpha,Beta,Gamma,Delta
 A,1416649,590270,236108,118054
 B,708325,531243,354162,177081
 C,354162,354162,236108,236108
 D,147568,147568,147568,147568"))
> closeAllConnections()

Convert data to long format

> library(ggplot2)
> dfa <- melt(df, id = c("Segment"), variable_name = "Company")

Determine maximum y-axis values to set the axis limits

> ylim1 <- max(cast(dfa, Company ~ ., sum)[,
     2], cast(dfa, Segment ~ ., sum)[, 2])
> ylim2 <- max(dfa$value)

Plot Layout Setup

> Layout <- grid.layout(nrow = 2, ncol = 3, widths = unit(c(4,
     2, 2), c("lines", "null", "null")), heights = unit(c(1,
     1, 1), c("null", "null", "null")))
> grid.show.layout(Layout)
> vplayout <- function(...) {
     grid.newpage()
     pushViewport(viewport(layout = Layout))
 }
> subplot <- function(x, y) viewport(layout.pos.row = x,
     layout.pos.col = y)

Helper function for plotting

> mmplot <- function(a, b, c, d, e, f) {
     vplayout()
     print(a, vp = subplot(1, 1:2))
     print(b, vp = subplot(1, 2))
     print(c, vp = subplot(1, 3))
     print(d, vp = subplot(2, 1:2))
     print(e, vp = subplot(2, 2))
     print(f, vp = subplot(2, 3))
 }

Number format function

> formatter <- function(x, prefix = "$") {
     ifelse(x > 999999999, paste(prefix, comma(x/1e+09,
         nsmall = 1), "bn", sep = ""), ifelse(x >
         999999, paste(prefix, comma(x/1e+06),
         "m", sep = ""), ifelse(x > 999, paste(prefix,
         comma(x/1000), "k", sep = ""), paste(prefix,
         comma(x), sep = ""))))
 }

Formatting

> pa <- ggplot(dfa) + scale_y_continuous(breaks = NA) +
     opts(legend.position = c(0.8, 0.85), legend.background = theme_rect(colour = NA)) +
     opts(panel.background = theme_rect(fill = "white",
         colour = NA)) + opts(panel.grid.minor = theme_blank(),
     panel.grid.major = theme_blank())

Plot y-axes

> pxa <- pa + geom_blank(aes(0.1, value)) + scale_y_continuous(formatter = formatter,
     limits = c(0, ylim1)) + scale_x_discrete(breaks = NA) +
     opts(plot.margin = unit(c(1, 0, 0, 0.5),
         "lines")) + opts(axis.title.x = theme_blank())
> pxb <- pa + geom_blank(aes(0.1, value)) + scale_y_continuous(formatter = formatter,
     limits = c(0, ylim2))

Upper row

> p1a <- pa + geom_bar(aes(Company, value), stat = "identity",
     fill = "dodgerblue4")
> p1a <- p1a + scale_y_continuous(limits = c(0,
     ylim1), breaks = NA)
> p1a <- p1a + scale_x_discrete(breaks = NA)
> p1a <- p1a + opts(plot.margin = unit(c(1, 0,
     0, -1), "lines"))
> p1a <- p1a + opts(axis.title.x = theme_blank())
> p3a <- pa + geom_bar(aes(Segment, value), stat = "identity",
     fill = "mediumseagreen")
> p3a <- p3a + scale_y_continuous(limits = c(0,
     ylim1), breaks = NA)
> p3a <- p3a + scale_x_discrete(breaks = NA)
> p3a <- p3a + opts(plot.margin = unit(c(1, 1,
     0, -0.5), "lines"))
> p3a <- p3a + opts(axis.title.x = theme_blank())

Lower row

> p2a <- pa + geom_bar(aes(Company, value, fill = Segment),
     stat = "identity", position = "dodge")
> p2a <- p2a + scale_fill_brewer(palette = "Blues")
> p2a <- p2a + opts(plot.margin = unit(c(0, 0,
     0.5, -1), "lines"))
> p2a <- p2a + scale_y_continuous(limits = c(0,
     ylim2), breaks = NA)
> p4a <- pa + geom_bar(aes(Segment, value, fill = Company),
     stat = "identity", position = "dodge")
> p4a <- p4a + scale_fill_brewer(palette = "Greens")
> p4a <- p4a + opts(plot.margin = unit(c(0, 1,
     0.5, -0.5), "lines"))
> p4a <- p4a + scale_y_continuous(limits = c(0,
     ylim2), breaks = NA)

Final Plot

> mmplot(pxa, p1a, p3a, pxb, p2a, p4a)
No comments yet

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: