Repository: plotters-rs/plotters (language: rust)

Issue:
Add palette color support
I just thought it might be of interest to start a discussion about this. I noticed this crate uses it's own simplistic color definitions, so to my mind came the possibility of using the [palette crate](https://github.com/Ogeon/palette) which would allow users to define and use colors in a very great spectrum.


Discussion / hints:
Yes, that looks awesome. Thank you for this suggestion.
I wouldn't mind making a PR for this as well then.
That would be fantastic! thank you in advance! 

Fix patch:
diff --git a/Cargo.toml b/Cargo.toml
index 6abceca4..78e7716a 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -14,6 +14,8 @@ exclude = ["doc-template/*"]
 [dependencies]
 chrono = { version = "0.4.6", optional = true }
 svg = { version = "0.5.12", optional = true }
+num-traits = { version = "^0.2", optional = true }
+palette = { version = "^0.4", default-features = false, optional = true }
 
 [target.'cfg(not(target_arch = "wasm32"))'.dependencies]
 rusttype = "0.7.6"
@@ -28,7 +30,8 @@ js-sys= "0.3.4"
 wasm-bindgen = "0.2.43"
 
 [features]
-default = ["bitmap", "svg", "chrono"]
+default = ["bitmap", "svg", "chrono", "palette_ext"]
+palette_ext = ["palette", "num-traits"]
 bitmap = ["image"]
 datetime = ["chrono"]
 evcxr = ["svg"]
