# Matplotlib Themes > **These themes give a chart the matplotlib look in pure .NET, with no other changes needed. No Python runtime is required.** The two themes mimic matplotlib's visual style: the pre-2.0 *classic* look and the modern *v2.0+* default. [MatPlotLibNet](https://github.com/xkqg/MatPlotLibNet) renders both entirely on its own. --- ## `Theme.MatplotlibClassic` — the pre-2.0 look This theme uses a white background, the `bgrcmyk` 7-color cycle, DejaVu Sans at 12pt, and a grid that is hidden by default. The grid is hidden because matplotlib ships with `plt.grid(False)`; users turn it on themselves. ```csharp using MatPlotLibNet; using MatPlotLibNet.Styling; double[] x = [0, 1, 2, 3, 4, 5]; double[] y1 = [0, 1, 4, 9, 16, 25]; double[] y2 = [0, 2, 4, 6, 8, 10]; Plt.Create() .WithTheme(Theme.MatplotlibClassic) .WithTitle("Classic matplotlib look") .Plot(x, y1, s => s.Label = "Quadratic") .Plot(x, y2, s => s.Label = "Linear") .WithLegend() .Save("classic.svg"); ``` ### Color cycle — `bgrcmyk` | # | Hex | Name | |---|-----------|---------| | 0 | `#0000FF` | blue | | 1 | `#008000` | green | | 2 | `#FF0000` | red | | 3 | `#00BFBF` | cyan | | 4 | `#BF00BF` | magenta | | 5 | `#BFBF00` | yellow | | 6 | `#000000` | black | ### At a glance | Property | Value | |---------------------|--------------------------------------------------| | Background | `#FFFFFF` (white) | | Axes background | `#FFFFFF` (white) | | Foreground text | `#000000` (pure black) | | Font family | `DejaVu Sans, Bitstream Vera Sans, sans-serif` | | Font size | `12.0pt` | | Grid | hidden by default (`Visible = false`) | | Cycle length | 7 colors | --- ## `Theme.MatplotlibV2` — the modern default This theme uses a white background, soft-black `#262626` text, the modern `tab10` 10-color cycle, DejaVu Sans at 10pt, and a grid that is hidden by default. Matplotlib v2 softened pure black to this soft black on purpose. ```csharp Plt.Create() .WithTheme(Theme.MatplotlibV2) .WithTitle("Modern matplotlib look") .Plot(x, y1, s => s.Label = "Quadratic") .Plot(x, y2, s => s.Label = "Linear") .WithLegend() .Save("v2.svg"); ``` ### Color cycle — `tab10` | # | Hex | Name | |----|-----------|---------| | 0 | `#1f77b4` | blue | | 1 | `#ff7f0e` | orange | | 2 | `#2ca02c` | green | | 3 | `#d62728` | red | | 4 | `#9467bd` | purple | | 5 | `#8c564b` | brown | | 6 | `#e377c2` | pink | | 7 | `#7f7f7f` | gray | | 8 | `#bcbd22` | olive | | 9 | `#17becf` | cyan | ### At a glance | Property | Value | |---------------------|-----------------------------------------| | Background | `#FFFFFF` (white) | | Axes background | `#FFFFFF` (white) | | Foreground text | `#262626` (soft black) | | Font family | `DejaVu Sans, sans-serif` | | Font size | `10.0pt` | | Grid | hidden by default (`Visible = false`) | | Cycle length | 10 colors | --- ## Opting into a grid Both themes ship with the grid **off**, matching matplotlib's `plt.grid(False)` default. ```csharp Plt.Create() .WithTheme(Theme.MatplotlibV2) .AddSubPlot(1, 1, 1, ax => ax .Plot(x, y) .ShowGrid(true)) // simple toggle .Save("v2_with_grid.svg"); ``` Or override the theme grid via `ThemeBuilder`: ```csharp var v2WithGrid = Theme.CreateFrom(Theme.MatplotlibV2) .WithGrid(g => g with { Visible = true, Color = Color.FromHex("#B0B0B0") }) .Build(); ``` --- ## Comparison | Aspect | `MatplotlibClassic` | `MatplotlibV2` | `Theme.Default` | |------------------|---------------------|-----------------------|-----------------| | Era mimicked | matplotlib < 2.0 | matplotlib 2.0+ | none specifically | | Cycle | `bgrcmyk` (7) | `tab10` (10) | `tab10` (10) | | Foreground text | pure black | soft black `#262626` | pure black | | Font size | 12pt | 10pt | 13pt (default) | | Grid default | off | off | **on** | | Use case | retro / classic | modern Jupyter look | MatPlotLibNet's own default | `Theme.Default` already uses `tab10`. Choose `MatplotlibV2` when you want the full matplotlib look: it has a different font stack, soft-black text, and a grid that is hidden by default. --- ## Community Themes There are six community themes. Each has its own palette, font, size, and grid defaults. Applying one visibly changes the chart; no other API calls are needed. | Theme | Palette | Font | Size | Grid | |---|---|---|---|---| | `Theme.Grayscale` | grayscale cycle (no hues) | default | default | default | | `Theme.Paper` | default | serif | 11pt | **off** | | `Theme.Presentation` | default | bold | 16pt | default | | `Theme.Poster` | default | bold | 20pt | on, **1.5 linewidth** | | `Theme.GitHub` | GitHub brand palette | default | default | `#E1E4E8` | | `Theme.Minimal` | default | default | 11pt | **off** | Use them the same way: `Plt.Create().WithTheme(Theme.Paper)…`. Contract tests check that each theme produces byte-distinct output, so a theme that collapses back to `Default` fails CI. --- ## Pixel-verified against matplotlib Every chart with a matplotlib equivalent is verified against a pinned matplotlib (3.10.8) reference PNG **under both themes**. The fidelity suite runs **146 tests** (73 fixtures × 2 themes): ```bash # regenerate reference PNGs (developers only — not run in CI) pip install -r tools/mpl_reference/requirements.txt python tools/mpl_reference/generate.py --all --style both # run the dual-theme fidelity tests dotnet run --project Tst/MatPlotLibNet.Fidelity/MatPlotLibNet.Fidelity.Tests.csproj ``` Each test renders one MatPlotLibNet figure, exports to PNG via the SkiaSharp backend, and compares against the matplotlib reference using three metrics: **RMS** pixel error, **block SSIM**, and **MaxColorDeltaE** (CIE ΔE\*76 across the 5 dominant colours). Failures emit a 3-panel side-by-side diff PNG (reference | actual | abs-difference heatmap) under `bin/Debug/net10.0/fidelity-failures/{theme}_{name}.diff.png`. Coverage: the **73 fixtures** are 12 core fixtures (line, scatter, bar, hist, pie, box, violin, heatmap, contour, polar, candlestick, errorbar), 45 Phase 5 fixtures (XY, grid, field, polar, categorical, distribution, 3D, financial, special), 15 Phase 6 fixtures (`pandas_ta` technical indicators), and 1 composition fixture (a multi-subplot suptitle, mathtext labels, and a mathtext legend). The v2 fixtures use `plt.style.context('default')`, which is matplotlib's modern default (tab10 cycle, DejaVu Sans 10pt, soft-black `#262626` foreground). This is the look that `Theme.MatplotlibV2` reproduces. --- ## Implementation notes An internal `MatplotlibThemeFactory` builds both themes through a shared `Build(...)` helper, so the two themes differ only where they have to: color cycle, font size, and foreground text. The font stack is a `record struct` (`MatplotlibFontStack`). It has named fields with value equality; it is not a positional tuple. --- ## See also - [[Styling]] — themes, colormaps, PropCycler, custom themes - [[Accessibility]] — `Theme.ColorBlindSafe`, `Theme.HighContrast` - [Source](https://github.com/xkqg/MatPlotLibNet/blob/main/Src/MatPlotLibNet/Styling/Themes/MatplotlibThemeFactory.cs)