# Introduction to ggInterval

### A source-portable companion for interval-valued visualization

#### Bo-Syue Jiang and Han-Ming Wu

#### 2026-04-28

# 1 Overview

`ggInterval` extends `ggplot2` for interval-valued data. The package supports visualizations such as scatter plots, histograms, index plots, radar plots, line plots, PCA displays, and correlation heatmaps, while keeping the layered grammar familiar to `ggplot2` users.

This vignette focuses on source-portable examples that can be rebuilt directly from the package. It uses built-in data, the bundled `data.csv` file for the aggregation example, and optional sections for packages such as `HistDAWass` and `MAINT.Data`.

# 2 Built-in Data

    data(facedata)
    data(Environment)

    facedata
    #> # A tibble: 27 × 6
    #>                   AD              BC                AH                DH
    #>  *        <symblc_n>      <symblc_n>        <symblc_n>        <symblc_n>
    #>  1 [155.00 : 157.00] [58.00 : 61.01] [100.45 : 103.28] [105.00 : 107.30]
    #>  2 [154.00 : 160.01] [57.00 : 64.00] [101.98 : 105.55] [104.35 : 107.30]
    #>  3 [154.01 : 161.00] [57.00 : 63.00]  [99.36 : 105.65] [101.04 : 109.04]
    #>  4 [168.86 : 172.84] [58.55 : 63.39] [102.83 : 106.53] [122.38 : 124.52]
    #>  5 [169.85 : 175.03] [60.21 : 64.38] [102.94 : 108.71] [120.24 : 124.52]
    #>  6 [168.76 : 175.15] [61.40 : 63.51] [104.35 : 107.45] [120.93 : 125.18]
    #>  7 [155.26 : 160.45] [53.15 : 60.21]   [95.88 : 98.49]   [91.68 : 94.37]
    #>  8 [156.26 : 161.31] [51.09 : 60.07]   [95.77 : 99.36]   [91.21 : 96.83]
    #>  9 [154.47 : 160.31] [55.08 : 59.03]   [93.54 : 98.98]   [90.43 : 96.43]
    #> 10 [164.00 : 168.00] [55.01 : 60.03] [120.28 : 123.04] [117.52 : 121.02]
    #> # ℹ 17 more rows
    #> # ℹ 2 more variables: EH <symblc_n>, GH <symblc_n>
    Environment
    #> # A tibble: 14 × 17
    #>                        URBANICITY                    INCOMELEVEL
    #>                        <symblc_m>                     <symblc_m>
    #>  1 6:0.14 4:0.43 5:0.08 1:0.21... 25:0.91 50:0.02 75:0.07 90:...
    #>  2 6:0.08 4:0.49 5:0.08 1:0.15... 25:0.56 50:0.15 75:0.29 90:...
    #>  3 6:0.13 4:0.42 5:0.10 1:0.24... 25:0.16 50:0.32 75:0.18 90:...
    #>  4 6:0.18 4:0.50 5:0.11 1:0.15... 25:0.12 50:0.18 75:0.07 90:...
    #>  5 6:0.12 4:0.38 5:0.08 1:0.30... 25:0.11 50:0.27 75:0.27 90:...
    #>  6 6:0.10 4:0.58 5:0.10 1:0.10... 25:0.04 50:0.12 75:0.06 90:...
    #>  7 6:0.10 4:0.39 5:0.10 1:0.31... 25:0.14 50:0.20 75:0.61 90:...
    #>  8 6:0.19 4:0.47 5:0.09 1:0.14... 25:0.99 50:0.01 75:0.00 90:...
    #>  9 6:0.22 4:0.42 5:0.13 1:0.15... 25:0.73 50:0.04 75:0.21 90:...
    #> 10 6:0.18 4:0.45 5:0.11 1:0.17... 25:0.22 50:0.41 75:0.30 90:...
    #> 11 6:0.18 4:0.43 5:0.09 1:0.17... 25:0.12 50:0.30 75:0.28 90:...
    #> 12 6:0.11 4:0.44 5:0.10 1:0.23... 25:0.11 50:0.39 75:0.37 90:...
    #> 13 6:0.23 4:0.41 5:0.13 1:0.11... 25:0.05 50:0.30 75:0.10 90:...
    #> 14 6:0.14 4:0.41 5:0.08 1:0.26... 25:0.21 50:0.07 75:0.69 90:...
    #> # ℹ 15 more variables: EDUCATION <symblc_m>, REGIONDEVELOPME <symblc_m>,
    #> #   CONTROL <symblc_n>, SATISFY <symblc_n>, INDIVIDUAL <symblc_n>,
    #> #   WELFARE <symblc_n>, HUMAN <symblc_n>, POLITICS <symblc_n>,
    #> #   BURDEN <symblc_n>, NOISE <symblc_n>, NATURE <symblc_n>, SEASETC <symblc_n>,
    #> #   MULTI <symblc_n>, WATERWASTE <symblc_n>, VEHICLE <symblc_n>

    Subjects <- substr(rownames(facedata), 1, 3)
    Subjects
    #>  [1] "FRA" "FRA" "FRA" "HUS" "HUS" "HUS" "INC" "INC" "INC" "ISA" "ISA" "ISA"
    #> [13] "JPL" "JPL" "JPL" "KHA" "KHA" "KHA" "LOT" "LOT" "LOT" "PHI" "PHI" "PHI"
    #> [25] "ROM" "ROM" "ROM"

