ggplotcli: Universal ggplot2 to Terminal Plotting

Introduction

ggplotcli is a universal converter that renders any ggplot2 plot in the terminal using Unicode/ASCII characters. It automatically extracts data, aesthetics, and styling from ggplot objects, supporting 15+ geom types, faceting, color aesthetics, and legends.

Basic Usage

library(plotcli)
#> Loading required package: R6
#> Loading required package: ggplot2
#> plotcli loaded. Use plotcli_options() to set global options.
library(ggplot2)

# Create a ggplot
p <- ggplot(mtcars, aes(x = wt, y = mpg, color = factor(cyl))) +
  geom_point() +
  labs(title = "MPG vs Weight by Cylinders")

# Render in terminal
ggplotcli(p, width = 60, height = 16)
#> 
#>                 MPG vs Weight by Cylinders                               
#>   35.0       ⠄                                                           
#>                  ⠐                                                       
#>   30.0   ⠐⠐                                                              
#>               ⠠                                             factor(cyl)  
#> m 25.0           ⠁           ⢀                              * 4          
#> p                  ⠄         ⠄                              * 6          
#> g 20.0              ⠐ ⠠ ⠐⠠   ⠐                              * 8          
#>                         ⠈       ⢰    ⠐                                   
#>                              ⡀      ⠁   ⠄                                
#>   15.0                          ⠈⠈⠆ ⠈                  ⠂                 
#>                                      ⠁                                   
#>   10.0                                                ⠂ ⠂                
#>               2.0         3.0         4.0         5.0                    
#>                                wt                                        
#> 

Supported Geoms

Scatter Plots (geom_point)

p <- ggplot(iris, aes(x = Sepal.Length, y = Sepal.Width, color = Species)) +
  geom_point() +
  labs(title = "Iris: Sepal Dimensions by Species")
ggplotcli(p, width = 60, height = 16)
#> 
#>             Iris: Sepal Dimensions by Species                             
#> S  4.5                     ⠠                                              
#> e                    ⡀   ⠄                                                
#> p  4.0                 ⢀     ⠂                                            
#> a                  ⢐  ⢀⢀   ⠐                         ⠐  ⠂   Species       
#> l  3.5       ⠁   ⠁⠨⠠ ⠄   ⠄                     ⠁            * setosa      
#> .         ⢀  ⡁⢀ ⠁ ⢨⠨ ⠁ ⠈      ⡀⠈  ⠁⠨⢀ ⡀ ⠠ ⡀⡀⢀  ⡀            * versicolor  
#> W  3.0   ⢀⢀  ⠂  ⡂⡂⢀    ⢀  ⡀⢀  ⡀⢀⢀   ⠐ ⡀⢀⢐ ⡀⠂  ⡀⡀    ⢀⢀      * virginica   
#> i         ⠐               ⡂⢐ ⡀ ⠐⢐ ⡂⢐⢐ ⡀⠐  ⡀     ⠐⢀   ⢀                    
#> d  2.5               ⠁   ⠄⠁⠠ ⠅ ⠈⠠  ⠈⠈                ⠠                    
#> t                ⠅ ⠈     ⠅⠁⠈       ⠈    ⠈                                 
#> h           ⠁     ⠈      ⠁     ⠐  ⠂⠈                                      
#>    2.0            ⠐                                                       
#>                  5.0          6.0          7.0          8.0               
#>                           Sepal.Length                                    
#> 

Line Plots (geom_line)

# Multiple colored lines
df <- data.frame(
  x = rep(1:30, 2),
  y = c(sin(1:30/4) * 10, cos(1:30/4) * 10),
  type = rep(c("sin", "cos"), each = 30)
)
p <- ggplot(df, aes(x, y, color = type)) +
  geom_line() +
  labs(title = "Sine and Cosine Waves")
ggplotcli(p, width = 60, height = 12)
#> 
#>                   Sine and Cosine Waves                            
#>   10.0   ⠠⢄⡀   ⣀⠤⠒⠢⠤⣀⡀                       ⣀⠤⠔⠒⠤⠤⣀   ⣀⠄          
#>            ⠈⡱⢖⠉      ⠈⠑⠤⡀                 ⣀⠔⠊       ⢉⠶⢎     type   
#>    5.0    ⡠⠊  ⠑⠢⡀       ⠈⠢⡀             ⢠⠊        ⣀⠔⠁  ⠣⡀   * cos  
#> y        ⠈      ⠘⢄        ⠑⢄          ⢀⠔⠁       ⢠⠊          * sin  
#>      0            ⠑⢄        ⠑⠤⡀     ⢀⠔⠁       ⢀⠔⠁                  
#>   -5.0              ⠑⠤⡀       ⠈⢆  ⢀⠔⠁        ⡰⠁                    
#>                       ⠈⠢⡀       ⡱⠶⣁       ⡠⠒⠉                      
#>  -10.0                  ⠈⠑⠒⠒⠤⠤⠒⠉   ⠉⠑⠒⠤⠔⠒⠉                         
#>         0      5.0    10.0    15.0    20.0    25.0    30.0         
#>                                x                                   
#> 

Histograms (geom_histogram)

p <- ggplot(mtcars, aes(x = mpg, fill = factor(cyl))) +
  geom_histogram(bins = 10, position = "dodge") +
  labs(title = "MPG Distribution by Cylinders")
