marimekko (mosaic) plots for ggplot2.
A one-sided formula controls the variable hierarchy and split directions. Column widths and segment heights encode marginal and conditional proportions of categorical variables.
# Install from CRAN
install.packages("marimekko")
# Or install the development version from GitHub
# devtools::install_github("gogonzo/marimekko")
install.packages("marimekko", repos = c('https://gogonzo.r-universe.dev', 'https://cloud.r-project.org'))
library(ggplot2)
library(marimekko)
titanic <- as.data.frame(Titanic)
ggplot(titanic) +
geom_marimekko(
aes(fill = Survived, weight = Freq),
formula = ~ Class | Survived
) +
labs(title = "Titanic survival by class", y = "Proportion") +
theme_marimekko()
A one-sided formula (~ ...) controls which variables are used, their
nesting order, and how each level splits the plot area. The plot starts
as a single rectangle (the unit square) and each variable subdivides it
further.
There are two split directions:
The first variable always splits horizontally (columns). Each |
switches direction, so the second variable splits vertically (rows
within each column), the third switches back to horizontal, and so on.
| Operator | Meaning |
|---|---|
| |
Separates groups of variables. Each ` |
+ |
Combines variables within the same group — they split in the same direction, one after another. |
| Formula | 1st split | 2nd split | 3rd split | Layout |
|---|---|---|---|---|
~ a | b |
a → columns (horizontal) |
b → rows within each column (vertical) |
— | Standard mosaic |
~ a | b | c |
a → columns |
b → rows |
c → sub-columns |
Alternating 3-level |
~ a + b | c |
a → columns, then b → sub-columns |
c → rows |
— | Double decker |
~ a | b + c |
a → columns |
b → rows, then c → sub-rows |
— | Multiple vertical |
Variables in the formula can be arbitrary R expressions:
~ factor(cyl) | cut(mpg, breaks = 3)
| Feature | Function / Parameter |
|---|---|
| Core marimekko plot | geom_marimekko() |
| Text labels on tiles | geom_marimekko_text() |
| Labels with background box | geom_marimekko_label() |
| Marginal percentages on x-axis | show_percentages = TRUE |
| Compute tiles without plotting | fortify_marimekko() |
| Minimal mosaic theme | theme_marimekko() |
| Pearson residual shading | after_stat(.residuals) |
| Conditional proportion shading | after_stat(.proportion) |
| Independent x/y gaps |
gap_x / gap_y
|
| Plotly interactivity | plotly::ggplotly() |
ggplot(titanic) +
geom_marimekko(
aes(fill = Survived, weight = Freq),
formula = ~ Class | Survived,
show_percentages = TRUE
) +
theme_marimekko()
ggplot(titanic) +
geom_marimekko(
aes(fill = Survived, weight = Freq),
formula = ~ Class | Survived
) +
geom_marimekko_text(aes(label = after_stat(weight)))
ggplot(titanic) +
geom_marimekko(
aes(
fill = Survived, weight = Freq,
alpha = after_stat(abs(.residuals))
),
formula = ~ Class | Survived
) +
scale_alpha_continuous(range = c(0.3, 1), guide = "none")
ggplot(titanic) +
geom_marimekko(
aes(fill = Survived, weight = Freq),
formula = ~ Class | Sex | Survived
)
ggplot(as.data.frame(Titanic)) +
geom_marimekko(
aes(fill = Survived, weight = Freq),
formula = ~ Class | Survived
) +
facet_wrap(~Sex)
ggplot(titanic) +
geom_marimekko(
aes(fill = Survived, weight = Freq),
formula = ~ Class | Survived, gap_x = 0.04, gap_y = 0
)
library(plotly)
p <- ggplot(titanic) +
geom_marimekko(
aes(fill = Survived, weight = Freq),
formula = ~ Class | Survived
)
ggplotly(p)
tiles <- fortify_marimekko(titanic,
formula = ~ Class | Survived, weight = Freq
)
head(tiles)
marimekko extends ggplot2 through the ggproto system:
StatMarimekko parses the formula, recursively partitions the
unit square, and returns tile rectangles (xmin, xmax, ymin,
ymax) with computed variables (.residuals, .proportion, .marginal).GeomRect with sensible defaults
(white borders, slight transparency).marimekko was designed to avoid pain points in other existing packages.
ggplot2 as only dependencyStatMarimekkoTiles exposes tile data so you can pair it with any ggplot2 geom to build custom companion layers (bubbles, residual markers, etc.)~ a | b | c encodes both variables and directionslibrary() -- marimekko::geom_marimekko() just workslevels() are honored~ factor(cyl) | cut(mpg, breaks = 3) worksggplotly() works out of the box