# 3 Basic Usage

    ggInterval_scatterplot(
      facedata,
      aes(x = AD, y = BC, fill = Subjects),
      showLabels = FALSE,
      col = "black"
    ) +
      scale_fill_brewer(palette = "Set1") +
      labs(fill = "Subjects")

# 4 Aggregating Classical Data into Interval-Valued Data

    breastData <- read.csv("data.csv")
    breastData$X <- NULL
    breastData <- dplyr::select(breastData, -id)

    breastData_kmeans <- classic2sym(breastData, groupby = "kmeans", k = 5)
    head(breastData_kmeans$intervalData[, 1:4])
    #> # A tibble: 5 × 4
    #>       diagnosis     radius_mean    texture_mean    perimeter_mean
    #>      <symblc_m>      <symblc_n>      <symblc_n>        <symblc_n>
    #> 1 B:0.98 M:0.02  [6.98 : 13.05]  [9.71 : 33.81]   [43.79 : 85.09]
    #> 2 B:0.04 M:0.96 [13.81 : 19.59] [11.89 : 39.28]  [91.56 : 132.40]
    #> 3 B:0.00 M:1.00 [20.73 : 28.11] [17.25 : 31.12] [135.70 : 188.50]
    #> 4 B:0.00 M:1.00 [15.50 : 24.25] [10.38 : 32.47] [102.90 : 166.20]
    #> 5 B:0.68 M:0.32 [11.84 : 16.30] [10.89 : 30.72]  [77.93 : 109.80]

    breastData_diag <- classic2sym(breastData, groupby = "diagnosis")
    head(breastData_diag$intervalData[, 1:4])
    #>       radius_mean    texture_mean   perimeter_mean           area_mean
    #> 1  [6.98 : 17.85]  [9.71 : 33.81] [43.79 : 114.60]   [143.50 : 992.10]
    #> 2 [10.95 : 28.11] [10.38 : 39.28] [71.90 : 188.50] [361.60 : 2,501.00]

# 5 Descriptive Statistics

    mean(facedata)
    #> # A tibble: 1 × 6
    #>      AD    BC    AH    DH    EH    GH
    #>   <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
    #> 1  163.  60.0  113.  113.  59.8  57.7
    sd(facedata)
    #> # A tibble: 1 × 6
    #>      AD    BC    AH    DH    EH    GH
    #>   <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
    #> 1  6.84  4.58  8.98  9.40  4.24  4.78

    cov(facedata$AD, facedata$BC, method = "BD")
    #> [1] 21.47015
    cor(facedata$AD, facedata$BC, method = "BD")
    #> [1] 0.6846339

    summary(facedata$AD)
    #> <symbolic_interval[7]>
    #>              Min.           1st Qu.            Median              Mean
    #> [149.34 : 155.32] [154.56 : 158.91] [163.00 : 167.07] [162.90 : 162.90]
    #>           3rd Qu.              Max.              Std.
    #> [167.13 : 171.19] [169.85 : 175.15]     [6.84 : 6.84]
    summary(Environment[1:3, ])
    #> $symbolic_interval
    #>                     CONTROL            SATISFY          INDIVIDUAL
    #> Min.    [-723.25 : -339.65] [-134.15 : 191.17] [-658.77 : -299.04]
    #> 1st Qu. [-483.56 : -124.77] [-134.03 : 221.00] [-625.52 : -268.47]
    #> Median    [-243.86 : 90.10] [-133.91 : 250.83] [-592.28 : -237.90]
    #> Mean    [-201.35 : -201.35]    [68.96 : 68.96] [-398.20 : -398.20]
    #> 3rd Qu.  [-219.66 : 147.05] [-104.46 : 282.82] [-542.15 : -173.54]
    #> Max.     [-195.44 : 203.99]  [-75.00 : 314.80] [-492.03 : -109.17]
    #> Std.      [258.04 : 258.04]  [109.12 : 109.12]   [127.06 : 127.06]
    #>                    WELFARE               HUMAN           POLITICS
    #> Min.    [-229.94 : 138.29] [-879.71 : -501.15] [-491.78 : -70.01]
    #> 1st Qu. [-184.41 : 161.36] [-726.36 : -312.15]  [-346.20 : 66.67]
    #> Median  [-138.88 : 184.42] [-573.00 : -123.14] [-200.61 : 203.36]
    #> Mean       [92.63 : 92.63] [-352.28 : -352.28]  [-63.41 : -63.41]
    #> 3rd Qu.  [-26.15 : 349.88]    [-367.09 : 0.68] [-145.13 : 235.78]
    #> Max.      [86.57 : 515.34]  [-161.18 : 124.50]  [-89.65 : 268.21]
    #> Std.     [183.83 : 183.83]   [295.23 : 295.23]  [192.80 : 192.80]
    #>                      BURDEN               NOISE             NATURE
    #> Min.    [-619.29 : -254.11]  [-403.24 : -29.45]  [-190.28 : 83.12]
    #> 1st Qu. [-548.22 : -171.34]   [-377.24 : -4.36] [-145.13 : 195.19]
    #> Median   [-477.14 : -88.57]   [-351.24 : 20.72]  [-99.99 : 307.27]
    #> Mean    [-282.90 : -282.90] [-152.88 : -152.88]  [111.80 : 111.80]
    #> 3rd Qu.   [-423.03 : 11.05]   [-294.80 : 52.49]  [-33.02 : 422.00]
    #> Max.     [-368.92 : 110.66]   [-238.37 : 84.26]   [33.96 : 536.72]
    #> Std.      [166.31 : 166.31]   [111.68 : 111.68]  [181.34 : 181.34]
    #>                     SEASETC              MULTI          WATERWASTE
    #> Min.    [-747.46 : -169.30] [-215.07 : 226.66] [-542.37 : -146.89]
    #> 1st Qu. [-679.36 : -125.54] [-177.55 : 249.70]    [-368.52 : 8.80]
    #> Median   [-611.26 : -81.79] [-140.04 : 272.75]  [-194.66 : 164.49]
    #> Mean    [-262.66 : -262.66]    [66.25 : 66.25]   [-80.69 : -80.69]
    #> 3rd Qu.   [-367.73 : 38.11]  [-97.46 : 290.42]  [-157.59 : 260.17]
    #> Max.     [-124.20 : 158.01]  [-54.88 : 308.08]  [-120.52 : 355.84]
    #> Std.      [243.16 : 243.16]  [121.64 : 121.64]   [224.56 : 224.56]
    #>                     VEHICLE
    #> Min.    [-840.00 : -574.57]
    #> 1st Qu. [-754.88 : -405.27]
    #> Median  [-669.76 : -235.98]
    #> Mean    [-409.06 : -409.06]
    #> 3rd Qu.  [-437.21 : -82.68]
    #> Max.      [-204.67 : 70.63]
    #> Std.      [280.31 : 280.31]
    #>
    #> $symbolic_modal
    #>      URBANICITY INCOMELEVEL EDUCATION REGIONDEVELOPME
    #> [1,] 6: 0.12    25: 0.54    1: 0.42   4: 0.51
    #> [2,] 4: 0.45    50: 0.17    3: 0.57   3: 0.27
    #> [3,] 5: 0.09    75: 0.18    5: 0.01   2: 0.15
    #> [4,] 1: 0.20    90: 0.07    6: 0.00   1: 0.08
    #> [5,] 3: 0.10    100: 0.04
    #> [6,] 2: 0.05

# 6 Univariate Plots

## 6.1 Index Plots and Index Images

    ggInterval_indexplot(facedata, aes(x = AD))

    ggInterval_indexplot(facedata, aes(x = AD, fill = Subjects)) +
      scale_fill_brewer(palette = "Set1") +
      geom_vline(xintercept = mean(facedata$AD), color = "darkgray") +
      labs(fill = "Subjects")

    ggInterval_indexImage(facedata, aes(x = AD)) +
      coord_flip()

    ggInterval_indexImage(facedata, aes(x = AD), full_strip = TRUE) +
      coord_flip()

    face.ip <- ggInterval_indexplot(facedata, aes(fill = Subjects), plotAll = TRUE) +
      scale_fill_brewer(palette = "Set1") +
      labs(x = "", y = "", fill = "Subjects")
    face.ip

    b <- ggInterval_indexplot(facedata, aes(fill = Subjects),
      plotAll = TRUE, row_order = "c") +
      scale_fill_brewer(palette = "Set1") +
      labs(x = "", y = "", fill = "Subjects")
    b

    cc <- ggInterval_indexplot(facedata, aes(fill = Subjects),
      plotAll = TRUE, row_order = "r") +
      scale_fill_brewer(palette = "Set1") +
      labs(x = "", y = "", fill = "Subjects")
    cc

In the ordered `plotAll` displays, the outer y-axis labels are suppressed by default. Here `row_order = "c"` reorders observations by interval centers within each variable panel, while `row_order = "r"` reorders them by interval ranges within each variable panel. Set `labels = TRUE` if you want the row labels repeated inside each variable panel.

## 6.2 Boxplots and Histograms

    ggInterval_boxplot(facedata, plotAll = TRUE, width_type = "violin-like") +
      theme(legend.position = "bottom", axis.text.x = element_blank())

    ggInterval_boxplot(facedata, plotAll = TRUE, width_type = "side-by-side") +
      theme(legend.position = "bottom", axis.text.x = element_blank())

    ggInterval_boxplot(facedata, aes(x = AD), width_type = "quantile-depth")

    hist.obj.equal <- ggInterval_hist(facedata, plotAll = TRUE, bins = 10)
    print(hist.obj.equal)

    hist.obj.equal$`Table AD`
    #>           Interval Observed.Frequency Relative.Frequency
    #> 1  [149.34:151.92]           1.077477         0.03990656
    #> 2   [151.92:154.5]           1.753623         0.06494900
    #> 3   [154.5:157.08]           5.525627         0.20465284
    #> 4  [157.08:159.66]           2.806570         0.10394703
    #> 5  [159.66:162.24]           1.042880         0.03862518
    #> 6  [162.24:164.83]           1.703999         0.06311106
    #> 7  [164.83:167.41]           3.304380         0.12238443
    #> 8  [167.41:169.99]           4.948225         0.18326760
    #> 9  [169.99:172.57]           3.738883         0.13847713
    #> 10 [172.57:175.15]           1.098337         0.04067915

    hist.obj.unequal <- ggInterval_hist(
      facedata,
      plotAll = TRUE,
      method = "unequal-bin"
    )
    print(hist.obj.unequal)

    ggInterval_hist(facedata, aes(x = AD), method = "equal-bin", bins = 10)

    ggInterval_hist(facedata, aes(x = AD), method = "unequal-bin")

## 6.3 Line Plot

    if (!requireNamespace("TTR", quietly = TRUE)) {
      stop("Package 'TTR' is required for this example.")
    }

    data("ttrc", package = "TTR")
    stock.data <- subset(
      ttrc[, c("Date", "Close", "Low", "High")],
      format(Date, "%Y-%m") %in% c("1985-01", "1985-02", "1985-03")
    )
    stock.data$Month <- factor(
      month.abb[as.integer(format(stock.data$Date, "%m"))],
      levels = month.abb[1:3]
    )
    stock.data$Day <- as.integer(format(stock.data$Date, "%d"))

    stock.data.LH <- classic2sym(
      stock.data,
      groupby = "customize",
      minData = stock.data$Low,
      maxData = stock.data$High
    )

    ggInterval_lineplot(stock.data.LH, aes(y = V1, x = Day), barWidth = 0.6) +
      geom_point(aes(y = Close), shape = 21, fill = "#D95F02",
                 color = "black", size = 1.6, stroke = 0.2) +
      coord_cartesian(xlim = c(1, 31), expand = FALSE) +
      facet_wrap(~Month, ncol = 1, scales = "free_y") +
      scale_x_continuous(breaks = c(1, 8, 15, 22, 29)) +
      labs(title = "Interval-valued Line Plot",
           x = "Day of month", y = "Price") +
      ggthemes::theme_economist() +
      theme(strip.text = element_text(face = "bold"))

## 6.4 Min-Max Plot

    mm.plot <- function(x) {
      plot.var <<- names(facedata)[x]
      ggInterval_MMplot(facedata, aes(facedata[[plot.var]], size = 2)) +
        coord_fixed(ratio = 1) +
        theme(legend.position = "none")
    }

    mm.plot.list <- lapply(seq_along(facedata), mm.plot)
    gridExtra::marrangeGrob(mm.plot.list, nrow = 2, ncol = 3, top = "")

## 6.5 Center-Range Plot

    cr_aspect_ratio <- 5

    ggInterval_CRplot(facedata, aes(size = 1.5), plotAll = TRUE) +
      coord_fixed(ratio = cr_aspect_ratio)

    facedata.scale <- scale(facedata)$intervalData
    ggInterval_CRplot(facedata.scale, aes(size = 1.5), plotAll = TRUE) +
      coord_fixed(ratio = cr_aspect_ratio)

# 7 Bivariate Plots

## 7.1 Scatter Plot with Label Controls

    ggInterval_scatterplot(
      facedata,
      aes(x = BC, y = AD, fill = Subjects),
      showLabels = TRUE,
      labelSize = 2.6,
      labelPosition = "topright",
      labelNudgeX = -0.2,
      labelNudgeY = 0.15,
      checkOverlap = FALSE,
      color = "black"
    ) +
      scale_fill_brewer(palette = "Set1") +
      scale_x_continuous(expand = expansion(mult = c(0.08, 0.12))) +
      scale_y_continuous(expand = expansion(mult = c(0.06, 0.10))) +
      labs(fill = "Subjects")

## 7.2 2D Histograms

    face.2dh.equal <- ggInterval_2Dhist(
      facedata,
      aes(x = BC, y = AD, col = "white"),
      method = "equal-bin",
      xBins = 10,
      yBins = 10,
      display = "p",
      palette = "Blues",
      direction = 1,
      cell_labels = TRUE
    )$plot

    face.2dh.equal +
      coord_fixed(ratio = 1)

    face.2dh.unequal <- ggInterval_2Dhist(
      facedata,
      aes(x = BC, y = AD, col = "white"),
      method = "unequal-bin",
      display = "p",
      palette = "Blues",
      direction = 1,
      tau = 0.5
    )$plot

    face.2dh.unequal +
      coord_fixed(ratio = 1)

# 8 Matrix Displays

## 8.1 Scatter Matrix

    ggInterval_scatterMatrix(facedata)

    ggInterval_scatterMatrix(facedata, aes(fill = "steelblue", alpha = 0.3))

## 8.2 2D Histogram Matrices

    ggInterval_2DhistMatrix(
      facedata,
      aes(col = "white"),
      method = "equal-bin",
      xBins = 10,
      yBins = 10,
      display = "p",
      removeZero = TRUE,
      palette = "Blues",
      direction = 1,
      cell_labels = FALSE
    )

    ggInterval_2DhistMatrix(
      facedata,
      aes(col = "white"),
      method = "unequal-bin",
      display = "p",
      palette = "Blues",
      direction = 1,
      tau = 0.5,
      removeZero = TRUE,
      cell_labels = FALSE
    )

## 8.3 Image Plots

    ggInterval_indexImage(
      facedata,
      plotAll = TRUE,
      full_strip = TRUE,
      column_condition = FALSE
    ) +
      scale_colour_distiller(palette = "Blues", direction = 1) +
      labs(x = "Subjects") +
      theme(axis.title.x = element_blank(),
            axis.text.x = element_blank(),
            axis.ticks.x = element_blank())

    ggInterval_indexImage(
      facedata,
      plotAll = TRUE,
      full_strip = TRUE
    ) +
      scale_colour_distiller(palette = "Spectral") +
      labs(x = "Subjects")

    ggInterval_indexImage(
      facedata,
      plotAll = TRUE,
      full_strip = FALSE,
      column_condition = FALSE
    ) +
      scale_colour_distiller(palette = "Blues", direction = 1) +
      labs(x = "Subjects") +
      theme(axis.title.x = element_blank(),
            axis.text.x = element_blank(),
            axis.ticks.x = element_blank())

    ggInterval_indexImage(
      facedata,
      plotAll = TRUE,
      full_strip = FALSE
    ) +
      scale_colour_distiller(palette = "Spectral") +
      labs(x = "Subjects")

## 8.4 Radar Plots

    library(ggthemes)

    ggInterval_radarplot(
      Environment,
      plotPartial = c(4, 6),
      showLegend = FALSE,
      base_circle = FALSE,
      base_lty = 1,
      addText = FALSE,
      addText_modal = FALSE
    ) +
      scale_fill_manual(values = c("darkred", "darkblue")) +
      scale_color_manual(values = c("darkred", "darkblue")) +
      labs(title = "") +
      theme_hc()

    ggInterval_radarplot(
      Environment,
      plotPartial = c(4, 6),
      showLegend = FALSE,
      base_circle = FALSE,
      base_lty = 1,
      addText = FALSE,
      addText_modal = FALSE,
      type = "rect"
    ) +
      scale_fill_manual(values = c("darkred", "darkblue")) +
      scale_color_manual(values = c("darkred", "darkblue")) +
      labs(title = "") +
      theme_hc()

    ggInterval_radarplot(
      facedata,
      base_circle = FALSE,
      base_lty = 1,
      type = "quantile",
      quantileNum = 5,
      showLegend = TRUE,
      Drift = 0
    ) +
      scale_fill_brewer(palette = "Greys") +
      labs(title = "", fill = "Quantiles") +
      theme_hc()

    ggInterval_radarplot(
      Environment,
      base_circle = FALSE,
      base_lty = 1,
      type = "quantile",
      quantileNum = 5,
      showLegend = TRUE,
      Drift = 0
    ) +
      scale_fill_brewer(palette = "Greys") +
      labs(title = "", fill = "Quantiles") +
      theme_hc()

# 9 Customization

    set.seed(1234567890)
    facedata.tmp <- facedata
    facedata.tmp$cluster <- RSDA::sym.kmeans(facedata.tmp, k = 3)$cluster

    ggInterval_indexplot(facedata.tmp, aes(y = AD, fill = Subjects)) +
      geom_text(
        aes(x = seq_len(nrow(facedata.tmp)), y = .data$AD$min,
            label = rownames(facedata.tmp)),
        vjust = 1.5,
        size = 2
      ) +
      scale_fill_brewer(palette = "Set1") +
      labs(title = "Customized Index Plot Using K-Means Clusters",
           fill = "Subjects") +
      facet_grid(cols = vars(cluster), scales = "free_x", space = "free_x") +
      theme_economist_white() +
      theme(axis.title.x = element_blank(),
            axis.text.x = element_blank(),
            axis.ticks.x = element_blank())

# 10 Working with Other SDA Packages

## 10.1 Histogram-Valued Data via HistDAWass

This example is evaluated only when the optional package `HistDAWass` is installed.

    BLOOD <- HistDAWass::BLOOD
    blood.min <- HistDAWass::get.MatH.stats(BLOOD, stat = "min")
    blood.max <- HistDAWass::get.MatH.stats(BLOOD, stat = "max")
    blood <- data.frame(blood.min, blood.max)

    myBLOOD <- classic2sym(
      blood,
      groupby = "customize",
      minData = blood[, 2:4],
      maxData = blood[, 6:8]
    )

    colnames(myBLOOD$intervalData) <- HistDAWass::get.MatH.main.info(BLOOD)$varnames
    ggInterval_PCA(myBLOOD$intervalData, plot = FALSE)$ggplotPCA

## 10.2 Midpoint-Range Data via MAINT.Data

This example is evaluated only when the optional package `MAINT.Data` is installed.

    AbaloneIdt <- MAINT.Data::AbaloneIdt

    AbaloneRange <- exp(AbaloneIdt@LogR)
    AbaloneMid <- AbaloneIdt@MidP
    AbaloneBounds <- data.frame(
      AbaloneMid - AbaloneRange / 2,
      AbaloneMid + AbaloneRange / 2
    )

    myAbalone <- classic2sym(
      AbaloneBounds,
      groupby = "customize",
      minData = AbaloneBounds[, 1:7],
      maxData = AbaloneBounds[, 8:14]
    )

    colnames(myAbalone$intervalData) <- AbaloneIdt@VarNames
    ggInterval_PCA(myAbalone$intervalData, plot = FALSE)$ggplotPCA

# 11 PCA and Correlation Heatmaps

    pca.results <- RSDA::sym.pca(facedata, method = "tops")
    rownames(pca.results$Sym.Components) <- rownames(facedata)

    ggInterval_scatterplot(
      pca.results$Sym.Components,
      aes(Dim.1, Dim.2, fill = as.factor(Subjects)),
      labelSize = 2.6,
      labelPosition = "topright",
      labelNudgeX = -0.2,
      labelNudgeY = 0.15,
      checkOverlap = TRUE,
      col = "black"
    ) +
      scale_fill_brewer(palette = "Set1") +
      scale_x_continuous(expand = expansion(mult = c(0.08, 0.12))) +
      scale_y_continuous(expand = expansion(mult = c(0.06, 0.10))) +
      coord_fixed(ratio = 1) +
      labs(x = "PCA-1", y = "PCA-2", fill = "Subjects")

    ggInterval_PCA(facedata, poly = TRUE, concepts_group = as.factor(Subjects)) +
      coord_fixed(ratio = 1) +
      labs(x = "PCA-1", y = "PCA-2")

    #> NULL

    ggInterval_corrplot(facedata, method = "BG", triangle = "lower")

# 12 Citation

Use `citation("ggInterval")` after installation to retrieve the current package citation metadata.