ggplotcli(p, width = 60, height = 12)
#> 
#>               MPG Distribution by Cylinders                              
#>                       ⣶⣶                                                 
#> c  6.0                ⣿⣿                                    factor(cyl)  
#> o                     ⣿⣿                                    * 4          
#> u  4.0                ⣿⣿     ⢰⣶⡆                            * 6          
#> n                     ⣿⣿ ⣤⣤⣤⡄⢸⣿⡇⢠⣤⣤            ⣤⣤           * 8          
#> t  2.0      ⢠⣤⡄  ⣤⣤   ⣿⣿ ⣿⣿⣿⣧⣼⣿⡇⢸⣿⣿  ⢠⣤⡄       ⣿⣿                        
#>             ⢸⣿⡇  ⣿⣿   ⣿⣿ ⣿⣿⣿⣿⣿⣿⡇⢸⣿⣿  ⢸⣿⡇       ⣿⣿  ⢠⣤⡄                   
#>      0   ⠠⠤⠤⠼⠿⠧⠤⠤⠿⠿⠤⠤⠤⠿⠿⠤⠿⠿⠿⠿⠿⠿⠧⠼⠿⠿⠤⠤⠼⠿⠧⠤⠤⠤⠤⠤⠤⠤⠿⠿⠤⠤⠼⠿⠧⠤⠤⠄                
#>          10.0     15.0     20.0     25.0    30.0     35.0                
#>                               mpg                                        
#> 

Density Plots (geom_density)

p <- ggplot(mtcars, aes(x = mpg, color = factor(cyl))) +
  geom_density() +
  labs(title = "MPG Density by Cylinders")
ggplotcli(p, width = 60, height = 12)
#> 
#>                  MPG Density by Cylinders                                
#> d 0.25            ⣠⢦                                                     
#> e 0.20           ⢠⠃⠈⣇      ⢀⡠⠞⠙⣆                            factor(cyl)  
#> n                ⡞  ⠸⡀  ⢠⠚⠉⠁   ⠸⡄                           * 4          
#> s 0.15          ⢠⠃   ⢣ ⢠⠃       ⢧                           * 6          
#> i 0.10         ⢀⡎    ⠈⢆⡎        ⠘⡄                          * 8          
#> t 0.05   ⠘⢦   ⢀⡞      ⡼⠳⠤⠖⠒⢦ ⢀⣠⠤⠖⢳⠒⠒⠒⠒⠒⠦⠤⠤⣄⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀                    
#> y         ⠈⢣⡀⣠⠞      ⡰⠁ ⢀⣀⡤⠔⢻⡉   ⠈⢧                 ⠈⠉⠉⠓⠂                
#>      0   ⠠⠤⠤⠭⠥⠤⠤⠤⠴⠶⠒⠚⠓⠒⠉⠉    ⠙⠒⠦⠤⠤⠬⠷⠶⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠄                
#>        10.0     15.0      20.0      25.0      30.0      35.0             
#>                               mpg                                        
#> 

Bar Charts (geom_col)

df <- data.frame(
  category = c("A", "B", "C", "D", "E", "F"),
  value = c(25, 45, 30, 60, 35, 50)
)
p <- ggplot(df, aes(x = category, y = value, fill = category)) +
  geom_col() +
  labs(title = "Category Values")
ggplotcli(p, width = 60, height = 12)
#> 
#>                      Category Values                                  
#>   60.0                           ⣶⣶⣶⣶⣶⣶⣶⣶                   category  
#> v 50.0                           ⣿⣿⣿⣿⣿⣿⣿⣿         ⣤⣤⣤⣤⣤⣤⣤⣤  * A       
#> a 40.0          ⢸⣿⣿⣿⣿⣿⣿⣿⡇        ⣿⣿⣿⣿⣿⣿⣿⣿         ⣿⣿⣿⣿⣿⣿⣿⣿  * B       
#> l 30.0          ⢸⣿⣿⣿⣿⣿⣿⣿⡇⣀⣀⣀⣀⣀⣀⣀⣀⣿⣿⣿⣿⣿⣿⣿⣿⢰⣶⣶⣶⣶⣶⣶⣶⡆⣿⣿⣿⣿⣿⣿⣿⣿  * C       
#> u       ⣤⣤⣤⣤⣤⣤⣤⣤⢸⣿⣿⣿⣿⣿⣿⣿⡇⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⢸⣿⣿⣿⣿⣿⣿⣿⡇⣿⣿⣿⣿⣿⣿⣿⣿  * D       
#> e 20.0  ⣿⣿⣿⣿⣿⣿⣿⣿⢸⣿⣿⣿⣿⣿⣿⣿⡇⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⢸⣿⣿⣿⣿⣿⣿⣿⡇⣿⣿⣿⣿⣿⣿⣿⣿  * E       
#>   10.0  ⣿⣿⣿⣿⣿⣿⣿⣿⢸⣿⣿⣿⣿⣿⣿⣿⡇⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⢸⣿⣿⣿⣿⣿⣿⣿⡇⣿⣿⣿⣿⣿⣿⣿⣿  * F       
#>      0  ⠿⠿⠿⠿⠿⠿⠿⠿⠸⠿⠿⠿⠿⠿⠿⠿⠇⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠸⠿⠿⠿⠿⠿⠿⠿⠇⠿⠿⠿⠿⠿⠿⠿⠿            
#>             A       B       C        D       E       F                
#>                             category                                  
#> 

Boxplots (geom_boxplot)

Boxplots are rendered with box-drawing characters by default, showing whiskers, box (Q1-Q3), median line, and outliers:

set.seed(42)
df <- data.frame(
  group = factor(rep(paste0("Group ", 1:6), each = 50)),
  value = c(rnorm(50, 10, 3), rnorm(50, 5, 2), rnorm(50, 8, 4),
            rnorm(50, 6, 2), rnorm(50, 12, 3), rnorm(50, 7, 2))
)
p <- ggplot(df, aes(x = group, y = value, fill = group)) +
  geom_boxplot() +
  labs(title = "Boxplot Colored by Group", y = "Value", x = "Group")
ggplotcli(p, width = 80, height = 20, boxplot_style = "ascii")
#> 
#>                            Boxplot Colored by Group                                        
#>                                     *                    ───────                           
#>           ───────                                           │                              
#>              │                      *                       │                              
#>   15.0       │                                          ┌───────┐               group      
#>              │                   ───*───                │       │               * Group 1  
#> V        ┌───────┐                  │                   │───────│   ───────     * Group 2  
#> a        │       │                  │                   └───────┘      │        * Group 3  
#> l 10.0   │───────│              ┌───────┐    ───────        │          │        * Group 4  
#> u        └───────┘    ───────   │       │   ┌───────┐       │      ┌───────┐    * Group 5  
#> e            │       ┌───────┐  └───────┘   │───────│    ───────   │       │    * Group 6  
#>    5.0       │       │───────│      │       └───────┘              └───────┘               
#>              │       └───────┘      │           │                      │                   
#>           ───*───     ───────       │        ───────                ───────                
#>                                  ───────                                                   
#>      0                   *          *                                                      
#>                                                                                            
#>            Group 1    Group 2     Group 3    Group 4     Group 5    Group 6                
#>                                        Group                                               
#> 

