--- title: "Basics" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Basics} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) ``` ```{r setup} library(ggcolonviz) library(ggplot2) ``` ## Basic Plotting ```{r example_data} patient_data <- data.frame( x = 0, y = 0, part = c( "Cecum", "Ileum", "Ascending", "Transverse", "Descending", "Sigmoid", "Rectum" ) ) ``` ```{r example_plot} patient_data |> ggplot(aes(x = x, y = y, part = part)) + geom_colon( color = "black", linewidth = 0.5, fill = "lightblue", show.legend = FALSE ) + geom_colon_label() + coord_fixed() + theme_void() ``` ## Layout Variants The SESCD variant is designed for visualizing the Simple Endoscopic Score for Crohn's Disease (SES-CD). It uses a specific layout scheme and labeling to represent the different segments of the colon according to the SES-CD scoring system. ```{r sescd-variant} patient_data <- data.frame( x = 0, y = 0, part = c( "Ileum", "Right", "Left", "Transverse", "Rectum" ) ) patient_data |> ggplot(aes(x = x, y = y, part = part)) + geom_colon( color = "black", linewidth = 0.5, fill = "lightblue", variant = "sescd" ) + geom_colon_label(variant = "sescd") + coord_fixed() + theme_void() ``` ## Custom Labels You can also provide custom labels for each segment of the colon. This allows you to display specific information or annotations directly on the plot. ```{r custom-labels} patient_data <- data.frame( x = 0, y = 0, part = c( "Ileum", "Right", "Left", "Transverse", "Rectum" ), label = c( "Ileum", "Right Colon", "Left Colon", "Transverse Colon", "Rectum" ) ) patient_data |> ggplot(aes(x = x, y = y, part = part)) + geom_colon( color = "black", linewidth = 0.5, fill = "lightblue", variant = "sescd" ) + geom_colon_label(variant = "sescd", aes(label = label)) + coord_fixed() + theme_void() ``` ## Faceting ### Faceting by Subject Faceting is supported, allowing you to create multiple plots based on a categorical variable. For example: ```{r faceting} # Define the parts parts <- c( "Cecum", "Ileum", "Ascending", "Transverse", "Descending", "Sigmoid", "Rectum" ) # Create subjects with discrete stages discrete_data <- dplyr::bind_rows( data.frame( subject = "Subject A: Localized", x = 0, y = 0, part = parts, stage = factor(c(0, 0, 0, 1, 3, 2, 2)) ), # 0=Normal, 1=Mild, 2=Mod, 3=Severe data.frame( subject = "Subject B: Diffuse", x = 0, y = 0, part = parts, stage = factor(c(1, 1, 1, 2, 2, 3, 3)) ), data.frame( subject = "Subject C: Remission", x = 0, y = 0, part = parts, stage = factor(c(0, 0, 0, 0, 0, 1, 1)) ) ) ggplot( discrete_data, aes(x = x, y = y, part = part, fill = stage)) + # 1. Draw the colon segments geom_colon(color = "white", linewidth = 0.5) + # 2. Add the labels (nudge/center logic still applies) # Map color to 'stage' too if you want text to change with background geom_colon_label( aes(angle = after_stat(angle)), size = 2, fontface = "bold", color = "white" ) + # 3. Facet by subject facet_wrap(~subject) + # 4. DISCRETE VIRIDIS # 'plasma' or 'viridis' work well for discrete categories scale_fill_viridis_d( option = "plasma", name = "Disease Stage", labels = c( "0: Normal", "1: Mild", "2: Moderate", "3: Severe" ) ) + coord_fixed() + theme_void() + theme( legend.position = "top" ) ``` ### Faceting by Time You can also create time series plots to show how the condition of the colon changes over time for a patient. ```{r time-series} # Longitudinal data for Subject 101 longitudinal_data <- dplyr::bind_rows( # Baseline: Severe inflammation in the lower colon data.frame( visit = "Week 0", x = 0, y = 0, part = parts, stage = factor(c(0, 0, 0, 1, 3, 3, 3), levels = 0:3) ), # Week 4: Partial response, inflammation moving down data.frame( visit = "Week 04", x = 0, y = 0, part = parts, stage = factor(c(0, 0, 0, 0, 2, 2, 3), levels = 0:3) ), # Week 8: Significant improvement data.frame( visit = "Week 08", x = 0, y = 0, part = parts, stage = factor(c(0, 0, 0, 0, 0, 1, 2), levels = 0:3) ), # Week 12: Clinical Remission data.frame( visit = "Week 12", x = 0, y = 0, part = parts, stage = factor(c(0, 0, 0, 0, 0, 0, 1), levels = 0:3) ) ) ggplot(longitudinal_data, aes(x = x, y = y, part = part, fill = stage)) + # 1. Custom Colon Geometry geom_colon(color = "white", linewidth = 0.4) + # 2. Centered Labels (nudge logic applies to every facet) geom_colon_label( aes(angle = after_stat(angle)), size = 2.2, fontface = "bold", color = "white" ) + # 3. Facet by Visit (Time Point) facet_wrap(~visit, nrow = 1) + # 4. Discrete Viridis Scale scale_fill_viridis_d( option = "magma", # 'magma' highlights 'hot' spots well name = "Disease Stage", labels = c("0: Normal", "1: Mild", "2: Moderate", "3: Severe"), drop = FALSE # Keep all stages in the legend even if not present in a facet ) + coord_fixed() + theme_minimal() + theme( panel.grid = element_blank(), axis.text = element_blank(), axis.title = element_blank(), strip.text = element_text(size = 12, face = "bold"), legend.position = "bottom" ) + labs( title = "Subject 101: Colon Disease Progression Over 12 Weeks") ``` ## Custom Blueprints `ggcolonviz` ships with two built-in layout variants (`"standard"` and `"sescd"`), but you can register your own blueprint for any anatomical scheme you need. ### How a blueprint works A blueprint is a plain data frame with three columns: | Column | Type | Meaning | |--------|------|---------| | `dx` | numeric | Relative x-coordinate of each polygon vertex | | `dy` | numeric | Relative y-coordinate of each polygon vertex | | `part` | character | Name of the segment this vertex belongs to | Each unique `part` value must have **at least 3 rows** (the minimum for a closed polygon). The coordinates are *offsets* — when you supply `x = 5, y = 2` in your plot data, every vertex for that row is shifted by `(5, 2)`. ### Listing available variants ```{r list-variants} list_colon_variants() ``` ### Registering a custom variant Use `register_colon_variant()` to add your blueprint to the package registry. The variant is then available by name in `geom_colon()`, `geom_colon_label()`, `colon_sf()`, and `colon_heatmap_grid()`. ```{r register-variant} # A minimal two-segment blueprint (e.g. a simplified proximal / distal split) simple_blueprint <- data.frame( dx = c(-2, 0, 0, -2, 0, 2, 2, 0), dy = c( 0, 0, 3, 3, 0, 0, 3, 3), part = c(rep("Proximal", 4), rep("Distal", 4)) ) register_colon_variant("simple", simple_blueprint) # Confirm it is registered list_colon_variants() ``` ### Using a custom variant in a plot Once registered, the variant works identically to the built-in ones: ```{r custom-variant-plot} data.frame(x = 0, y = 0, part = c("Proximal", "Distal")) |> ggplot(aes(x = x, y = y, part = part)) + geom_colon( variant = "simple", color = "black", linewidth = 0.5, fill = "lightblue" ) + geom_colon_label(variant = "simple") + coord_fixed() + theme_void() ``` ### Overwriting a variant Calling `register_colon_variant()` with an existing name **replaces** it. This lets you iterate on your blueprint interactively: ```{r overwrite-variant, eval=FALSE} # Refine the blueprint and re-register simple_blueprint_v2 <- simple_blueprint simple_blueprint_v2$dy <- simple_blueprint_v2$dy * 1.5 # taller segments register_colon_variant("simple", simple_blueprint_v2) ``` ### Validation `register_colon_variant()` validates the input and stops with a clear message if: - `name` is not a single non-empty string - `data` is not a data frame - Any of the required columns (`dx`, `dy`, `part`) are missing - `dx` or `dy` are not numeric - Any segment has fewer than 3 vertex rows ```{r validation-example, error=TRUE} # Missing the 'dy' column — will error informatively bad_bp <- data.frame(dx = c(0, 1, 1), part = c("A", "A", "A")) register_colon_variant("bad", bad_bp) ```