How can spineplot plot ggplot2-like stacked bar charts?

Viewed 313

Section 6.2 of A Layered Grammar of Graphics says the following:

In the grammar, a pie chart is a stacked bar geom drawn in a polar coordinate system.

Similarly, the documentation for ggplot2's coord_polar says:

#' # A pie chart = stacked bar chart + polar coordinates
pie <- ggplot(mtcars, aes(x = factor(1), fill = factor(cyl))) +
 geom_bar(width = 1)
pie + coord_polar(theta = "y")

Running only the first line of their code, I get the following graph. enter image description here

The documentation for spineplot (base R, not ggplot), says:

Spine plots are a special cases of mosaic plots, and can be seen as a generalization of stacked (or highlighted) bar plots.

After reading this, I thought that I would be able to get spineplot to generate a graph like the stacked bar chart above. However, I have failed in every attempt. For various reasons, all of the following throw errors:

spineplot(table(mtcars$cyl))
spineplot(prop.table(mtcars$cyl))
spineplot(factor(mtcars$cyl))
spineplot(mtcars$cyl,nrow(mtcars))
spineplot(factor(mtcars$cyl),nrow(mtcars))
spineplot(nrow(mtcars),factor(mtcars$cyl))

This is much unlike base R's pie(table(mtcars$cyl)) and mosaicplot(table(mtcars$cyl)) which both work without complaint, but do not show the counts for each variable.

So, is it possible to get spineplot to generate the desired stacked bar chart? Or do I have some misunderstanding over what a spineplot is? The article linked earlier also claims that "A bullseye chart is the polar equivalent of the spineplot" and that a pie chart is just a transformed bullseye plot, so there definitely should be some very strong relationship between spineplots and stacked bar charts.

1 Answers

A spineplot requires two variables, so to plot mtcars$cyl you need to add another variable, e.g. mtcars$gear:

spineplot(table(mtcars$cyl, mtcars$gear))

example_1.png

The docs go into more detail and have some good examples of potential uses for this type of plot.

--

Another example; Horsepower is related to the number of cylinders. This is the typical format: "variable (factor), tilde, variable (factor or continuous)":

spineplot(factor(mtcars$cyl) ~ mtcars$hp,
          xlab = "Horsepower",
          ylab = "Number of Gears",
          main = "Spineplot: mtcars dataset")

example_2.png

--

I don't believe it's possible to draw a spineplot like the one in your example. The relationship between spineplots and stacked barplots is as quoted in your question: "spine plots are a special case of mosaic plots, and can be seen as a generalization of stacked (or highlighted) bar plots". They are essentially two stacked barplots combined to show the proportion of two variables in contrast to each other via the widths of the bars (like a mosaic plot). I think the best way to plot the proportion of values for a single variable is to use a stacked barplot, e.g.

par(xpd = TRUE)
par(mar=c(2,4,3,6))
mtcars_cyl_percentage <- as.matrix(table(mtcars$cyl)*100/sum(table(mtcars$cyl)))
barplot(mtcars_cyl_percentage, border="white", col = 4:2, main = "Stacked Barplot: mtcars dataset",
        ylab = "Proportion (%)")
legend("topleft", c("8 cylinders", "6 cylinders", "4 cylinders"),
       inset = c(1, 0), bty = "n", fill = 2:4)

example_3.png

Related