You can also use Braille rendering for boxplots:

ggplotcli(p, width = 80, height = 20, boxplot_style = "braille")
#> 
#>                            Boxplot Colored by Group                                        
#>                                      ⡀                                                     
#>                                                           ⠒⠒⡖⠒⠂                            
#>             ⠉⠉⡏⠉⠁                                           ⡇                              
#>   15.0        ⡇                      ⠂                      ⡇                   group      
#>               ⡇                      ⠂                 ⢰⠒⠒⠒⠒⠓⠒⠒⠒⢲               * Group 1  
#> V        ⢀⣀⣀⣀⣀⣇⣀⣀⣀⡀                ⠉⠉⡏⠉⠁               ⢸        ⢸    ⢀⣀⣀⣀⣀      * Group 2  
#> a        ⢸        ⡇                  ⡇                 ⢸⠉⠉⠉⠉⠉⠉⠉⠉⢹      ⢸        * Group 3  
#> l 10.0   ⢸⠒⠒⠒⠒⠒⠒⠒⠒⡇                  ⡇        ⠐⠒⢲⠒⠒    ⠘⠒⠒⠒⠒⡖⠒⠒⠒⠚      ⢸        * Group 4  
#> u        ⠸⠤⠤⠤⠤⡤⠤⠤⠤⠇    ⠠⠤⢤⠤⠤    ⢰⠒⠒⠒⠒⠓⠒⠒⠒⢲      ⢸           ⡇      ⢰⠒⠒⠒⠚⠒⠒⠒⠒⡆   * Group 5  
#> e             ⡇      ⣀⣀⣀⣀⣸⣀⣀⣀⣀⡀ ⢸⠒⠒⠒⠒⠒⠒⠒⠒⢺  ⡖⠒⠒⠒⠚⠒⠒⠒⠒⡆      ⡇      ⢸⠒⠒⠒⠒⠒⠒⠒⠒⡇   * Group 6  
#>    5.0        ⡇      ⡗⠒⠒⠒⠒⠒⠒⠒⠒⡇ ⠘⠒⠒⠒⠒⡖⠒⠒⠒⠚  ⣏⣉⣉⣉⣉⣉⣉⣉⣉⡇    ⠉⠉⠉⠉⠁    ⠘⠒⠒⠒⢲⠒⠒⠒⠒⠃              
#>               ⡇      ⠧⠤⠤⠤⢤⠤⠤⠤⠤⠇      ⡇          ⢸                      ⢸                   
#>             ⠤⠤⡧⠤⠄      ⢀⣀⣸⣀⣀         ⡇        ⠠⠤⠼⠤⠤                    ⢸                   
#>                                    ⠒⠒⠓⠒⠂                             ⠐⠒⠚⠒⠒                 
#>      0                               ⠄                                                     
#>                          ⠈                                                                 
#>            Group 1    Group 2     Group 3    Group 4     Group 5    Group 6                
#>                                        Group                                               
#> 

Combining Multiple Geoms

# Histogram with density overlay
p <- ggplot(mtcars, aes(x = mpg)) +
  geom_histogram(aes(y = after_stat(density)), bins = 10, fill = "gray") +
  geom_density(color = "red") +
  labs(title = "Histogram with Density Overlay")
ggplotcli(p, width = 60, height = 12)
#> 
#>               Histogram with Density Overlay                 
#> d                 ⢰⣶⣶⣶⣶⣶                                     
#> e 0.08            ⢸⣿⣿⣿⣿⣿⣶⣶⣶⣶⣶⣶⣶⣶⣶                            
#> n 0.06            ⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿                            
#> s               ⢀⡴⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠑⢦⡀                         
#> i 0.04        ⢀⡴⠋ ⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣤⣤⣭⣷⣤⡀        ⣤⣤⣤⣤⣤         
#> t 0.02   ⢠⣤⣤⣤⣾⣥⣤⣤⣤⣼⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣭⣷⣦⣤⣄⣀⣀⣀⣀⣿⣿⣿⣿⣿         
#> y        ⢸⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡇    ⣿⣿⣿⣿⣿⣽⣶⣦⣤⡄    
#>      0   ⠸⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠿⠧⠤⠤⠤⠤⠿⠿⠿⠿⠿⠿⠿⠿⠿⠇    
#>          10.0     15.0     20.0     25.0    30.0     35.0    
#>                               mpg                            
#> 
# Points with smooth line
p <- ggplot(mtcars, aes(x = wt, y = mpg)) +
  geom_point(color = "gray") +
  geom_smooth(method = "loess", color = "red") +
  labs(title = "Scatter with LOESS Smooth")
suppressMessages(ggplotcli(p, width = 60, height = 12))
#> 
#>                 Scatter with LOESS Smooth                    
#>                                                              
#>   35.0   ⢐⢤⣀⣀⠁   ⠐                                           
#> m 30.0       ⠉⠲⠢⢄⡀                                           
#> p 25.0           ⠉⠉⡒⠤⣀⣀      ⡐                               
#> g 20.0              ⠈ ⠐⠉⠩⠙⠒⠒⠢⠬⢄⣀⣠    ⠠                       
#>   15.0                       ⠄  ⢈⠩⡒⠒⢣⠤⠤⢄⣂⣀⣀            ⡀     
#>   10.0                               ⠁     ⠉⠉⠉⠉⠑⠒⠒⠒⠒⠢⠤⡤⠤⡄    
#>                                                              
#>               2.0         3.0         4.0         5.0        
#>                                wt                            
#> 

Faceting

facet_wrap with Color Aesthetics

Faceting works seamlessly with color/fill aesthetics and legends:

mtcars$cyl_fac <- factor(mtcars$cyl)
p <- ggplot(mtcars, aes(x = wt, y = mpg, color = cyl_fac)) +
  geom_point() +
  facet_wrap(~cyl_fac) +
  labs(title = "MPG vs Weight: Faceted by Cylinders")
ggplotcli(p, width = 75, height = 16)
#> 
#>                    MPG vs Weight: Faceted by Cylinders                              
#>                4, 1                  6, 1                  8, 1                     
#>          ⠠                                                                          
#>         ⣀  ⠁                                                                        
#>    30.0                                                                    cyl_fac  
#>           ⠁⠄                                                               * 4      
#> m           ⡀  ⢀⠁                                                          * 6      
#> p  20.0     ⠈ ⠂                    ⠂⡐ ⠂                                    * 8      
#> g                                      ⠅                     ⠂⢀⠁                    
#>                                                             ⠂⢤⠠ ⠁     ⡀             
#>                                                                ⠂                    
#>    10.0                                                              ⠐⠐             
#>          2.0      4.0          2.0      4.0          2.0      4.0                   
#>                                                                                     
#>                                        wt                                           
#> 

facet_grid

p <- ggplot(mtcars, aes(x = wt, y = mpg, color = factor(gear))) +
  geom_point() +
  facet_grid(am ~ cyl) +
  labs(title = "MPG: AM (rows) x Cylinders (cols)")
ggplotcli(p, width = 80, height = 20)
#> 
#>                       MPG: AM (rows) x Cylinders (cols)                                       
#>                0, 4, 1                 0, 6, 1                 0, 8, 1                        
#>                                                                                               
#>    30.0                                                                                       
#>                 ⢀⠂                                                                            
#>    20.0      ⠁                           ⠁⡄                       ⡀ ⠄                         
#>                                                                   ⠔⠌⡄⠐      ⠄   factor(gear)  
#> m  10.0                                                                    ⠠⠠   * 3           
#> p              1, 4, 1                 1, 6, 1                 1, 8, 1          * 4           
#> g        ⠐ ⠠                                                                    * 5           
#>    30.0 ⠉ ⡀                                                                                   
#>            ⠈⡀                                                                                 
#>    20.0       ⠈                       ⠢⠂                                                      
#>                                                                 ⠐  ⠄                          
#>    10.0                                                                                       
#>          2.0        4.0          2.0        4.0          2.0        4.0                       
#>                                                                                               
#>                                           wt                                                  
#>                                                                                               
#> 

Styling Options

Borders and Grid Lines

p <- ggplot(mtcars, aes(x = hp, y = qsec)) +
  geom_point(color = "cyan") +
  labs(title = "Quarter Mile Time vs HP")

# With border
ggplotcli(p, width = 55, height = 12, border = TRUE)
#> 
#>                Quarter Mile Time vs HP                  
#>        ⡏⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⢹  
#>   22.0 ⡇        ⠠                                    ⢸  
#> q      ⡇                                             ⢸  
#> s 20.0 ⡇    ⢲    ⠂⠡ ⢀                                ⢸  
#> e 18.0 ⡇  ⠈     ⠁ ⢈ ⠈   ⡀  ⢀⠰   ⠂⠐ ⠠                 ⢸  
#> c      ⡇        ⠁ ⠐⠁    ⠁  ⢀         ⢠               ⢸  
#>   16.0 ⡇                                ⠂         ⠂  ⢸  
#>        ⣇⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣸  
#>        50.0    100     150    200    250     300        
#>                             hp                          
#> 

# With grid
ggplotcli(p, width = 55, height = 12, grid = "major")
#> 
#>                Quarter Mile Time vs HP                  
#>          ⡇     ⠐⢸       ⡇      ⡇      ⢸       ⡇         
#>   22.0 ⠉⠉⡏⠉⠉⠉⠉⠉⠉⢹⠉⠉⠉⠉⠉⠉⠉⡏⠉⠉⠉⠉⠉⠉⡏⠉⠉⠉⠉⠉⠉⢹⠉⠉⠉⠉⠉⠉⠉⡏⠉⠉⠉⠉⠉⠉⠉  
#> q      ⣀⣀⣇⣀⣀⣀⣀⣀⣀⣸⣄⣀⣀⣀⣀⣀⣀⣇⣀⣀⣀⣀⣀⣀⣇⣀⣀⣀⣀⣀⣀⣸⣀⣀⣀⣀⣀⣀⣀⣇⣀⣀⣀⣀⣀⣀⣀  
#> s 20.0   ⡇ ⡂    ⢸ ⠂⢀    ⡇      ⡇      ⢸       ⡇         
#> e 18.0 ⠤⠤⡧⠤⠤⠤⠤⠤⠥⢼⠬⠤⠴⠤⠤⠤⠤⡧⠤⠤⠤⡤⠤⠤⡧⠤⠤⠤⠤⠤⠤⢼⠤⠤⠤⠤⠤⠤⠤⡧⠤⠤⠤⠤⠤⠤⠤  
#> c        ⡇     ⠄⢸ ⡆     ⡇  ⠐⠁  ⡇   ⠈  ⢸       ⡇         
#>   16.0 ⠒⠒⡗⠒⠒⠒⠒⠒⠒⢺⠒⠒⠒⠒⠒⠒⠒⡗⠒⠒⠲⠒⠒⠒⡗⠒⠒⠒⠒⠒⠒⣺⠒⠒⠒⠒⠒⠒⠒⡗⠒⠒⠒⠒⠒⠒⠒  
#>          ⡇      ⢸       ⡇      ⡇      ⢸  ⠄    ⡇    ⠐    
#>        50.0    100     150    200    250     300        
#>                             hp                          
#> 

