How to Configure Plotly Visualization with Custom Themes in optionstratlib

You configure Plotly visualization with custom themes in optionstratlib by setting the color_scheme field in GraphConfig to ColorScheme::Custom with a vector of hex color strings, which the Graph trait automatically applies when rendering.

The optionstratlib crate provides a comprehensive visualization module that leverages Plotly for interactive financial charts. When you configure Plotly visualization with custom themes, you control the aesthetic layer through a type-safe enum system while maintaining full programmatic control over individual trace colors.

Understanding the Theme Architecture

ColorScheme Enum

The foundation of theme configuration resides in src/visualization/styles.rs. The ColorScheme enum defines both built-in palettes and the custom variant:

  • Default – Standard library palette
  • Viridis – Perceptually uniform sequential colormap
  • Plasma – High-contrast sequential palette
  • White – Monochromatic white theme
  • HighContrast – Accessibility-optimized colors
  • Custom(Vec<String>) – User-defined hex, rgb, or CSS color names

GraphConfig Struct

Located in src/visualization/config.rs, GraphConfig serves as the central configuration container. The color_scheme field accepts any ColorScheme variant, while additional fields control line styles, dimensions, axis labels, and legend visibility.

Implementing Custom Color Themes

To apply a custom palette, instantiate ColorScheme::Custom with your color vector when building the GraphConfig:

use optionstratlib::visualization::{
    Graph, GraphConfig, GraphData, Series2D, ColorScheme, LineStyle, OutputType,
};
use std::path::Path;

struct MyCustomPlot;

impl Graph for MyCustomPlot {
    fn graph_data(&self) -> GraphData {
        let series = Series2D {
            x: vec![0.0, 1.0, 2.0, 3.0],
            y: vec![0.0, 2.0, 1.0, 3.0],
            ..Default::default()
        };
        GraphData::Series(series)
    }

    fn graph_config(&self) -> GraphConfig {
        let custom_colors = vec![
            "#1f77b4".into(), // muted blue
            "#ff7f0e".into(), // orange
            "#2ca02c".into(), // green
        ];

        GraphConfig {
            title: "Custom Themed Analysis".into(),
            width: 800,
            height: 600,
            color_scheme: ColorScheme::Custom(custom_colors),
            line_style: LineStyle::Dashed,
            ..Default::default()
        }
    }
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let plot = MyCustomPlot;
    plot.render(OutputType::Html(Path::new("output.html").to_path_buf()))?;
    Ok(())
}

The pick_color function in src/visualization/utils.rs handles the color resolution. It cycles through the custom palette based on trace index, ensuring each series receives a distinct color from your defined set.

Overriding Individual Trace Colors

You can override specific trace colors while maintaining the theme for others. Set the line_color field on individual Series2D instances:

impl Graph for MyPlot {
    fn graph_data(&self) -> GraphData {
        let mut s1 = Series2D {
            x: vec![0.0, 1.0, 2.0],
            y: vec![0.0, 1.0, 0.5],
            ..Default::default()
        };
        s1.line_color = Some("#d62728".into()); // Force red for this trace

        let s2 = Series2D {
            x: vec![0.0, 1.0, 2.0],
            y: vec![1.0, 0.5, 1.5],
            ..Default::default()
        };

        GraphData::MultiSeries(vec![s1, s2])
    }

    fn graph_config(&self) -> GraphConfig {
        GraphConfig {
            color_scheme: ColorScheme::Viridis, // s2 uses Viridis palette
            ..Default::default()
        }
    }
}

The to_plot method in src/visualization/plotly.rs checks for explicit colors before consulting the ColorScheme, allowing this mixed approach.

Built-in Theme Options for Accessibility

For accessibility requirements, use the HighContrast variant:

let cfg = GraphConfig {
    color_scheme: ColorScheme::HighContrast,
    ..Default::default()
};

This palette selects colors optimized for screen readers and low-vision displays, as implemented in the color resolution logic within src/visualization/utils.rs.

Summary

  • Theme configuration centers on the ColorScheme enum in src/visualization/styles.rs, supporting both built-in palettes and custom color vectors.
  • GraphConfig in src/visualization/config.rs binds themes to specific plots through the color_scheme field.
  • Color resolution occurs in src/visualization/utils.rs via pick_color, which cycles through palette indices for each trace.
  • Trace-level overrides take precedence over themes when line_color is explicitly set on Series2D instances.
  • Accessibility is supported through the HighContrast theme variant.

Frequently Asked Questions

How do I define a custom color palette with specific hex codes?

Create a Vec<String> containing your hex codes, rgb values, or CSS color names, then pass it to ColorScheme::Custom when constructing your GraphConfig. The pick_color function in src/visualization/utils.rs automatically cycles through these colors for each trace in your plot.

Can I use different themes for different traces in the same plot?

While you cannot assign different ColorScheme variants to individual traces directly, you can achieve mixed styling by setting explicit line_color values on specific Series2D instances while allowing other traces to inherit colors from the global ColorScheme defined in GraphConfig.

What built-in themes are available besides custom palettes?

The ColorScheme enum in src/visualization/styles.rs provides Default, Viridis, Plasma, White, and HighContrast. The HighContrast option is specifically designed for accessibility, using colors that remain distinguishable for users with low vision or color blindness.

Where is the theme actually applied to the Plotly traces?

Theme application occurs in src/visualization/plotly.rs within the to_plot method implementation of the Graph trait. This method iterates through traces and calls pick_color from src/visualization/utils.rs for any trace lacking an explicit color, thereby applying the ColorScheme defined in the configuration.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →