--- title: "Introduction to ggtaichi" author: | Youzhi Yu
University of Chicago date: "`r Sys.Date()`" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Introduction to ggtaichi} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r setup, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>", warning = FALSE, message = FALSE, fig.width = 7, fig.height = 7, fig.align = "center", dpi = 120 ) ``` ## Why taichi? A heat map drawn with `ggplot2::geom_tile()` carries three dimensions of information: the `x` position, the `y` position, and a single value mapped to fill. That is plenty when there is one number per cell, but it forces you to *facet* (or to draw two separate maps) the moment you want to compare two data sources on the same footing. `ggtaichi` removes that limitation by replacing each cell with a **taichi** (yin-yang) diagram. The symbol is a circle split by an S-curve into two interlocking "fish": - the **yang** (light) fish is shaded by one data source, and - the **yin** (dark) fish is shaded by the other. Because both fish live in the same cell, a single `geom_taichi()` layer encodes **four** dimensions at once: `x`, `y`, `yin`, and `yang`. The two sources keep their own color scales and legends, so they can be read independently while still being compared side by side. There are no decorative eyes or markers -- every drop of ink on the plot is mapped to data. ```{r} library(ggtaichi) library(ggplot2) ``` ## Reading a single symbol It is worth zooming in on one cell to see the anatomy of the glyph. The yang fish (its bulb at the bottom) carries one source; the yin fish (its bulb at the top) carries the other. Each half is filled by its own gradient, so a lighter or darker shade is a smaller or larger value. ```{r, fig.width = 4.5, fig.height = 4.5} one <- data.frame(x = 1, y = 1, google = 7, twitter = 3) ggplot(one, aes(x, y)) + geom_taichi(yin = twitter, yang = google) + coord_fixed() + theme_taichi() ``` Here the yang (red) fish reads `7` and the yin (grey) fish reads `3`; the deeper the ink, the larger the number relative to the rest of the data. ## The example data `ggtaichi` ships with the same data sets used by its foundational package `ggDoubleHeat`. `pitts_tg` records the 30-week COVID-related Google and Twitter incidence rates for 9 categories in the Pittsburgh Metropolitan Statistical Area (MSA). ```{r} head(pitts_tg) ``` `states_tg` is the larger sibling, repeating the same measurements across four states, and `pitts_emojis` holds the most popular weekly emoji per category. See `?pitts_tg`, `?states_tg`, and `?pitts_emojis` for the full descriptions. ## A first taichi grid The two value columns are passed to the `yin` and `yang` arguments. Everything else -- the `x`/`y` mapping, faceting, titles -- is plain `ggplot2`. The legend titles default to the column names you supplied (`Twitter` and `Google` here). ```{r, fig.height = 6} ggplot(pitts_tg, aes(x = week, y = category)) + geom_taichi(yin = Twitter, yang = Google) + theme_taichi() + ggtitle("Pittsburgh Google & Twitter Incidence Rate (%)") ``` Each symbol stays round regardless of the panel's aspect ratio, so you do **not** need `coord_fixed()`. The shape is sized in square units, like the radius of a `grid::circleGrob()`. ## Fewer cells, bigger glyphs Thirty weeks across nine categories is a lot of ink in one panel. When the goal is to *read* individual symbols rather than scan an overall texture, subset the data: fewer cells means each taichi is drawn larger. ```{r, fig.height = 8} pitts_small <- subset(pitts_tg, week <= 6) ggplot(pitts_small, aes(x = week, y = category)) + geom_taichi(yin = Twitter, yang = Google) + theme_taichi() + ggtitle("The first six weeks, drawn large") ``` ## Which source should be yin? `yin` defaults to a grey (luminance) ramp and `yang` to a red ramp, echoing the "ink and seal" look of a classic taichi. The choice is yours, but a useful rule of thumb is to put the source you want to read as *intensity* on `yin` (the eye reads darkness quickly) and the source you want to read as *warmth* on `yang`. ## Customizing the color scales Each fish gets its own gradient. `yang_colors` and `yin_colors` accept any color vector (usually hex codes), and `yang_name` / `yin_name` relabel the legends. Any extra argument is forwarded to `ggplot2::scale_fill_gradientn()`, so you can, for example, set common `limits` so both legends share a scale, or pass an `na.value`. ```{r, fig.height = 8} ggplot(pitts_small, aes(x = week, y = category)) + geom_taichi( yin = Twitter, yin_name = "Twitter (%)", yin_colors = c("#deebf7", "#3182bd", "#08306b"), yang = Google, yang_name = "Google (%)", yang_colors = c("#fee6ce", "#e6550d", "#7f2704") ) + theme_taichi() ``` ## Removing the panel padding `ggplot2` leaves a margin around discrete and continuous scales, which can make a taichi grid look like it is floating. `remove_padding()` trims it; tell it whether each axis is continuous (`"c"`) or discrete (`"d"`). ```{r, fig.height = 8} ggplot(pitts_small, aes(x = week, y = category)) + geom_taichi(yin = Twitter, yang = Google) + remove_padding(x = "c", y = "d") + theme_taichi() ``` ## Comparing places with facets Because `geom_taichi()` is an ordinary layer, faceting works out of the box. The `states_tg` data set carries the same measurements across four states; pairing two of them over a few weeks keeps every glyph large and legible. ```{r, fig.height = 8} two_states <- subset(states_tg, state %in% c("New York", "Texas") & week <= 6) ggplot(two_states, aes(x = week, y = category)) + geom_taichi(yin = Twitter, yang = Google) + facet_wrap(~ state, ncol = 1) + remove_padding(x = "c", y = "d") + theme_taichi() + ggtitle("New York vs Texas, weeks 1-6") ``` ## Theming `theme_taichi()` is a light, off-white companion theme that bottoms the legends, drops the panel grid and ticks, and emphasizes the axis labels. It is a normal `ggplot2` theme, so you can override any element afterwards, or skip it entirely and bring your own. ```{r, fig.height = 6} ggplot(pitts_small, aes(x = week, y = category)) + geom_taichi(yin = Twitter, yang = Google) + theme_taichi() + theme(plot.background = element_rect(fill = "white")) + ggtitle("theme_taichi(), then tweaked") ``` ## Acknowledgement `ggtaichi` stands on the shoulders of the [`ggDoubleHeat`](https://CRAN.R-project.org/package=ggDoubleHeat) package, which pioneered the two-source "double" heat map through its `geom_heat_*()` family and supplies the example data used throughout this vignette. Please cite it alongside `ggtaichi`: > Yu Y, Buskirk T (2025). *ggDoubleHeat: A Heatmap-Like Visualization Tool*. > R package version 0.1.3. CRAN: > , GitHub: >