# Both
ggplotcli(p, width = 55, height = 12, border = TRUE, grid = "major")
#> 
#>                Quarter Mile Time vs HP                  
#>        ⡏⠉⠉⡏⠉⠉⠉⠉⠉⠉⡏⠉⠉⠉⠉⠉⠉⡏⠉⠉⠉⠉⠉⠉⡏⠉⠉⠉⠉⠉⠉⡏⠉⠉⠉⠉⠉⠉⡏⠉⠉⠉⠉⠉⠉⠉⢹  
#>   22.0 ⡇  ⡇     ⠠⡇      ⡇      ⡇      ⡇      ⡇       ⢸  
#> q      ⡏⠉⠉⡏⠉⠉⠉⠉⠉⠉⡏⠉⠉⠉⠉⠉⠉⡏⠉⠉⠉⠉⠉⠉⡏⠉⠉⠉⠉⠉⠉⡏⠉⠉⠉⠉⠉⠉⡏⠉⠉⠉⠉⠉⠉⠉⢹  
#> s 20.0 ⡗⠒⠒⡗⠒⢲⠒⠒⠒⠒⡗⠳⠒⢒⠒⠒⠒⡗⠒⠒⠒⠒⠒⠒⡗⠒⠒⠒⠒⠒⠒⡗⠒⠒⠒⠒⠒⠒⡗⠒⠒⠒⠒⠒⠒⠒⢺  
#> e 18.0 ⡗⠒⠒⡟⠒⠒⠒⠒⠒⠓⡗⢚⠒⠚⠒⠒⠒⡗⠒⠒⢒⠲⠒⠒⡗⠒⠒⠒⠲⠒⠒⡗⠒⠒⠒⠒⠒⠒⡗⠒⠒⠒⠒⠒⠒⠒⢺  
#> c      ⡧⠤⠤⡧⠤⠤⠤⠤⠤⠥⡧⠴⠥⠤⠤⠤⠤⡧⠤⠤⢤⠤⠤⠤⡧⠤⠤⠤⠤⠤⢤⡧⠤⠤⠤⠤⠤⠤⡧⠤⠤⠤⠤⠤⠤⠤⢼  
#>   16.0 ⡇  ⡇      ⡇      ⡇      ⡇      ⡇ ⠂    ⡇    ⠂  ⢸  
#>        ⣇⣀⣀⣇⣀⣀⣀⣀⣀⣀⣇⣀⣀⣀⣀⣀⣀⣇⣀⣀⣀⣀⣀⣀⣇⣀⣀⣀⣀⣀⣀⣇⣀⣀⣀⣀⣀⣀⣇⣀⣀⣀⣀⣀⣀⣀⣸  
#>        50.0    100     150    200    250     300        
#>                             hp                          
#> 

Theme Auto-Detection

ggplotcli automatically respects ggplot2 themes:

p <- ggplot(mtcars, aes(x = wt, y = mpg)) +
  geom_point(color = "blue") +
  labs(title = "theme_bw() - Grid + Border")

# theme_bw has both grid and border
ggplotcli(p + theme_bw(), width = 60, height = 14, border = "auto", grid = "auto")
#> 
#>                 theme_bw() - Grid + Border                   
#>   35.0 ⡏⠉⠉⢹⠉⠉⠉⠉⠉⡏⠉⠉⠉⠉⠉⡏⠉⠉⠉⠉⢹⠉⠉⠉⠉⠉⡏⠉⠉⠉⠉⢹⠉⠉⠉⠉⠉⢹⠉⠉⠉⠉⠉⡏⠉⠉⠉⠉⢹⠉⠉⢹  
#>        ⡧⠤⠤⢼⠤⠤⠤⠤⠤⡧⠤⠤⠤⠤⠤⡧⠤⠤⠤⠤⢼⠤⠤⠤⠤⠤⡧⠤⠤⠤⠤⢼⠤⠤⠤⠤⠤⢼⠤⠤⠤⠤⠤⡧⠤⠤⠤⠤⢼⠤⠤⢼  
#>   30.0 ⣏⣉⣉⣹⣉⣍⣉⣉⣉⣏⣉⣉⣉⣉⣉⣏⣉⣉⣉⣉⣹⣉⣉⣉⣉⣉⣏⣉⣉⣉⣉⣹⣉⣉⣉⣉⣉⣹⣉⣉⣉⣉⣉⣏⣉⣉⣉⣉⣹⣉⣉⣹  
#> m      ⣗⣒⣒⣺⣒⣒⣒⣒⣲⣗⣒⣒⣒⣒⣒⣗⣒⣒⣒⣒⣺⣒⣒⣒⣒⣒⣗⣒⣒⣒⣒⣺⣒⣒⣒⣒⣒⣺⣒⣒⣒⣒⣒⣗⣒⣒⣒⣒⣺⣒⣒⣺  
#> p 25.0 ⡗⠒⠒⢺⠒⠒⠒⠒⠒⡗⠒⠒⠒⡒⠒⡗⠒⠒⠒⠒⢺⠒⡒⠒⠒⠒⡗⠒⠒⠒⠒⢺⠒⠒⠒⠒⠒⢺⠒⠒⠒⠒⠒⡗⠒⠒⠒⠒⢺⠒⠒⢺  
#> g 20.0 ⡯⠭⠭⢽⠭⠭⠭⠭⠭⡯⠭⠭⠭⠭⠭⡯⠯⠭⠭⠯⢽⠭⠭⠭⠭⢭⡯⠭⠭⠭⡭⢽⠭⠭⠭⠭⠭⢽⠭⠭⠭⠭⠭⡯⠭⠭⠭⠭⢽⠭⠭⢽  
#>        ⡯⠭⠭⢽⠭⠭⠭⠭⠭⡯⠭⠭⠭⠭⠭⡯⠭⠭⠭⠭⢽⠭⢭⠭⠭⢭⣯⠭⠽⢭⠭⢽⠭⠭⠭⠭⠭⢽⠭⠭⠭⠭⠭⡯⠭⠭⠭⠭⢽⠭⠭⢽  
#>   15.0 ⣗⣒⣒⣺⣒⣒⣒⣒⣒⣗⣒⣒⣒⣒⣒⣗⣒⣒⣒⣒⣺⣒⣒⣒⣒⣒⣗⣓⣒⣒⣒⣺⣒⣒⣒⣒⣒⣺⣒⣒⣒⣒⣒⣗⣒⣒⣒⣓⣺⣒⣒⣺  
#>        ⡗⠒⠒⢺⠒⠒⠒⠒⠒⡗⠒⠒⠒⠒⠒⡗⠒⠒⠒⠒⢺⠒⠒⠒⠒⠒⡗⠒⠒⠒⠒⢺⠒⠒⠒⠒⠒⢺⠒⠒⠒⠒⠒⡗⠒⠒⠒⠒⢺⠒⠒⢺  
#>   10.0 ⣇⣀⣀⣸⣀⣀⣀⣀⣀⣇⣀⣀⣀⣀⣀⣇⣀⣀⣀⣀⣸⣀⣀⣀⣀⣀⣇⣀⣀⣀⣀⣸⣀⣀⣀⣀⣀⣸⣀⣀⣀⣀⣀⣇⣀⣀⣀⣀⣸⣀⣀⣸  
#>               2.0         3.0         4.0         5.0        
#>                                wt                            
#> 