diff --git a/README.md b/README.md
index 6e7497b9..371caf56 100644
--- a/README.md
+++ b/README.md
@@ -86,7 +86,7 @@ And the following code draws a quadratic function. `src/main.rs`,
 use plotters::prelude::*;
 fn main() -> Result<(), Box<dyn std::error::Error>> {
     let root = BitMapBackend::new("plotters-doc-data/0.png", (640, 480)).into_drawing_area();
-    root.fill(&White)?;
+    root.fill(&WHITE)?;
     let mut chart = ChartBuilder::on(&root)
         .caption("y=x^2", ("Arial", 50).into_font())
         .margin(5)
@@ -98,14 +98,14 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
  
     chart.draw_series(LineSeries::new(
         (-50..=50).map(|x| x as f32 / 50.0).map(|x| (x, x * x)),
-        &Red,
+        &RED,
     ))?
         .label("y = x^2")
-        .legend(|(x,y)| Path::new(vec![(x,y), (x + 20,y)], &Red));
+        .legend(|(x,y)| Path::new(vec![(x,y), (x + 20,y)], &RED));
 
     chart.configure_series_labels()
-        .background_style(&White.mix(0.8))
-        .border_style(&Black)
+        .background_style(&WHITE.mix(0.8))
+        .border_style(&BLACK)
         .draw()?;
 
     Ok(())
@@ -128,7 +128,7 @@ extern crate plotters;
 use plotters::prelude::*;
 
 let figure = evcxr_figure((640, 480), |root| {
-    root.fill(&White);
+    root.fill(&WHITE);
     let mut chart = ChartBuilder::on(&root)
         .caption("y=x^2", ("Arial", 50).into_font())
         .margin(5)
@@ -140,14 +140,14 @@ let figure = evcxr_figure((640, 480), |root| {
 
     chart.draw_series(LineSeries::new(
         (-50..=50).map(|x| x as f32 / 50.0).map(|x| (x, x * x)),
-        &Red,
+        &RED,
     )).unwrap()
         .label("y = x^2")
-        .legend(|(x,y)| Path::new(vec![(x,y), (x + 20,y)], &Red));
+        .legend(|(x,y)| Path::new(vec![(x,y), (x + 20,y)], &RED));
 
     chart.configure_series_labels()
-        .background_style(&White.mix(0.8))
-        .border_style(&Black)
+        .background_style(&WHITE.mix(0.8))
+        .border_style(&BLACK)
         .draw()?;
     Ok(())
 });
@@ -227,7 +227,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
     let mut backend = BitMapBackend::new("plotters-doc-data/1.png", (300, 200));
     // And if we want SVG backend
     // let backend = SVGBackend::new("output.svg", (800, 600));
-    backend.draw_rect((50, 50), (200, 150), &Red, true)?;
+    backend.draw_rect((50, 50), (200, 150), &RED, true)?;
     Ok(())
 }
 ```
@@ -272,12 +272,12 @@ To learn more about the element system, please read the [element module document
 use plotters::prelude::*;
 fn main() -> Result<(), Box<dyn std::error::Error>> {
     let root = BitMapBackend::new("plotters-doc-data/3.png", (300, 200)).into_drawing_area();
-    root.fill(&White)?;
+    root.fill(&WHITE)?;
     // Draw an circle on the drawing area
     root.draw(&Circle::new(
         (100, 100),
         50,
-        Into::<ShapeStyle>::into(&Green).filled(),
+        Into::<ShapeStyle>::into(&GREEN).filled(),
     ))?;
     Ok(())
 }
@@ -309,7 +309,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
 
     let dot_and_label = |x: f32, y: f32| {
         return EmptyElement::at((x, y))
-            + Circle::new((0, 0), 3, ShapeStyle::from(&Black).filled())
+            + Circle::new((0, 0), 3, ShapeStyle::from(&BLACK).filled())
             + Text::new(format!("({:.2},{:.2})", x, y), (10, 0), ("Arial", 15.0).into_font());
     };
 
@@ -333,7 +333,7 @@ of the chart context object.
 use plotters::prelude::*;
 fn main() -> Result<(), Box<dyn std::error::Error>> {
     let root = BitMapBackend::new("plotters-doc-data/5.png", (640, 480)).into_drawing_area();
-    root.fill(&White);
+    root.fill(&WHITE);
     let root = root.margin(10, 10, 10, 10);
     // After this point, we should be able to draw construct a chart context
     let mut chart = ChartBuilder::on(&root)
@@ -358,13 +358,13 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
     // And we can draw something in the drawing area
     chart.draw_series(LineSeries::new(
         vec![(0.0, 0.0), (5.0, 5.0), (8.0, 7.0)],
-        &Red,
+        &RED,
     ))?;
     // Similarly, we can draw point series
     chart.draw_series(PointSeries::of_element(
         vec![(0.0, 0.0), (5.0, 5.0), (8.0, 7.0)],
         5,
-        &Red,
+        &RED,
         &|c, s, st| {
             return EmptyElement::at(c)    // We want to construct a composed element on-the-fly
             + Circle::new((0,0),s,st.filled()) // At this point, the new pixel coordinate is established
diff --git a/doc-template/examples/chart.rs b/doc-template/examples/chart.rs
index 7e97c4ba..a8a1af8f 100644
--- a/doc-template/examples/chart.rs
+++ b/doc-template/examples/chart.rs
@@ -1,12 +1,12 @@
 use plotters::prelude::*;
 fn main() -> Result<(), Box<dyn std::error::Error>> {
     let root = BitMapBackend::new("plotters-doc-data/5.png", (640, 480)).into_drawing_area();
-    root.fill(&White);
+    root.fill(&WHITE);
     let root = root.margin(10, 10, 10, 10);
     // After this point, we should be able to draw construct a chart context
     let mut chart = ChartBuilder::on(&root)
         // Set the caption of the chart
-        .caption("This is our first plot", ("Arial",40).into_font())
+        .caption("This is our first plot", ("Arial", 40).into_font())
         // Set the size of the label region
         .x_label_area_size(20)
         .y_label_area_size(40)
@@ -26,13 +26,13 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
     // And we can draw something in the drawing area
     chart.draw_series(LineSeries::new(
         vec![(0.0, 0.0), (5.0, 5.0), (8.0, 7.0)],
-        &Red,
+        &RED,
     ))?;
     // Similarly, we can draw point series
     chart.draw_series(PointSeries::of_element(
         vec![(0.0, 0.0), (5.0, 5.0), (8.0, 7.0)],
         5,
-        &Red,
+        &RED,
         &|c, s, st| {
             return EmptyElement::at(c)    // We want to construct a composed element on-the-fly
             + Circle::new((0,0),s,st.filled()) // At this point, the new pixel coordinate is established
diff --git a/doc-template/examples/composable_elements.rs b/doc-template/examples/composable_elements.rs
index e650baba..6e826037 100644
--- a/doc-template/examples/composable_elements.rs
+++ b/doc-template/examples/composable_elements.rs
@@ -13,8 +13,12 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
 
     let dot_and_label = |x: f32, y: f32| {
         return EmptyElement::at((x, y))
-            + Circle::new((0, 0), 3, ShapeStyle::from(&Black).filled())
-            + Text::new(format!("({:.2},{:.2})", x, y), (10, 0), ("Arial", 15.0).into_font());
+            + Circle::new((0, 0), 3, ShapeStyle::from(&BLACK).filled())
+            + Text::new(
+                format!("({:.2},{:.2})", x, y),
+                (10, 0),
+                ("Arial", 15.0).into_font(),
+            );
     };
 
     root.draw(&dot_and_label(0.5, 0.6))?;
diff --git a/doc-template/examples/drawing_backends.rs b/doc-template/examples/drawing_backends.rs
index b7e300a6..7561e6e6 100644
--- a/doc-template/examples/drawing_backends.rs
+++ b/doc-template/examples/drawing_backends.rs
@@ -4,6 +4,6 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
     let mut backend = BitMapBackend::new("plotters-doc-data/1.png", (300, 200));
     // And if we want SVG backend
     // let backend = SVGBackend::new("output.svg", (800, 600));
-    backend.draw_rect((50, 50), (200, 150), &Red, true)?;
+    backend.draw_rect((50, 50), (200, 150), &RED, true)?;
     Ok(())
 }
diff --git a/doc-template/examples/elements.rs b/doc-template/examples/elements.rs
index 5877b936..4f162227 100644
--- a/doc-template/examples/elements.rs
+++ b/doc-template/examples/elements.rs
@@ -1,12 +1,12 @@
 use plotters::prelude::*;
 fn main() -> Result<(), Box<dyn std::error::Error>> {
     let root = BitMapBackend::new("plotters-doc-data/3.png", (300, 200)).into_drawing_area();
-    root.fill(&White)?;
+    root.fill(&WHITE)?;
     // Draw an circle on the drawing area
     root.draw(&Circle::new(
         (100, 100),
         50,
-        Into::<ShapeStyle>::into(&Green).filled(),
+        Into::<ShapeStyle>::into(&GREEN).filled(),
     ))?;
     Ok(())
 }
diff --git a/doc-template/examples/quick_start.rs b/doc-template/examples/quick_start.rs
index c7603a76..4b5fbd14 100644
--- a/doc-template/examples/quick_start.rs
+++ b/doc-template/examples/quick_start.rs
@@ -1,7 +1,7 @@
 use plotters::prelude::*;
 fn main() -> Result<(), Box<dyn std::error::Error>> {
     let root = BitMapBackend::new("plotters-doc-data/0.png", (640, 480)).into_drawing_area();
-    root.fill(&White)?;
+    root.fill(&WHITE)?;
     let mut chart = ChartBuilder::on(&root)
         .caption("y=x^2", ("Arial", 50).into_font())
         .margin(5)
@@ -10,17 +10,19 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
         .build_ranged(-1f32..1f32, -0.1f32..1f32)?;
 
     chart.configure_mesh().draw()?;
- 
-    chart.draw_series(LineSeries::new(
-        (-50..=50).map(|x| x as f32 / 50.0).map(|x| (x, x * x)),
-        &Red,
-    ))?
+
+    chart
+        .draw_series(LineSeries::new(
+            (-50..=50).map(|x| x as f32 / 50.0).map(|x| (x, x * x)),
+            &RED,
+        ))?
         .label("y = x^2")
-        .legend(|(x,y)| Path::new(vec![(x,y), (x + 20,y)], &Red));
+        .legend(|(x, y)| Path::new(vec![(x, y), (x + 20, y)], &RED));
 
-    chart.configure_series_labels()
-        .background_style(&White.mix(0.8))
-        .border_style(&Black)
+    chart
+        .configure_series_labels()
+        .background_style(&WHITE.mix(0.8))
+        .border_style(&BLACK)
         .draw()?;
 
     Ok(())
diff --git a/doc-template/readme.template.md b/doc-template/readme.template.md
index 00194716..86c50bf5 100644
--- a/doc-template/readme.template.md
+++ b/doc-template/readme.template.md
@@ -55,7 +55,7 @@ extern crate plotters;
 use plotters::prelude::*;
 
 let figure = evcxr_figure((640, 480), |root| {
-    root.fill(&White);
+    root.fill(&WHITE);
     let mut chart = ChartBuilder::on(&root)
         .caption("y=x^2", ("Arial", 50).into_font())
         .margin(5)
@@ -67,14 +67,14 @@ let figure = evcxr_figure((640, 480), |root| {
 
     chart.draw_series(LineSeries::new(
         (-50..=50).map(|x| x as f32 / 50.0).map(|x| (x, x * x)),
-        &Red,
+        &RED,
     )).unwrap()
         .label("y = x^2")
-        .legend(|(x,y)| Path::new(vec![(x,y), (x + 20,y)], &Red));
+        .legend(|(x,y)| Path::new(vec![(x,y), (x + 20,y)], &RED));
 
     chart.configure_series_labels()
-        .background_style(&White.mix(0.8))
-        .border_style(&Black)
+        .background_style(&WHITE.mix(0.8))
+        .border_style(&BLACK)
         .draw()?;
     Ok(())
 });
@@ -234,4 +234,7 @@ For example, the following dependency description would avoid compiling with bit
 plotters = { git = "https://github.com/38/plotters.git", default_features = false, features = ["svg"] }
 ```
 
+The library also allows consumers to make use of the [`Palette`](https://crates.io/crates/palette/) crate's color types by default.
+This behaviour can also be turned off by setting `default_features = false`.
+
 $$style$$
diff --git a/examples/chart.rs b/examples/chart.rs
index 9a789bfc..94b2a70b 100644
--- a/examples/chart.rs
+++ b/examples/chart.rs
@@ -4,7 +4,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
     let root_area =
         BitMapBackend::new("plotters-doc-data/sample.png", (1024, 768)).into_drawing_area();
 
-    root_area.fill(&White)?;
+    root_area.fill(&WHITE)?;
 
     let root_area = root_area
         .titled("Image Title", ("Arial", 60).into_font())?
@@ -29,10 +29,10 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
 
     cc.draw_series(LineSeries::new(
         (0..12).map(|x| ((x - 6) as f32 / 2.0, ((x - 6) as f32 / 2.0).sin())),
-        &Red,
+        &RED,
     ))?
     .label("Sine")
-    .legend(|(x, y)| Path::new(vec![(x, y), (x + 20, y)], &Red));
+    .legend(|(x, y)| Path::new(vec![(x, y), (x + 20, y)], &RED));
 
     cc.draw_series(LineSeries::new(
         (0..6800).map(|x| {
@@ -41,12 +41,12 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
                 ((x - 3400) as f32 / 1000.0).cos(),
             )
         }),
-        &Blue,
+        &BLUE,
     ))?
     .label("Cosine")
-    .legend(|(x, y)| Path::new(vec![(x, y), (x + 20, y)], &Blue));
+    .legend(|(x, y)| Path::new(vec![(x, y), (x + 20, y)], &BLUE));
 
-    cc.configure_series_labels().border_style(&Black).draw()?;
+    cc.configure_series_labels().border_style(&BLACK).draw()?;
 
     /*
     // It's possible to use a existing pointing element
@@ -60,7 +60,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
     cc.draw_series(PointSeries::of_element(
         (0..6).map(|x| ((x - 3) as f32 / 1.0, ((x - 3) as f32 / 1.0).sin())),
         5,
-        ShapeStyle::from(&Red).filled(),
+        ShapeStyle::from(&RED).filled(),
         &|coord, size, style| {
             EmptyElement::at(coord)
                 + Circle::new((0, 0), size, style)
@@ -85,7 +85,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
                     (x as f32 / 100.0).powf(idx as f32 * 2.0 + 1.0),
                 )
             }),
-            &Blue,
+            &BLUE,
         ))?;
     }
 
diff --git a/examples/histogram.rs b/examples/histogram.rs
index db9f937c..5cacdf37 100644
--- a/examples/histogram.rs
+++ b/examples/histogram.rs
@@ -3,7 +3,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
     let root =
         BitMapBackend::new("plotters-doc-data/histogram.png", (640, 480)).into_drawing_area();
 
-    root.fill(&White)?;
+    root.fill(&WHITE)?;
 
     let mut chart = ChartBuilder::on(&root)
         .x_label_area_size(35)
@@ -15,7 +15,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
     chart
         .configure_mesh()
         .disable_x_mesh()
-        .line_style_1(&White.mix(0.3))
+        .line_style_1(&WHITE.mix(0.3))
         .x_label_offset(30)
         .y_desc("Count")
         .x_desc("Bucket")
@@ -28,7 +28,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
 
     chart.draw_series(
         Histogram::vertical(&chart)
-            .style(Red.mix(0.5).filled())
+            .style(RED.mix(0.5).filled())
             .data(data.iter().map(|x: &u32| (*x, 1))),
     )?;
 
diff --git a/examples/mandelbrot.rs b/examples/mandelbrot.rs
index 321a3d15..81fa6882 100644
--- a/examples/mandelbrot.rs
+++ b/examples/mandelbrot.rs
@@ -5,7 +5,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
     let root =
         BitMapBackend::new("plotters-doc-data/mandelbrot.png", (800, 600)).into_drawing_area();
 
-    root.fill(&White)?;
+    root.fill(&WHITE)?;
 
     let mut chart = ChartBuilder::on(&root)
         .margin(20)
@@ -30,7 +30,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
         if c != 100 {
             plotting_area.draw_pixel((x, y), &HSLColor(c as f64 / 100.0, 1.0, 0.5))?;
         } else {
-            plotting_area.draw_pixel((x, y), &Black)?;
+            plotting_area.draw_pixel((x, y), &BLACK)?;
         }
     }
 
diff --git a/examples/normal-dist.rs b/examples/normal-dist.rs
index fe2a1728..f1d4df4d 100644
--- a/examples/normal-dist.rs
+++ b/examples/normal-dist.rs
@@ -8,7 +8,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
     let root =
         BitMapBackend::new("plotters-doc-data/normal-dist.png", (1024, 768)).into_drawing_area();
 
-    root.fill(&White)?;
+    root.fill(&WHITE)?;
 
     let sd = 0.13;
 
@@ -40,10 +40,10 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
     scatter_ctx.draw_series(
         random_points
             .iter()
-            .map(|(x, y)| Circle::new((*x, *y), 2, Green.filled())),
+            .map(|(x, y)| Circle::new((*x, *y), 2, GREEN.filled())),
     )?;
     let x_hist = Histogram::vertical(&x_hist_ctx)
-        .style(Green.filled())
+        .style(GREEN.filled())
         .margin(0)
         .data(
             random_points
@@ -51,7 +51,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
                 .map(|(x, _)| ((x * 100.0) as u32, 0.002)),
         );
     let y_hist = Histogram::horizental(&y_hist_ctx)
-        .style(Green.filled())
+        .style(GREEN.filled())
         .margin(0)
         .data(
             random_points
diff --git a/examples/piston-demo/src/main.rs b/examples/piston-demo/src/main.rs
index 57bef1d3..7d94c1eb 100644
--- a/examples/piston-demo/src/main.rs
+++ b/examples/piston-demo/src/main.rs
@@ -15,18 +15,18 @@ fn main() {
         .unwrap();
     let sys = System::new();
     window.set_max_fps(FPS as u64);
-    let mut load_measurement:Vec<_> = (0..FPS).map(|_| sys.cpu_load().unwrap()).collect();
+    let mut load_measurement: Vec<_> = (0..FPS).map(|_| sys.cpu_load().unwrap()).collect();
     let mut epoch = 0;
     let mut data = vec![];
     while let Some(_) = draw_piston_window(&mut window, |b| {
-        let cpu_loads = load_measurement[epoch%FPS as usize].done()?;
+        let cpu_loads = load_measurement[epoch % FPS as usize].done()?;
 
         let root = b.into_drawing_area();
-        root.fill(&White)?;
+        root.fill(&WHITE)?;
 
         if data.len() < cpu_loads.len() {
             for _ in data.len()..cpu_loads.len() {
-                data.push(VecDeque::from(vec![0f32;N_DATA_POINTS+1]));
+                data.push(VecDeque::from(vec![0f32; N_DATA_POINTS + 1]));
             }
         }
 
@@ -66,8 +66,8 @@ fn main() {
         }
 
         cc.configure_series_labels()
-            .background_style(&White.mix(0.8))
-            .border_style(&Black)
+            .background_style(&WHITE.mix(0.8))
+            .border_style(&BLACK)
             .draw()?;
 
         load_measurement[epoch % FPS as usize] = sys.cpu_load()?;
diff --git a/examples/stock.rs b/examples/stock.rs
index 78513a91..120cf279 100644
--- a/examples/stock.rs
+++ b/examples/stock.rs
@@ -10,7 +10,7 @@ fn parse_time(t: &str) -> Date<Local> {
 fn main() -> Result<(), Box<dyn std::error::Error>> {
     let data = get_data();
     let root = BitMapBackend::new("plotters-doc-data/stock.png", (1024, 768)).into_drawing_area();
-    root.fill(&White)?;
+    root.fill(&WHITE)?;
 
     let (to_date, from_date) = (
         parse_time(&data[0].0) + Duration::days(1),
@@ -23,11 +23,11 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
         .caption("MSFT Stock Price", ("Arial", 50.0).into_font())
         .build_ranged(from_date..to_date, 110f32..135f32)?;
 
-    chart.configure_mesh().line_style_2(&White).draw()?;
+    chart.configure_mesh().line_style_2(&WHITE).draw()?;
 
     chart.draw_series(
         data.iter()
-            .map(|x| CandleStick::new(parse_time(x.0), x.1, x.2, x.3, x.4, &Green, &Red, 15)),
+            .map(|x| CandleStick::new(parse_time(x.0), x.1, x.2, x.3, x.4, &GREEN, &RED, 15)),
     )?;
 
     Ok(())
diff --git a/examples/wasm-demo/src/func_plot.rs b/examples/wasm-demo/src/func_plot.rs
index 890be75a..05cbc054 100644
--- a/examples/wasm-demo/src/func_plot.rs
+++ b/examples/wasm-demo/src/func_plot.rs
@@ -9,7 +9,7 @@ fn start_plotting(
     let root = backend.into_drawing_area();
     let font: FontDesc = ("Arial", 20.0).into();
 
-    root.fill(&White)?;
+    root.fill(&WHITE)?;
 
     let mut chart = ChartBuilder::on(&root)
         .caption(format!("y=x^{}", pow), font)
@@ -23,7 +23,7 @@ fn start_plotting(
         (-50..=50)
             .map(|x| x as f32 / 50.0)
             .map(|x| (x, x.powf(pow as f32))),
-        &Red,
+        &RED,
     ))?;
 
     root.present()?;
diff --git a/examples/wasm-demo/src/mandelbrot.rs b/examples/wasm-demo/src/mandelbrot.rs
index 73fd3fb4..79a864e1 100644
--- a/examples/wasm-demo/src/mandelbrot.rs
+++ b/examples/wasm-demo/src/mandelbrot.rs
@@ -33,7 +33,7 @@ fn draw_mandelbrot_impl(
     let backend = CanvasBackend::new(element).unwrap();
 
     let root = backend.into_drawing_area();
-    root.fill(&White)?;
+    root.fill(&WHITE)?;
 
     let mut chart = ChartBuilder::on(&root)
         .margin(20)
@@ -57,7 +57,7 @@ fn draw_mandelbrot_impl(
         if c != 100 {
             plotting_area.draw_pixel((x, y), &HSLColor(c as f64 / 100.0, 1.0, 0.5))?;
         } else {
-            plotting_area.draw_pixel((x, y), &Black)?;
+            plotting_area.draw_pixel((x, y), &BLACK)?;
         }
     }
 
diff --git a/src/chart/series.rs b/src/chart/series.rs
index b5f8c07d..b6d0bffc 100644
--- a/src/chart/series.rs
+++ b/src/chart/series.rs
@@ -3,7 +3,7 @@ use crate::coord::CoordTranslate;
 use crate::drawing::backend::{BackendCoord, DrawingErrorKind};
 use crate::drawing::{DrawingAreaErrorKind, DrawingBackend};
 use crate::element::{EmptyElement, IntoDynElement, MultiLineText, Rectangle};
-use crate::style::{IntoFont, ShapeStyle, TextStyle, Transparent};
+use crate::style::{IntoFont, ShapeStyle, TextStyle, TRANSPARENT};
 
 pub enum SeriesLabelPosition {
     UpperLeft,
@@ -59,8 +59,8 @@ impl<'a, 'b, DB: DrawingBackend + 'a, CT: CoordTranslate> SeriesLabelStyle<'a, '
             target,
             position: SeriesLabelPosition::MiddleRight,
             legend_area_size: 30,
-            border_style: (&Transparent).into(),
-            background: (&Transparent).into(),
+            border_style: (&TRANSPARENT).into(),
+            background: (&TRANSPARENT).into(),
             label_font: None,
             margin: 10,
         }
diff --git a/src/element/basic_shapes.rs b/src/element/basic_shapes.rs
index be61d9ca..8b562b51 100644
--- a/src/element/basic_shapes.rs
+++ b/src/element/basic_shapes.rs
@@ -46,7 +46,7 @@ fn test_pixel_element() {
         m.check_draw_pixel(|c, (x, y)| {
             assert_eq!(x, 150);
             assert_eq!(y, 152);
-            assert_eq!(c, Red.to_rgba());
+            assert_eq!(c, RED.to_rgba());
         });
 
         m.drop_check(|b| {
@@ -54,7 +54,7 @@ fn test_pixel_element() {
             assert_eq!(b.draw_count, 1);
         });
     });
-    da.draw(&Pixel::new((150, 152), &Red))
+    da.draw(&Pixel::new((150, 152), &RED))
         .expect("Drawing Failure");
 }
 
@@ -100,7 +100,7 @@ fn test_path_element() {
     use crate::prelude::*;
     let da = crate::create_mocked_drawing_area(300, 300, |m| {
         m.check_draw_path(|c, path| {
-            assert_eq!(c, Blue.to_rgba());
+            assert_eq!(c, BLUE.to_rgba());
             assert_eq!(path, vec![(100, 101), (105, 107), (150, 157)]);
         });
         m.drop_check(|b| {
@@ -108,7 +108,7 @@ fn test_path_element() {
             assert_eq!(b.draw_count, 1);
         });
     });
-    da.draw(&Path::new(vec![(100, 101), (105, 107), (150, 157)], &Blue))
+    da.draw(&Path::new(vec![(100, 101), (105, 107), (150, 157)], &BLUE))
         .expect("Drawing Failure");
 }
 
@@ -177,7 +177,7 @@ fn test_rect_element() {
     use crate::prelude::*;
     let da = crate::create_mocked_drawing_area(300, 300, |m| {
         m.check_draw_rect(|c, f, u, d| {
-            assert_eq!(c, Blue.to_rgba());
+            assert_eq!(c, BLUE.to_rgba());
             assert_eq!(f, false);
             assert_eq!([u, d], [(100, 101), (105, 107)]);
         });
@@ -186,7 +186,7 @@ fn test_rect_element() {
             assert_eq!(b.draw_count, 1);
         });
     });
-    da.draw(&Rectangle::new([(100, 101), (105, 107)], &Blue))
+    da.draw(&Rectangle::new([(100, 101), (105, 107)], &BLUE))
         .expect("Drawing Failure");
 }
 
@@ -239,7 +239,7 @@ fn test_circle_element() {
     use crate::prelude::*;
     let da = crate::create_mocked_drawing_area(300, 300, |m| {
         m.check_draw_circle(|c, f, s, r| {
-            assert_eq!(c, Blue.to_rgba());
+            assert_eq!(c, BLUE.to_rgba());
             assert_eq!(f, false);
             assert_eq!(s, (150, 151));
             assert_eq!(r, 20);
@@ -249,6 +249,6 @@ fn test_circle_element() {
             assert_eq!(b.draw_count, 1);
         });
     });
-    da.draw(&Circle::new((150, 151), 20, &Blue))
+    da.draw(&Circle::new((150, 151), 20, &BLUE))
         .expect("Drawing Failure");
 }
diff --git a/src/element/mod.rs b/src/element/mod.rs
index 6336fa55..61c05f67 100644
--- a/src/element/mod.rs
+++ b/src/element/mod.rs
@@ -44,8 +44,8 @@
             backend: &mut DB
         ) -> Result<(), DrawingErrorKind<DB::ErrorType>> {
             let pos = pos.next().unwrap();
-            backend.draw_rect(pos, (pos.0 + 10, pos.1 + 12), &Red.to_rgba(), false)?;
-            backend.draw_text("X", &("Arial", 20).into(), pos, &Red.to_rgba())
+            backend.draw_rect(pos, (pos.0 + 10, pos.1 + 12), &RED.to_rgba(), false)?;
+            backend.draw_text("X", &("Arial", 20).into(), pos, &RED.to_rgba())
         }
     }
 
@@ -77,8 +77,8 @@
         ).into_drawing_area();
         let font:FontDesc = ("Arial", 20).into();
         root.draw(&(EmptyElement::at((200, 200))
-                + Text::new("X", (0, 0), &"Arial".into_font().resize(20.0).color(&Red))
-                + Rectangle::new([(0,0), (10, 12)], &Red)
+                + Text::new("X", (0, 0), &"Arial".into_font().resize(20.0).color(&RED))
+                + Rectangle::new([(0,0), (10, 12)], &RED)
         ))?;
         Ok(())
     }
@@ -121,7 +121,7 @@
         let root =
             BitMapBackend::new("plotters-doc-data/element-3.png", (640, 480))
             .into_drawing_area();
-        root.fill(&White)?;
+        root.fill(&WHITE)?;
         let mut chart = ChartBuilder::on(&root)
             .x_label_area_size(40)
             .y_label_area_size(40)
@@ -140,9 +140,9 @@
             // but they can be placed into a dynamic element wrapper,
             // by doing so, the type is unified.
             if center.1 == 2 {
-                Cross::new(center, 4, Into::<ShapeStyle>::into(&Red).filled()).into_dyn()
+                Cross::new(center, 4, Into::<ShapeStyle>::into(&RED).filled()).into_dyn()
             } else {
-                Circle::new(center, 4, Into::<ShapeStyle>::into(&Green).filled()).into_dyn()
+                Circle::new(center, 4, Into::<ShapeStyle>::into(&GREEN).filled()).into_dyn()
             }
         }))?;
 
diff --git a/src/lib.rs b/src/lib.rs
index 3b8a795c..20c45458 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -134,7 +134,7 @@ And the following code draws a quadratic function. `src/main.rs`,
 use plotters::prelude::*;
 fn main() -> Result<(), Box<dyn std::error::Error>> {
     let root = BitMapBackend::new("plotters-doc-data/0.png", (640, 480)).into_drawing_area();
-    root.fill(&White)?;
+    root.fill(&WHITE)?;
     let mut chart = ChartBuilder::on(&root)
         .caption("y=x^2", ("Arial", 50).into_font())
         .margin(5)
@@ -146,14 +146,14 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
 
     chart.draw_series(LineSeries::new(
         (-50..=50).map(|x| x as f32 / 50.0).map(|x| (x, x * x)),
-        &Red,
+        &RED,
     ))?
         .label("y = x^2")
-        .legend(|(x,y)| Path::new(vec![(x,y), (x + 20,y)], &Red));
+        .legend(|(x,y)| Path::new(vec![(x,y), (x + 20,y)], &RED));
 
     chart.configure_series_labels()
-        .background_style(&White.mix(0.8))
-        .border_style(&Black)
+        .background_style(&WHITE.mix(0.8))
+        .border_style(&BLACK)
         .draw()?;
 
     Ok(())
@@ -176,7 +176,7 @@ extern crate plotters;
 use plotters::prelude::*;
 
 let figure = evcxr_figure((640, 480), |root| {
-    root.fill(&White);
+    root.fill(&WHITE);
     let mut chart = ChartBuilder::on(&root)
         .caption("y=x^2", ("Arial", 50).into_font())
         .margin(5)
@@ -188,14 +188,14 @@ let figure = evcxr_figure((640, 480), |root| {
 
     chart.draw_series(LineSeries::new(
         (-50..=50).map(|x| x as f32 / 50.0).map(|x| (x, x * x)),
-        &Red,
+        &RED,
     )).unwrap()
         .label("y = x^2")
-        .legend(|(x,y)| Path::new(vec![(x,y), (x + 20,y)], &Red));
+        .legend(|(x,y)| Path::new(vec![(x,y), (x + 20,y)], &RED));
 
     chart.configure_series_labels()
-        .background_style(&White.mix(0.8))
-        .border_style(&Black)
+        .background_style(&WHITE.mix(0.8))
+        .border_style(&BLACK)
         .draw()?;
     Ok(())
 });
@@ -275,7 +275,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
     let mut backend = BitMapBackend::new("plotters-doc-data/1.png", (300, 200));
     // And if we want SVG backend
     // let backend = SVGBackend::new("output.svg", (800, 600));
-    backend.draw_rect((50, 50), (200, 150), &Red, true)?;
+    backend.draw_rect((50, 50), (200, 150), &RED, true)?;
     Ok(())
 }
 ```
@@ -320,12 +320,12 @@ To learn more about the element system, please read the [element module document
 use plotters::prelude::*;
 fn main() -> Result<(), Box<dyn std::error::Error>> {
     let root = BitMapBackend::new("plotters-doc-data/3.png", (300, 200)).into_drawing_area();
-    root.fill(&White)?;
+    root.fill(&WHITE)?;
     // Draw an circle on the drawing area
     root.draw(&Circle::new(
         (100, 100),
         50,
-        Into::<ShapeStyle>::into(&Green).filled(),
+        Into::<ShapeStyle>::into(&GREEN).filled(),
     ))?;
     Ok(())
 }
@@ -357,7 +357,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
 
     let dot_and_label = |x: f32, y: f32| {
         return EmptyElement::at((x, y))
-            + Circle::new((0, 0), 3, ShapeStyle::from(&Black).filled())
+            + Circle::new((0, 0), 3, ShapeStyle::from(&BLACK).filled())
             + Text::new(format!("({:.2},{:.2})", x, y), (10, 0), ("Arial", 15.0).into_font());
     };
 
@@ -381,7 +381,7 @@ of the chart context object.
 use plotters::prelude::*;
 fn main() -> Result<(), Box<dyn std::error::Error>> {
     let root = BitMapBackend::new("plotters-doc-data/5.png", (640, 480)).into_drawing_area();
-    root.fill(&White);
+    root.fill(&WHITE);
     let root = root.margin(10, 10, 10, 10);
     // After this point, we should be able to draw construct a chart context
     let mut chart = ChartBuilder::on(&root)
@@ -406,13 +406,13 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
     // And we can draw something in the drawing area
     chart.draw_series(LineSeries::new(
         vec![(0.0, 0.0), (5.0, 5.0), (8.0, 7.0)],
-        &Red,
+        &RED,
     ))?;
     // Similarly, we can draw point series
     chart.draw_series(PointSeries::of_element(
         vec![(0.0, 0.0), (5.0, 5.0), (8.0, 7.0)],
         5,
-        &Red,
+        &RED,
         &|c, s, st| {
             return EmptyElement::at(c)    // We want to construct a composed element on-the-fly
             + Circle::new((0,0),s,st.filled()) // At this point, the new pixel coordinate is established
@@ -484,6 +484,9 @@ pub mod evcxr;
 #[cfg(test)]
 pub use crate::drawing::create_mocked_drawing_area;
 
+#[cfg(feature = "palette_ext")]
+pub use palette;
+
 /// The module imports the most commonly used types and modules in Plotters
 pub mod prelude {
     pub use crate::chart::{ChartBuilder, ChartContext, SeriesLabelPosition};
@@ -498,10 +501,10 @@ pub mod prelude {
     pub use crate::drawing::*;
     pub use crate::series::{Histogram, LineSeries, PointSeries};
     pub use crate::style::{
-        Black, Blue, Color, Cyan, FontDesc, FontTransform, Green, HSLColor, IntoFont, Magenta,
-        Palette, Palette100, Palette99, Palette9999, PaletteColor, RGBColor, Red, ShapeStyle,
-        SimpleColor, TextStyle, Transparent, White, Yellow,
+        Color, FontDesc, FontTransform, HSLColor, IntoFont, Palette, Palette100, Palette99,
+        Palette9999, PaletteColor, RGBColor, ShapeStyle, SimpleColor, TextStyle,
     };
+    pub use crate::style::{BLACK, BLUE, CYAN, GREEN, MAGENTA, RED, TRANSPARENT, WHITE, YELLOW};
 
     pub use crate::element::{
         CandleStick, Circle, Cross, DynElement, EmptyElement, IntoDynElement, MultiLineText, Path,
diff --git a/src/series/histogram.rs b/src/series/histogram.rs
index a63d1c72..0ee377b7 100644
--- a/src/series/histogram.rs
+++ b/src/series/histogram.rs
@@ -7,7 +7,7 @@ use crate::chart::ChartContext;
 use crate::coord::{DescreteRanged, Ranged, RangedCoord};
 use crate::drawing::DrawingBackend;
 use crate::element::Rectangle;
-use crate::style::{Color, Green, ShapeStyle};
+use crate::style::{Color, ShapeStyle, GREEN};
 
 pub trait HistogramType {}
 pub struct Vertical;
@@ -40,7 +40,7 @@ where
 {
     fn empty() -> Self {
         Self {
-            style: Green.filled(),
+            style: GREEN.filled(),
             margin: 5,
             iter: HashMap::new().into_iter(),
             baseline: Box::new(|| A::default()),
diff --git a/src/style/color.rs b/src/style/color.rs
index 7fd0103f..1d61c774 100644
--- a/src/style/color.rs
+++ b/src/style/color.rs
@@ -37,7 +37,7 @@ pub trait Color {
 /// The RGBA representation of the color, Plotters use RGBA as the internal representation
 /// of color
 #[derive(Clone, PartialEq, Debug)]
-pub struct RGBAColor(u8, u8, u8, f64);
+pub struct RGBAColor(pub(super) u8, pub(super) u8, pub(super) u8, pub(super) f64);
 
 impl Color for RGBAColor {
     fn rgb(&self) -> (u8, u8, u8) {
@@ -93,41 +93,6 @@ impl SimpleColor for RGBColor {
     }
 }
 
-macro_rules! predefined_color {
-    ($name:ident, $r:expr, $g:expr, $b:expr, $doc: expr) => {
-        #[doc = $doc]
-        pub struct $name;
-        impl SimpleColor for $name {
-            fn rgb(&self) -> (u8,u8,u8) {
-                return ($r, $g, $b);
-            }
-        }
-    };
-
-    ($name:ident, $r:expr, $g:expr, $b:expr, $a: expr, $doc: expr) => {
-        #[doc = $doc]
-        pub struct $name;
-        impl Color for $name {
-            fn rgb(&self) -> (u8,u8,u8) {
-                return ($r, $g, $b);
-            }
-            fn alpha(&self) -> f64 {
-                $a
-            }
-        }
-    }
-}
-
-predefined_color!(White, 255, 255, 255, "The predefined white color");
-predefined_color!(Black, 0, 0, 0, "The predefined black color");
-predefined_color!(Red, 255, 0, 0, "The predefined red color");
-predefined_color!(Green, 0, 255, 0, "The predefined green color");
-predefined_color!(Blue, 0, 0, 255, "The predefined blue color");
-predefined_color!(Yellow, 255, 255, 0, "The predefined yellow color");
-predefined_color!(Cyan, 0, 255, 255, "The predefined cyan color");
-predefined_color!(Magenta, 255, 0, 255, "The predefined magenta color");
-predefined_color!(Transparent, 0, 0, 0, 0.0, "The predefined transparent");
-
 /// The color described by HSL color space
 pub struct HSLColor(pub f64, pub f64, pub f64);
 
diff --git a/src/style/colors.rs b/src/style/colors.rs
new file mode 100644
index 00000000..4854da84
--- /dev/null
+++ b/src/style/colors.rs
@@ -0,0 +1,57 @@
+//! Basic predefined colors.
+use super::{RGBAColor, RGBColor};
+
+macro_rules! predefined_color {
+    ($name:ident, $r:expr, $g:expr, $b:expr, $doc:expr) => {
+        #[doc = $doc]
+        pub const $name: RGBColor = RGBColor($r, $g, $b);
+    };
+
+    ($name:ident, $r:expr, $g:expr, $b:expr, $a: expr, $doc:expr) => {
+        #[doc = $doc]
+        pub const $name: RGBAColor = RGBAColor($r, $g, $b, $a);
+    }
+}
+
+predefined_color!(WHITE, 255, 255, 255, "The predefined white color");
+predefined_color!(BLACK, 0, 0, 0, "The predefined black color");
+predefined_color!(RED, 255, 0, 0, "The predefined red color");
+predefined_color!(GREEN, 0, 255, 0, "The predefined green color");
+predefined_color!(BLUE, 0, 0, 255, "The predefined blue color");
+predefined_color!(YELLOW, 255, 255, 0, "The predefined yellow color");
+predefined_color!(CYAN, 0, 255, 255, "The predefined cyan color");
+predefined_color!(MAGENTA, 255, 0, 255, "The predefined magenta color");
+predefined_color!(TRANSPARENT, 0, 0, 0, 0.0, "The predefined transparent");
+
+/// Predefined Color definitions using the [palette](https://docs.rs/palette/) color types
+#[cfg(feature = "palette_ext")]
+pub mod palette_ext {
+    use palette::rgb::Srgb;
+    use palette::Alpha;
+
+    use std::marker::PhantomData;
+
+    macro_rules! predefined_color_pal {
+        ($name:ident, $r:expr, $g:expr, $b:expr, $doc:expr) => {
+            #[doc = $doc]
+            pub const $name: Srgb<u8> = predefined_color_pal!(@gen_c $r, $g, $b);
+        };
+        ($name:ident, $r:expr, $g:expr, $b:expr, $a:expr, $doc:expr) => {
+            #[doc = $doc]
+            pub const $name: Alpha<Srgb<u8>, f64> = Alpha{ alpha: $a, color: predefined_color_pal!(@gen_c $r, $g, $b) };
+        };
+        (@gen_c $r:expr, $g:expr, $b:expr) => {
+            Srgb { red: $r, green: $g, blue: $b, standard: PhantomData }
+        };
+    }
+
+    predefined_color_pal!(WHITE, 255, 255, 255, "The predefined white color");
+    predefined_color_pal!(BLACK, 0, 0, 0, "The predefined black color");
+    predefined_color_pal!(RED, 255, 0, 0, "The predefined red color");
+    predefined_color_pal!(GREEN, 0, 255, 0, "The predefined green color");
+    predefined_color_pal!(BLUE, 0, 0, 255, "The predefined blue color");
+    predefined_color_pal!(YELLOW, 255, 255, 0, "The predefined yellow color");
+    predefined_color_pal!(CYAN, 0, 255, 255, "The predefined cyan color");
+    predefined_color_pal!(MAGENTA, 255, 0, 255, "The predefined magenta color");
+    predefined_color_pal!(TRANSPARENT, 0, 0, 0, 0.0, "The predefined transparent");
+}
diff --git a/src/style/mod.rs b/src/style/mod.rs
index fa5bc5e4..2da759fd 100644
--- a/src/style/mod.rs
+++ b/src/style/mod.rs
@@ -2,16 +2,18 @@
   The style for shapes and text, font, color, etc.
 */
 mod color;
+pub mod colors;
 mod font;
 mod palette;
 
-pub use color::{
-    Black, Blue, Color, Cyan, Green, HSLColor, Magenta, PaletteColor, RGBAColor, RGBColor, Red,
-    SimpleColor, Transparent, White, Yellow,
-};
+#[cfg(feature = "palette_ext")]
+mod palette_ext;
 
+/// Definitions of palettes of accessibility
+pub use self::palette::*;
+pub use color::{Color, HSLColor, PaletteColor, RGBAColor, RGBColor, SimpleColor};
+pub use colors::{BLACK, BLUE, CYAN, GREEN, MAGENTA, RED, TRANSPARENT, WHITE, YELLOW};
 pub use font::{FontDesc, FontError, FontResult, FontTransform, IntoFont, LayoutBox};
-pub use palette::*;
 
 /// Style of a text
 #[derive(Clone)]
@@ -48,7 +50,7 @@ impl<'a, T: Into<FontDesc<'a>>> From<T> for TextStyle<'a> {
     fn from(font: T) -> Self {
         Self {
             font: font.into(),
-            color: Black.to_rgba(),
+            color: BLACK.to_rgba(),
         }
     }
 }
diff --git a/src/style/palette_ext.rs b/src/style/palette_ext.rs
new file mode 100644
index 00000000..35e15ff5
--- /dev/null
+++ b/src/style/palette_ext.rs
@@ -0,0 +1,136 @@
+use num_traits::Float;
+
+use palette::encoding::Linear;
+use palette::luma::{Luma, LumaStandard};
+use palette::rgb::RgbStandard;
+use palette::rgb::{Rgb, RgbSpace};
+use palette::white_point::D65;
+use palette::{Alpha, Component, Hsl, Hsv, Hwb, Lab, Lch, LinSrgb, Xyz, Yxy};
+
+use super::color::Color;
+
+impl<S: RgbStandard, T: Component> Color for Rgb<S, T> {
+    fn rgb(&self) -> (u8, u8, u8) {
+        self.into_format::<u8>().into_components()
+    }
+
+    #[inline]
+    fn alpha(&self) -> f64 {
+        1.0
+    }
+}
+
+impl<S: LumaStandard, T: Component> Color for Luma<S, T> {
+    fn rgb(&self) -> (u8, u8, u8) {
+        let (luma,) = self.into_format::<u8>().into_components();
+        (luma, luma, luma)
+    }
+
+    #[inline]
+    fn alpha(&self) -> f64 {
+        1.0
+    }
+}
+
+impl<S: RgbSpace, T: Component + Float> Color for Hsl<S, T> {
+    fn rgb(&self) -> (u8, u8, u8) {
+        Rgb::<Linear<S>, T>::from(*self)
+            .into_format::<u8>()
+            .into_components()
+    }
+
+    #[inline]
+    fn alpha(&self) -> f64 {
+        1.0
+    }
+}
+
+impl<S: RgbSpace, T: Component + Float> Color for Hsv<S, T> {
+    fn rgb(&self) -> (u8, u8, u8) {
+        Rgb::<Linear<S>, T>::from(*self)
+            .into_format::<u8>()
+            .into_components()
+    }
+
+    #[inline]
+    fn alpha(&self) -> f64 {
+        1.0
+    }
+}
+
+impl<S: RgbSpace, T: Component + Float> Color for Hwb<S, T> {
+    fn rgb(&self) -> (u8, u8, u8) {
+        Rgb::<Linear<S>, T>::from(*self)
+            .into_format::<u8>()
+            .into_components()
+    }
+
+    #[inline]
+    fn alpha(&self) -> f64 {
+        1.0
+    }
+}
+
+impl<T: Component + Float> Color for Lab<D65, T> {
+    fn rgb(&self) -> (u8, u8, u8) {
+        LinSrgb::<T>::from(*self)
+            .into_format::<u8>()
+            .into_components()
+    }
+
+    #[inline]
+    fn alpha(&self) -> f64 {
+        1.0
+    }
+}
+
+impl<T: Component + Float> Color for Lch<D65, T> {
+    fn rgb(&self) -> (u8, u8, u8) {
+        LinSrgb::<T>::from(*self)
+            .into_format::<u8>()
+            .into_components()
+    }
+
+    #[inline]
+    fn alpha(&self) -> f64 {
+        1.0
+    }
+}
+
+impl<T: Component + Float> Color for Xyz<D65, T> {
+    fn rgb(&self) -> (u8, u8, u8) {
+        LinSrgb::<T>::from(*self)
+            .into_format::<u8>()
+            .into_components()
+    }
+
+    #[inline]
+    fn alpha(&self) -> f64 {
+        1.0
+    }
+}
+
+impl<T: Component + Float> Color for Yxy<D65, T> {
+    fn rgb(&self) -> (u8, u8, u8) {
+        LinSrgb::<T>::from(*self)
+            .into_format::<u8>()
+            .into_components()
+    }
+
+    #[inline]
+    fn alpha(&self) -> f64 {
+        1.0
+    }
+}
+
+impl<C: Color, T: Component> Color for Alpha<C, T> {
+    #[inline]
+    fn rgb(&self) -> (u8, u8, u8) {
+        self.color.rgb()
+    }
+
+    #[inline]
+    fn alpha(&self) -> f64 {
+        self.alpha.convert()
+    }
+}


Test patch: