From 2b08e51796b8c3cc109e47afef66b2fb2ec69e89 Mon Sep 17 00:00:00 2001 From: Thomas Lin Pedersen Date: Thu, 12 Mar 2026 12:04:54 +0100 Subject: [PATCH] update palettes --- doc/syntax/scale/aesthetic/1_color.qmd | 73 ++++++++++--------- .../examples/gradient_sequential.svg | 27 +++++++ .../aesthetic/examples/swatch_ggsql10.svg | 16 ++-- .../scale/aesthetic/generate_examples.R | 2 + src/plot/scale/palettes.rs | 50 ++++++++++++- 5 files changed, 121 insertions(+), 47 deletions(-) create mode 100644 doc/syntax/scale/aesthetic/examples/gradient_sequential.svg diff --git a/doc/syntax/scale/aesthetic/1_color.qmd b/doc/syntax/scale/aesthetic/1_color.qmd index 51ba618f..c1cd601a 100644 --- a/doc/syntax/scale/aesthetic/1_color.qmd +++ b/doc/syntax/scale/aesthetic/1_color.qmd @@ -85,31 +85,32 @@ SCALE color TO ['antiquewhite', 'firebrick'] ### Continuous palettes #### Sequential -Sequential palettes for numeric data. `navia` is the default continuous color palette in ggsql. +Sequential palettes for numeric data. `sequential` is the default continuous color palette in ggsql. | Name | Gradient | Source | Description | |------|----------|--------|-------------| -| `navia` | ![](examples/gradient_navia.svg){height=20 .lightbox} | Crameri | **Default.** Blue-green-cream (alias: `sequential`) | -| `batlow` | ![](examples/gradient_batlow.svg){height=20 .lightbox} | Crameri | Blue-green-yellow-red | +| `sequential` | ![](examples/gradient_sequential.svg){height=20 .lightbox} | ggsql | **Default.** Blue-teal-green (derived from navia) | +| `acton` | ![](examples/gradient_acton.svg){height=20 .lightbox} | Crameri | Dark purple-light purple | +| `bamako` | ![](examples/gradient_bamako.svg){height=20 .lightbox} | Crameri | Teal-olive-cream | +| `batlow` | ![](examples/gradient_batlow.svg){height=20 .lightbox} | Crameri | Blue-teal-green-brown-pink | | `batlowk` | ![](examples/gradient_batlowk.svg){height=20 .lightbox} | Crameri | Dark variant of batlow | | `batloww` | ![](examples/gradient_batloww.svg){height=20 .lightbox} | Crameri | Light variant of batlow | -| `hawaii` | ![](examples/gradient_hawaii.svg){height=20 .lightbox} | Crameri | Green-yellow-orange-magenta | -| `lajolla` | ![](examples/gradient_lajolla.svg){height=20 .lightbox} | Crameri | Cream-yellow-orange-brown | -| `tokyo` | ![](examples/gradient_tokyo.svg){height=20 .lightbox} | Crameri | White-magenta-dark blue | -| `turku` | ![](examples/gradient_turku.svg){height=20 .lightbox} | Crameri | Cream-green-dark brown | -| `acton` | ![](examples/gradient_acton.svg){height=20 .lightbox} | Crameri | White-purple | -| `bamako` | ![](examples/gradient_bamako.svg){height=20 .lightbox} | Crameri | White-brown-dark brown | -| `bilbao` | ![](examples/gradient_bilbao.svg){height=20 .lightbox} | Crameri | White-orange-dark brown | -| `buda` | ![](examples/gradient_buda.svg){height=20 .lightbox} | Crameri | White-pink-magenta | -| `davos` | ![](examples/gradient_davos.svg){height=20 .lightbox} | Crameri | White-blue | -| `devon` | ![](examples/gradient_devon.svg){height=20 .lightbox} | Crameri | White-blue-dark blue | -| `glasgow` | ![](examples/gradient_glasgow.svg){height=20 .lightbox} | Crameri | Blue-cream-orange | -| `grayc` | ![](examples/gradient_grayc.svg){height=20 .lightbox} | Crameri | White-black grayscale | -| `imola` | ![](examples/gradient_imola.svg){height=20 .lightbox} | Crameri | Blue-cream-green | -| `lapaz` | ![](examples/gradient_lapaz.svg){height=20 .lightbox} | Crameri | White-blue-dark | -| `lipari` | ![](examples/gradient_lipari.svg){height=20 .lightbox} | Crameri | White-orange-dark blue | -| `nuuk` | ![](examples/gradient_nuuk.svg){height=20 .lightbox} | Crameri | White-blue-green | -| `oslo` | ![](examples/gradient_oslo.svg){height=20 .lightbox} | Crameri | White-blue-black | +| `bilbao` | ![](examples/gradient_bilbao.svg){height=20 .lightbox} | Crameri | Brown-tan-white | +| `buda` | ![](examples/gradient_buda.svg){height=20 .lightbox} | Crameri | Magenta-pink-yellow | +| `davos` | ![](examples/gradient_davos.svg){height=20 .lightbox} | Crameri | Dark blue-teal-green-white | +| `devon` | ![](examples/gradient_devon.svg){height=20 .lightbox} | Crameri | Dark purple-blue-white | +| `glasgow` | ![](examples/gradient_glasgow.svg){height=20 .lightbox} | Crameri | Purple-brown-olive-light purple | +| `grayc` | ![](examples/gradient_grayc.svg){height=20 .lightbox} | Crameri | Black-white grayscale | +| `hawaii` | ![](examples/gradient_hawaii.svg){height=20 .lightbox} | Crameri | Magenta-orange-green-cyan | +| `imola` | ![](examples/gradient_imola.svg){height=20 .lightbox} | Crameri | Blue-teal-green-yellow | +| `lajolla` | ![](examples/gradient_lajolla.svg){height=20 .lightbox} | Crameri | Dark brown-orange-yellow-cream | +| `lapaz` | ![](examples/gradient_lapaz.svg){height=20 .lightbox} | Crameri | Dark purple-blue-teal-cream | +| `lipari` | ![](examples/gradient_lipari.svg){height=20 .lightbox} | Crameri | Dark blue-red-orange-cream | +| `navia` | ![](examples/gradient_navia.svg){height=20 .lightbox} | Crameri | Blue-teal-green-cream | +| `nuuk` | ![](examples/gradient_nuuk.svg){height=20 .lightbox} | Crameri | Blue-teal-green-yellow | +| `oslo` | ![](examples/gradient_oslo.svg){height=20 .lightbox} | Crameri | Black-blue-white | +| `tokyo` | ![](examples/gradient_tokyo.svg){height=20 .lightbox} | Crameri | Dark purple-magenta-olive-green | +| `turku` | ![](examples/gradient_turku.svg){height=20 .lightbox} | Crameri | Black-olive-tan-pink | | `blues` | ![](examples/gradient_blues.svg){height=20 .lightbox} | ColorBrewer | Light to dark blue | | `greens` | ![](examples/gradient_greens.svg){height=20 .lightbox} | ColorBrewer | Light to dark green | | `oranges` | ![](examples/gradient_oranges.svg){height=20 .lightbox} | ColorBrewer | Light to dark orange | @@ -141,15 +142,15 @@ Diverging palettes emphasize a critical midpoint with two contrasting hues on ei | Name | Gradient | Source | Description | |------|----------|--------|-------------| | `vik` | ![](examples/gradient_vik.svg){height=20 .lightbox} | Crameri | Blue-white-red (alias: `diverging`) | -| `berlin` | ![](examples/gradient_berlin.svg){height=20 .lightbox} | Crameri | Blue-white-red (different hues) | -| `roma` | ![](examples/gradient_roma.svg){height=20 .lightbox} | Crameri | Green-cream-orange | -| `bam` | ![](examples/gradient_bam.svg){height=20 .lightbox} | Crameri | Blue-white-red | -| `broc` | ![](examples/gradient_broc.svg){height=20 .lightbox} | Crameri | Brown-white-green | -| `cork` | ![](examples/gradient_cork.svg){height=20 .lightbox} | Crameri | Blue-white-green | -| `lisbon` | ![](examples/gradient_lisbon.svg){height=20 .lightbox} | Crameri | Blue-white-brown | -| `managua` | ![](examples/gradient_managua.svg){height=20 .lightbox} | Crameri | Blue-white-magenta | -| `tofino` | ![](examples/gradient_tofino.svg){height=20 .lightbox} | Crameri | Blue-cream-brown | -| `vanimo` | ![](examples/gradient_vanimo.svg){height=20 .lightbox} | Crameri | Magenta-white-green | +| `berlin` | ![](examples/gradient_berlin.svg){height=20 .lightbox} | Crameri | Light blue-dark-light red | +| `roma` | ![](examples/gradient_roma.svg){height=20 .lightbox} | Crameri | Brown-cream-blue | +| `bam` | ![](examples/gradient_bam.svg){height=20 .lightbox} | Crameri | Purple-white-green | +| `broc` | ![](examples/gradient_broc.svg){height=20 .lightbox} | Crameri | Purple-white-olive | +| `cork` | ![](examples/gradient_cork.svg){height=20 .lightbox} | Crameri | Purple-white-green | +| `lisbon` | ![](examples/gradient_lisbon.svg){height=20 .lightbox} | Crameri | Light purple-dark-light yellow | +| `managua` | ![](examples/gradient_managua.svg){height=20 .lightbox} | Crameri | Yellow-dark-cyan | +| `tofino` | ![](examples/gradient_tofino.svg){height=20 .lightbox} | Crameri | Light purple-dark-light green | +| `vanimo` | ![](examples/gradient_vanimo.svg){height=20 .lightbox} | Crameri | Pink-dark-light green | | `rdbu` | ![](examples/gradient_rdbu.svg){height=20 .lightbox} | ColorBrewer | Red-Blue | | `rdylbu` | ![](examples/gradient_rdylbu.svg){height=20 .lightbox} | ColorBrewer | Red-Yellow-Blue | | `rdylgn` | ![](examples/gradient_rdylgn.svg){height=20 .lightbox} | ColorBrewer | Red-Yellow-Green | @@ -158,7 +159,7 @@ Diverging palettes emphasize a critical midpoint with two contrasting hues on ei | `prgn` | ![](examples/gradient_prgn.svg){height=20 .lightbox} | ColorBrewer | Purple-Green | | `piyg` | ![](examples/gradient_piyg.svg){height=20 .lightbox} | ColorBrewer | Pink-Yellow-Green | | `rdgy` | ![](examples/gradient_rdgy.svg){height=20 .lightbox} | ColorBrewer | Red-Grey | -| `puor` | ![](examples/gradient_puor.svg){height=20 .lightbox} | ColorBrewer | Purple-Orange | +| `puor` | ![](examples/gradient_puor.svg){height=20 .lightbox} | ColorBrewer | Orange-Purple | #### Multi-Sequential @@ -176,11 +177,11 @@ Cyclic palettes wrap around, making them suitable for periodic data like angles, | Name | Gradient | Source | Description | |------|----------|--------|-------------| -| `romao` | ![](examples/gradient_romao.svg){height=20 .lightbox} | Crameri | Cyclic green-orange (alias: `cyclic`) | -| `bamo` | ![](examples/gradient_bamo.svg){height=20 .lightbox} | Crameri | Cyclic blue-red | -| `broco` | ![](examples/gradient_broco.svg){height=20 .lightbox} | Crameri | Cyclic brown-green | -| `corko` | ![](examples/gradient_corko.svg){height=20 .lightbox} | Crameri | Cyclic blue-green | -| `viko` | ![](examples/gradient_viko.svg){height=20 .lightbox} | Crameri | Cyclic blue-red | +| `romao` | ![](examples/gradient_romao.svg){height=20 .lightbox} | Crameri | Cyclic purple-orange-teal-blue (alias: `cyclic`) | +| `bamo` | ![](examples/gradient_bamo.svg){height=20 .lightbox} | Crameri | Cyclic purple-pink-cream-olive | +| `broco` | ![](examples/gradient_broco.svg){height=20 .lightbox} | Crameri | Cyclic gray-blue-cream-olive | +| `corko` | ![](examples/gradient_corko.svg){height=20 .lightbox} | Crameri | Cyclic gray-blue-teal-green | +| `viko` | ![](examples/gradient_viko.svg){height=20 .lightbox} | Crameri | Cyclic purple-blue-cream-orange | ### Discrete palettes @@ -229,7 +230,7 @@ Kelly, K.L. (1965). Twenty-two colors of maximum contrast. *Color Engineering*, #### For general continuous data -- **`navia`** (default) - Good all-purpose choice, perceptually uniform +- **`sequential`** (default) - Good all-purpose choice, perceptually uniform - **`viridis`** - Excellent for print, colorblind-safe, perceptually uniform - **`batlow`** - Wide perceptual range, good for scientific data diff --git a/doc/syntax/scale/aesthetic/examples/gradient_sequential.svg b/doc/syntax/scale/aesthetic/examples/gradient_sequential.svg new file mode 100644 index 00000000..d0d04d53 --- /dev/null +++ b/doc/syntax/scale/aesthetic/examples/gradient_sequential.svg @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/doc/syntax/scale/aesthetic/examples/swatch_ggsql10.svg b/doc/syntax/scale/aesthetic/examples/swatch_ggsql10.svg index ee06a2c3..cdb6abc5 100644 --- a/doc/syntax/scale/aesthetic/examples/swatch_ggsql10.svg +++ b/doc/syntax/scale/aesthetic/examples/swatch_ggsql10.svg @@ -1,12 +1,12 @@ - - - - - - + + + + + + - - + + diff --git a/doc/syntax/scale/aesthetic/generate_examples.R b/doc/syntax/scale/aesthetic/generate_examples.R index 7677476b..4498ad90 100644 --- a/doc/syntax/scale/aesthetic/generate_examples.R +++ b/doc/syntax/scale/aesthetic/generate_examples.R @@ -6,6 +6,8 @@ # Continuous palettes referenced in color_cont.qmd CONTINUOUS_PALETTES <- c( + # ggsql default + "sequential", # Crameri Sequential "navia", "batlow", "batlowk", "batloww", "hawaii", "lajolla", "tokyo", "turku", "acton", "bamako", "bilbao", "buda", "davos", "devon", "glasgow", diff --git a/src/plot/scale/palettes.rs b/src/plot/scale/palettes.rs index 8220470a..22c329ef 100644 --- a/src/plot/scale/palettes.rs +++ b/src/plot/scale/palettes.rs @@ -10,8 +10,8 @@ use crate::plot::ArrayElement; /// ggsql 10 - default categorical palette pub const GGSQL10: &[&str] = &[ - "#0067A5", "#F3C300", "#008856", "#F38400", "#875692", "#BE0032", "#A1CAF1", "#E68FAC", - "#8DB600", "#654522", + "#8DB600", "#0067A5", "#F38400", "#875692", "#F3C300", "#008856", "#A1CAF1", "#BE0032", + "#E68FAC", "#654522", ]; /// Tableau 10 @@ -1482,6 +1482,37 @@ pub const NAVIA: &[&str] = &[ "#F4F1CE", "#F6F2D0", "#F7F2D2", "#F8F2D2", "#F8F2D4", "#F9F2D6", "#FAF3D7", "#FCF3D8", ]; +/// Sequential palette (204 colors) +/// Derived from Crameri navia with 20% of lightest colors removed +pub const SEQUENTIAL: &[&str] = &[ + "#021326", "#041428", "#04152B", "#04172C", "#04182D", "#041930", "#051932", "#051A33", + "#051B35", "#051D38", "#051E39", "#051F3B", "#05203E", "#05213F", "#052241", "#052444", + "#052546", "#052647", "#06274A", "#06284C", "#062A4D", "#062B50", "#062C52", "#062D53", + "#062E55", "#063058", "#063159", "#06325B", "#06335E", "#06345F", "#063561", "#063764", + "#063966", "#073967", "#073A6A", "#073B6B", "#073E6C", "#083F6E", "#083F71", "#0A4072", + "#0A4373", "#0B4476", "#0B4578", "#0B4679", "#0C477A", "#0C487D", "#0C4A7E", "#0D4C7F", + "#0D4C80", "#0E4D81", "#104E84", "#105185", "#115285", "#125286", "#135387", "#135588", + "#13578A", "#14588B", "#15598C", "#17598C", "#175B8C", "#185D8D", "#195E8D", "#195F8E", + "#1A5F8E", "#1A6090", "#1B6190", "#1D6390", "#1E6491", "#1E6591", "#1F6691", "#1F6691", + "#1F6791", "#206891", "#216A91", "#216B91", "#226C91", "#246C91", "#246C91", "#256D90", + "#266E90", "#266E90", "#267090", "#26718E", "#27718E", "#27728E", "#28728E", "#2A728D", + "#2A738D", "#2B748D", "#2B748C", "#2C768C", "#2C768C", "#2C778C", "#2C788C", "#2D788C", + "#2E798B", "#2E798B", "#30798B", "#30798A", "#317A8A", "#317B8A", "#327B88", "#327D88", + "#337D88", "#337E87", "#337E87", "#347F87", "#347F86", "#357F86", "#357F85", "#378085", + "#378085", "#388185", "#398385", "#398385", "#398484", "#398484", "#3A8584", "#3B8583", + "#3B8583", "#3D8581", "#3D8681", "#3E8781", "#3F8780", "#3F8880", "#3F8880", "#3F8A7F", + "#408A7F", "#418B7F", "#418C7F", "#438C7F", "#448C7E", "#448C7E", "#458D7D", "#468E7D", + "#468E7D", "#46907B", "#47917B", "#48917A", "#48927A", "#4A9279", "#4B9279", "#4C9379", + "#4C9479", "#4C9479", "#4D9678", "#4E9778", "#509877", "#509877", "#519976", "#529976", + "#529A74", "#539A74", "#549B73", "#559D73", "#579E72", "#579F72", "#589F72", "#599F72", + "#59A071", "#5AA171", "#5BA370", "#5DA470", "#5EA56E", "#5FA56E", "#5FA66D", "#61A76D", + "#63A96C", "#64AA6C", "#65AB6C", "#66AC6C", "#66AC6B", "#68AD6B", "#6AAE6A", "#6BB06A", + "#6CB168", "#6DB268", "#70B268", "#71B368", "#72B467", "#73B667", "#76B767", "#78B867", + "#79B967", "#7ABA67", "#7DBB67", "#7FBD67", "#80BF67", "#83BF67", "#85C068", "#86C168", + "#88C36A", "#8CC56A", "#8DC56B", "#90C66C", "#92C76C", "#94CA6D", "#98CB6E", "#99CC70", + "#9BCC72", "#9FCD72", "#A1CE73", "#A4D176", +]; + /// Crameri nuuk (256 colors) /// Source: Fabio Crameri scientific colour maps pub const NUUK: &[&str] = &[ @@ -2020,7 +2051,8 @@ pub fn get_color_palette(name: &str) -> Option<&'static [&'static str]> { "lajolla" => Some(LAJOLLA), "lapaz" => Some(LAPAZ), "lipari" => Some(LIPARI), - "navia" | "sequential" => Some(NAVIA), + "navia" => Some(NAVIA), + "sequential" => Some(SEQUENTIAL), "nuuk" => Some(NUUK), "oslo" => Some(OSLO), "tokyo" => Some(TOKYO), @@ -2223,6 +2255,18 @@ mod tests { assert_eq!(get_color_palette("acton").unwrap().len(), 256); } + #[test] + fn test_sequential_palette() { + // Sequential is derived from navia with 20% lightest colors removed + assert_eq!(get_color_palette("sequential").unwrap().len(), 204); + assert_eq!(get_color_palette("navia").unwrap().len(), 256); + // First colors should match + assert_eq!( + get_color_palette("sequential").unwrap()[0], + get_color_palette("navia").unwrap()[0] + ); + } + #[test] fn test_get_shape_palette() { // Combined palette (all shapes)