# theme_classic has border but no grid
ggplotcli(p + theme_classic() + labs(title = "theme_classic() - Border Only"), 
           width = 60, height = 14, border = "auto", grid = "auto")
#> 
#>               theme_classic() - Border Only                  
#>   35.0 ⡏⠉⠉⢹⠉⠉⠉⠉⠉⡏⠉⠉⠉⠉⠉⡏⠉⠉⠉⠉⢹⠉⠉⠉⠉⠉⡏⠉⠉⠉⠉⢹⠉⠉⠉⠉⠉⢹⠉⠉⠉⠉⠉⡏⠉⠉⠉⠉⢹⠉⠉⢹  
#>        ⡧⠤⠤⢼⠤⠤⠤⠤⠤⡧⠤⠤⠤⠤⠤⡧⠤⠤⠤⠤⢼⠤⠤⠤⠤⠤⡧⠤⠤⠤⠤⢼⠤⠤⠤⠤⠤⢼⠤⠤⠤⠤⠤⡧⠤⠤⠤⠤⢼⠤⠤⢼  
#>   30.0 ⣏⣉⣉⣹⣉⣍⣉⣉⣉⣏⣉⣉⣉⣉⣉⣏⣉⣉⣉⣉⣹⣉⣉⣉⣉⣉⣏⣉⣉⣉⣉⣹⣉⣉⣉⣉⣉⣹⣉⣉⣉⣉⣉⣏⣉⣉⣉⣉⣹⣉⣉⣹  
#> m      ⣗⣒⣒⣺⣒⣒⣒⣒⣲⣗⣒⣒⣒⣒⣒⣗⣒⣒⣒⣒⣺⣒⣒⣒⣒⣒⣗⣒⣒⣒⣒⣺⣒⣒⣒⣒⣒⣺⣒⣒⣒⣒⣒⣗⣒⣒⣒⣒⣺⣒⣒⣺  
#> p 25.0 ⡗⠒⠒⢺⠒⠒⠒⠒⠒⡗⠒⠒⠒⡒⠒⡗⠒⠒⠒⠒⢺⠒⡒⠒⠒⠒⡗⠒⠒⠒⠒⢺⠒⠒⠒⠒⠒⢺⠒⠒⠒⠒⠒⡗⠒⠒⠒⠒⢺⠒⠒⢺  
#> g 20.0 ⡯⠭⠭⢽⠭⠭⠭⠭⠭⡯⠭⠭⠭⠭⠭⡯⠯⠭⠭⠯⢽⠭⠭⠭⠭⢭⡯⠭⠭⠭⡭⢽⠭⠭⠭⠭⠭⢽⠭⠭⠭⠭⠭⡯⠭⠭⠭⠭⢽⠭⠭⢽  
#>        ⡯⠭⠭⢽⠭⠭⠭⠭⠭⡯⠭⠭⠭⠭⠭⡯⠭⠭⠭⠭⢽⠭⢭⠭⠭⢭⣯⠭⠽⢭⠭⢽⠭⠭⠭⠭⠭⢽⠭⠭⠭⠭⠭⡯⠭⠭⠭⠭⢽⠭⠭⢽  
#>   15.0 ⣗⣒⣒⣺⣒⣒⣒⣒⣒⣗⣒⣒⣒⣒⣒⣗⣒⣒⣒⣒⣺⣒⣒⣒⣒⣒⣗⣓⣒⣒⣒⣺⣒⣒⣒⣒⣒⣺⣒⣒⣒⣒⣒⣗⣒⣒⣒⣓⣺⣒⣒⣺  
#>        ⡗⠒⠒⢺⠒⠒⠒⠒⠒⡗⠒⠒⠒⠒⠒⡗⠒⠒⠒⠒⢺⠒⠒⠒⠒⠒⡗⠒⠒⠒⠒⢺⠒⠒⠒⠒⠒⢺⠒⠒⠒⠒⠒⡗⠒⠒⠒⠒⢺⠒⠒⢺  
#>   10.0 ⣇⣀⣀⣸⣀⣀⣀⣀⣀⣇⣀⣀⣀⣀⣀⣇⣀⣀⣀⣀⣸⣀⣀⣀⣀⣀⣇⣀⣀⣀⣀⣸⣀⣀⣀⣀⣀⣸⣀⣀⣀⣀⣀⣇⣀⣀⣀⣀⣸⣀⣀⣸  
#>               2.0         3.0         4.0         5.0        
#>                                wt                            
#> 

Canvas Types

Three rendering modes are available:

wave <- ggplot(data.frame(x = 1:25, y = sin(1:25/4)*8), aes(x, y)) +
  geom_line(color = "green")

# Braille (highest resolution - 2x4 dots per character)
ggplotcli(wave + labs(title = "Braille Canvas (highest resolution)"), 
           width = 50, height = 8, canvas_type = "braille")