# 13 Session Information

    sessionInfo()
    #> R version 4.6.0 (2026-04-24 ucrt)
    #> Platform: x86_64-w64-mingw32/x64
    #> Running under: Windows 10 x64 (build 19045)
    #>
    #> Matrix products: default
    #>   LAPACK version 3.12.1
    #>
    #> locale:
    #> [1] LC_COLLATE=C
    #> [2] LC_CTYPE=Chinese (Traditional)_Taiwan.utf8
    #> [3] LC_MONETARY=Chinese (Traditional)_Taiwan.utf8
    #> [4] LC_NUMERIC=C
    #> [5] LC_TIME=Chinese (Traditional)_Taiwan.utf8
    #>
    #> time zone: Asia/Taipei
    #> tzcode source: internal
    #>
    #> attached base packages:
    #> [1] stats     graphics  grDevices utils     datasets  methods   base
    #>
    #> other attached packages:
    #>  [1] RSQLite_2.4.6    ggthemes_5.2.0   ggInterval_0.2.5 RSDA_3.2.5
    #>  [5] lubridate_1.9.5  forcats_1.0.1    stringr_1.6.0    dplyr_1.2.1
    #>  [9] purrr_1.2.2      readr_2.2.0      tidyr_1.3.2      tibble_3.3.1
    #> [13] tidyverse_2.0.0  ggplot2_4.0.3
    #>
    #> loaded via a namespace (and not attached):
    #>   [1] neuralnet_1.44.2     splines_4.6.0        polyclip_1.10-7
    #>   [4] xts_0.14.2           XML_3.99-0.23        rpart_4.1.27
    #>   [7] lifecycle_1.0.5      tcltk_4.6.0          rstatix_0.7.3
    #>  [10] globals_0.19.1       lattice_0.22-9       MASS_7.3-65
    #>  [13] flashClust_1.1-4     backports_1.5.1      magrittr_2.0.5
    #>  [16] plotly_4.12.0        sass_0.4.10          rmarkdown_2.31
    #>  [19] jquerylib_0.1.4      yaml_2.3.12          otel_0.2.0
    #>  [22] sn_2.1.3             askpass_1.2.1        reticulate_1.46.0
    #>  [25] DBI_1.3.0            RColorBrewer_1.1-3   abind_1.4-8
    #>  [28] Rtsne_0.17           tweenr_2.0.3         lava_1.9.0
    #>  [31] gbm_2.2.3            ggrepel_0.9.8        listenv_0.10.1
    #>  [34] proto_1.0.0          umap_0.2.10.0        RSpectra_0.16-2
    #>  [37] parallelly_1.47.0    codetools_0.2-20     DT_0.34.0
    #>  [40] ggforce_0.5.0        tidyselect_1.2.1     shape_1.4.6.1
    #>  [43] farver_2.1.2         stats4_4.6.0         jsonlite_2.0.0
    #>  [46] Formula_1.2-5        ggridges_0.5.7       randomcoloR_1.1.0.1
    #>  [49] survival_3.8-6       iterators_1.0.14     emmeans_2.0.3
    #>  [52] HistDAWass_1.0.8     foreach_1.5.2        tools_4.6.0
    #>  [55] chron_2.3-62         miscTools_0.6-30     Rcpp_1.1.1-1.1
    #>  [58] glue_1.8.1           mnormt_2.1.2         prodlim_2026.03.11
    #>  [61] gridExtra_2.3        xfun_0.57            TTR_0.24.4
    #>  [64] withr_3.0.2          numDeriv_2016.8-1.1  fastmap_1.2.0
    #>  [67] GGally_2.4.0         openssl_2.4.0        digest_0.6.39
    #>  [70] timechange_0.4.0     R6_2.6.1             estimability_1.5.1
    #>  [73] colorspace_2.1-2     gtools_3.9.5         MAINT.Data_2.8.0
    #>  [76] ggpolypath_0.4.0     generics_0.1.4       data.table_1.18.2.1
    #>  [79] robustbase_0.99-7    class_7.3-23         httr_1.4.8
    #>  [82] htmlwidgets_1.6.4    scatterplot3d_0.3-45 sqldf_0.4-12
    #>  [85] ggstats_0.13.0       RJSONIO_2.0.0        pkgconfig_2.0.3
    #>  [88] gtable_0.3.6         blob_1.3.0           S7_0.2.2
    #>  [91] pcaPP_2.0-5          htmltools_0.5.9      carData_3.0-6
    #>  [94] multcompView_0.1-11  scales_1.4.0         leaps_3.2
    #>  [97] png_0.1-9            histogram_0.0-25     knitr_1.51
    #> [100] tzdb_0.5.0           curl_7.1.0           nloptr_2.2.1
    #> [103] cachem_1.1.0         zoo_1.8-15           parallel_4.6.0
    #> [106] pillar_1.11.1        grid_4.6.0           reshape_0.8.10
    #> [109] vctrs_0.7.3          randomForest_4.7-1.2 ggpubr_0.6.3
    #> [112] car_3.1-5            xtable_1.8-8         cluster_2.1.8.2
    #> [115] princurve_2.1.6      evaluate_1.0.5       gsubfn_0.7
    #> [118] mvtnorm_1.3-7        cli_3.6.6            compiler_4.6.0
    #> [121] rlang_1.2.0          rrcov_1.7-7          future.apply_1.20.2
    #> [124] ggsignif_0.6.4       labeling_0.4.3       mclust_6.1.2
    #> [127] plyr_1.8.9           stringi_1.8.7        viridisLite_0.4.3
    #> [130] lazyeval_0.2.3       glmnet_4.1-10        V8_8.2.0
    #> [133] Matrix_1.7-5         hms_1.1.4            bit64_4.8.0
    #> [136] future_1.70.0        FactoMineR_2.14      kknn_1.4.1
    #> [139] igraph_2.3.0         broom_1.0.12         memoise_2.0.1
    #> [142] bslib_0.10.0         DEoptimR_1.1-4       bit_4.6.0