#> 
#>       Braille Canvas (highest resolution)          
#>            ⢀⣀⠤⠔⠒⠒⠒⠒⠒⠒⠤⢄⡀                           
#> y  5.0   ⠔⠊⠁           ⠈⠑⠤⣀                        
#>   -5.0                     ⠉⠑⠢⢄⡀           ⣀⠤⠒⠉    
#>                                ⠈⠑⠢⠤⠤⠤⠤⠤⠤⠒⠊⠉        
#>        0      5.0    10.0    15.0   20.0    25.0   
#>                           x                        
#> 

# Block (medium resolution - uses block characters)
ggplotcli(wave + labs(title = "Block Canvas (medium resolution)"), 
           width = 50, height = 8, canvas_type = "block")
#> 
#>         Block Canvas (medium resolution)           
#>             ▄▄▄▀▀▀▀▀▄▄▄                            
#> y  5.0   ▄▀▀           ▀▀▀▄▄                       
#>   -5.0                      ▀▄▄▄           ▄▄▀▀    
#>                                 ▀▀▀▄▄▄▄▄▀▀▀        
#>        0      5.0    10.0    15.0   20.0    25.0   
#>                           x                        
#> 

# ASCII (basic, most compatible)
ggplotcli(wave + labs(title = "ASCII Canvas (most compatible)"), 
           width = 50, height = 8, canvas_type = "ascii")
#> 
#>          ASCII Canvas (most compatible)            
#>               *********                            
#> y  5.0   *****         *****                       
#>   -5.0                      ****         ******    
#>                                 *********          
#>        0      5.0    10.0    15.0   20.0    25.0   
#>                           x                        
#> 

Color Mapping

ggplotcli intelligently maps ggplot2 colors to terminal colors (red, yellow, green, cyan, blue, magenta). The mapping prioritizes color distinctness over hue accuracy to maximize visual differentiation between groups.

Many Groups (8+)

Even with many groups, colors are distributed to minimize repetition:

set.seed(123)
df <- data.frame(
  group = factor(rep(paste0("G", 1:8), each = 30)),
  value = unlist(lapply(1:8, function(i) rnorm(30, mean = i * 2, sd = 1.5)))
)
p <- ggplot(df, aes(x = group, y = value, fill = group)) +
  geom_boxplot() +
  labs(title = "8 Groups with Optimized Color Distribution")
ggplotcli(p, width = 85, height = 18, boxplot_style = "ascii")
#> 
#>                     8 Groups with Optimized Color Distribution                              
#>                                                                            ─────            
#>                                                            *      ─────   ┌─────┐    group  
#>                                                            *     ┌─────┐  └─────┘    * G1   
#>   15.0                                                   ─────   │─────│   ─────     * G2   
#> v                                              ─────    ┌─────┐  └─────┘             * G3   
#> a                                     ─────   ┌─────┐   └─────┘                      * G4   
#> l 10.0                         *     ┌─────┐  │─────│                                * G5   
#> u                  ─────     ─────   └─────┘  └─────┘                                * G6   
#> e                    │      └─────┘   ─────                                          * G7   
#>    5.0    ─────   ┌─────┐    ─────                                                   * G8   
#>          ┌─────┐  └─────┘      *                                                            
#>          └─────┘   ─────                                                                    
#>      0    ─────                                                                             
#>                                                                                             
#>             G1       G2       G3       G4        G5       G6       G7       G8              
#>                                           group                                             
#> 

Showcase: Maximum Complexity

Complex Faceted Boxplot

set.seed(42)
df <- data.frame(
  treatment = factor(rep(c("Control", "Drug A", "Drug B"), each = 60)),
  timepoint = factor(rep(rep(c("Baseline", "Week 4", "Week 8"), each = 20), 3)),
  response = c(
    rnorm(20, 50, 10), rnorm(20, 52, 10), rnorm(20, 51, 10),  # Control
    rnorm(20, 50, 10), rnorm(20, 65, 12), rnorm(20, 70, 11),  # Drug A
    rnorm(20, 50, 10), rnorm(20, 58, 11), rnorm(20, 62, 10)   # Drug B
  )
)

p <- ggplot(df, aes(x = timepoint, y = response)) +
  geom_boxplot(aes(fill = treatment)) +
  labs(title = "Treatment Response Over Time",
       subtitle = "Faceted by treatment group",
       x = "Timepoint", y = "Response") +
  theme_bw()

ggplotcli(p, width = 100, height = 22, boxplot_style = "ascii")
#> 
#>                                    Treatment Response Over Time                                                
#>                                     Faceted by treatment group                                                 
#>        ⡏⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⢹            
#>    100 ⡇                                                                        *                 ⢸            
#>        ⡇                                                                                          ⢸            
#>        ⡇                                                                        *                 ⢸            
#> R 80.0 ⡇                                          ─────                       ──*──               ⢸            
#> e      ⡇                                         ┌─────┐                        │    ─────        ⢸ treatment  
#> s      ⡇        ─────                      ───── │     │   *                 ┌─────┐┌─────┐       ⢸ * Control  
#> p      ⡇       ┌─────┐ ─────  ─────          │   │─────│ ─────         ───── └─────┘│─────│       ⢸ * Drug A   
#> o 60.0 ⡇       │     │┌─────┐   │         ┌─────┐└─────┘┌─────┐       ┌─────┐   │   └─────┘       ⢸ * Drug B   
#> n      ⡇       │─────││─────│┌─────┐      │─────│   │   └─────┘       │─────│ ──*──    │          ⢸            
#> s      ⡇       └─────┘└─────┘│─────│      └─────┘ ─────  ─────        └─────┘        ──*──        ⢸            
#> e      ⡇          │    ───── └─────┘         │             *           ─────                      ⢸            
#>   40.0 ⡇          │             │            │                                                    ⢸            
#>        ⡇          │           ─────        ─────                                                  ⢸            
#>        ⡇        ─────                                                    *                        ⢸            
#>   20.0 ⡇                                                                                          ⢸            
#>        ⣇⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣸            
#>                     Baseline                      Week 4                      Week 8                           
#>                                                Timepoint                                                       
#> 

Multi-Layer Scientific Plot

# Simulated experiment data
set.seed(123)
x <- seq(0, 10, length.out = 50)
df <- data.frame(
  x = rep(x, 3),
  y = c(
    2 * x + rnorm(50, 0, 1.5),
    1.5 * x + 3 + rnorm(50, 0, 1.2),
    x^1.2 + rnorm(50, 0, 1)
  ),
  group = rep(c("Linear", "Offset", "Power"), each = 50)
)

p <- ggplot(df, aes(x = x, y = y, color = group)) +
  geom_point(alpha = 0.6) +
  geom_smooth(method = "loess", se = FALSE) +
  labs(title = "Multi-Group Regression Analysis",
       subtitle = "Points with LOESS smoothing",
       x = "Predictor", y = "Response") +
  theme_minimal()

suppressMessages(ggplotcli(p, width = 70, height = 18))
#> 
#>                   Multi-Group Regression Analysis                               
#>                     Points with LOESS smoothing                                 
#>                                                            ⠄    ⠠               
#>   20.0                                                      ⠂⢀⡐⣤⢰⣾              
#> R                                                      ⡀⣠⡄⣶⢰⣇⣿⣿⣿⣿⣿              
#> e 15.0                                         ⢀⢀⠠⡀⣤⣠⣾⣸⣯⣿⣿⣿⣿⣿⣿⡟⣿⢹⠿    group     
#> s                                          ⠂⡀⡀⣬⢰⣾⣸⣧⣿⣾⣿⣿⣿⣿⡟⣿⠹⠇⠛⢁⠁ ⠈    * Linear  
#> p                              ⢀   ⡀  ⠐⠐⣀⣠⢠⣦⣿⣷⣿⣿⣿⢿⡟⣿⢻⠿⠸⠃⠋⠡ ⠂⠁         * Offset  
#> o 10.0                        ⠠  ⡀⣠⢠⣴⢴⡇⣿⣷⣿⣿⡟⣿⡏⡿⢸⠛⠘⠁⡁  ⠈               * Power   
#> n                         ⡀⣥⡆⣶⢰⣿⢸⡇⣿⣸⣿⣿⡿⣿⡯⠿⠘⠃⠉   ⠐                               
#> s            ⡀ ⠐  ⢄⣀⢤⡆⣶⣖⣿⢸⡇⣿⣇⣿⣼⣿⢾⡟⡿⡹⠟⠘⠑⠁ ⠈                                      
#> e  5.0    ⢀⡀⣠⢠⣴⢰⡇⣿⢸⣿⢸⡇⣿⣧⣿⣾⡿⣿⡟⡿⠹⠫⠈ ⠂                                             
#>           ⣿⡇⣿⢸⣿⣸⣿⣿⢾⣿⢻⡟⠿⠃⠛⠈⠁                                                     
#>      0    ⣿⡷⣿⠿⢿⠙⠣⠋⡊⠁   ⠈                                                        
#>           ⠋                                                                     
#>           0         2.0        4.0        6.0        8.0       10.0             
#>                                 Predictor                                       
#> 

Dense Scatter with Facets

p <- ggplot(iris, aes(x = Sepal.Length, y = Petal.Length, color = Species)) +
  geom_point() +
  facet_wrap(~Species) +
  labs(title = "Iris Dataset: Sepal vs Petal Length",
       subtitle = "Faceted by species with color legend") +
  theme_bw()

ggplotcli(p, width = 80, height = 16)
#> 
#>                      Iris Dataset: Sepal vs Petal Length                                      
#>                      Faceted by species with color legend                                     
#>               setosa, 1             versicolor, 1           virginica, 1                      
#> P      ⡏⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⢹ ⡏⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⢹ ⡏⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⢹                
#> e   6.0⡇                     ⢸ ⡇                     ⢸ ⡇                 ⢀⡄  ⢸                
#> t      ⡇                     ⢸ ⡇                     ⢸ ⡇          ⡀⣄⠄⡤⡀⠴⠑ ⠂⠁ ⢸  Species       
#> a      ⡇                     ⢸ ⡇       ⡀⣀⠠⣂⣄⣀⡢⢄      ⢸ ⡇    ⢀   ⠔⠒⠮⠎⠃⠊⠃      ⢸  * setosa      
#> l   4.0⡇                     ⢸ ⡇     ⡀⠄⠸⣖⠖⠊⠉⠈⠁       ⢸ ⡇                     ⢸  * versicolor  
#> .      ⡇                     ⢸ ⡇    ⠈⠑               ⢸ ⡇                     ⢸  * virginica   
#> L   2.0⡇  ⡀⣀⣂⣰⣀⣄⢠            ⢸ ⡇                     ⢸ ⡇                     ⢸                
#> e      ⡇ ⠈⠉⠊ ⠁ ⠉ ⠁           ⢸ ⡇                     ⢸ ⡇                     ⢸                
#> n      ⣇⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣸ ⣇⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣸ ⣇⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣀⣸                
#> g          5.0  6.0   7.0   8.0    5.0  6.0   7.0   8.0    5.0  6.0   7.0   8.0               
#>                                                                                               
#>                                      Sepal.Length                                             
#> 

Supported Features Summary

Feature Status
geom_point ✓
geom_line, geom_path ✓
geom_bar, geom_col, geom_histogram ✓
geom_density ✓
geom_smooth ✓
geom_area ✓
geom_segment, geom_hline, geom_vline ✓
geom_rect ✓
geom_text ✓
geom_boxplot ✓
Color/fill aesthetics ✓
Legends (auto-generated) ✓
facet_wrap, facet_grid ✓
Titles, subtitles, captions ✓
Theme auto-detection ✓
Optimized color mapping ✓
Multiple canvas types ✓
geom_tile (heatmaps) Planned
geom_violin Planned