plotly/Plotly.NET
65.9
Adequate · 23 September 2026
59.8k
lines of production code
F#
with C#
5
measurements over time
What this system is
Plotly.NET is a .NET library that generates interactive Plotly.js charts and static images from F\# and C\# code. It provides a comprehensive API for creating diverse visualizations, including 2D, 3D, statistical, and geographic plots, with support for global theming and layout customization. The system integrates with .NET Interactive notebooks for inline display and includes headless browser rendering for exporting charts to PNG, JPG, or SVG formats.
How it got here
2016–2021 — Plotly.NET modernization and API expansion
22 changes.
The project underwent a major architectural overhaul, migrating from legacy F\# scaffolding to a modern .NET 10 monorepo with FAKE-based build pipelines. This period focused on restructuring the codebase into modular components, introducing statically typed abstractions for layouts, traces, and configurations, and adding new features like interactive notebook support and image export capabilities.
2022–2023 — Build migration and test expansion
17 changes.
The project migrated its build infrastructure to a modular FAKE-based pipeline and introduced C\# interop support with custom extension methods and an Optional type. This period also focused heavily on expanding test coverage, adding comprehensive validation for chart serialization, HTML generation, and new Plotly.js features across both F\# and C\# environments.
2024–2026 — AI-assisted development and test infrastructure
9 changes.
This period focused on establishing a robust infrastructure for AI-assisted development, including a dedicated devcontainer environment and specialized agent skills for generating chart test baselines. Significant effort was also directed toward expanding test coverage for interactive features, C\# HTML code generation, and various charting capabilities, alongside refactoring the C\# Chart API for improved maintainability.
Features
Add .NET Interactive kernel extension for inline Plotly chart display
The Plotly.NET.Interactive package now includes a kernel extension that automatically registers a formatter for GenericChart objects in .NET Interactive notebooks. When a chart is rendered, it is converted to HTML that embeds the Plotly.js library via RequireJS from a CDN, ensuring charts display correctly without requiring local asset files. This change also drops strong naming from the assemblies, which may require users to update their project references if they rely on strong-named dependencies.
src/Plotly.NET.Interactive · high confidence
Add Smith subplot layout objects
New layout abstractions for the Smith subplot have been added, including the \Smith\ container and its \RealAxis\ and \ImaginaryAxis\ components. These objects allow users to configure subplot properties such as background color and domain, as well as detailed axis styling including grid dash styles, tick formatting, and label aliasing.
src/Plotly.NET/Layout/ObjectAbstractions/Smith · high confidence
Add Ternary layout object abstraction
Introduces a new \Ternary\ type in the layout object abstractions, enabling users to configure ternary subplot layouts. This object supports setting the A, B, and C axes (via \LinearAxis\), defining the domain, specifying the sum for triplets, and customizing the background color, providing the underlying structure for ternary plots.
src/Plotly.NET/Layout/ObjectAbstractions/Ternary · high confidence
Add global chart templates and colorways
Introduces a new theming system allowing users to apply predefined visual styles to their charts. The library now includes built-in templates such as 'light', 'dark', 'fslab', 'plotly', and 'transparent', each defining specific background colors, axis styles, and font settings. Additionally, the 'fslab' template provides a custom colorway palette, and users can create or modify templates to control default layout and trace appearances globally.
src/Plotly.NET/Templates · high confidence
Add layout slider configuration support
Users can now configure layout sliders in Plotly.NET figures. This change introduces new types—\Slider\, \SliderStep\, and \SliderCurrentValue\—which allow setting visual properties (such as colors, fonts, padding, and tick dimensions), defining step behaviors (including labels, values, and API methods), and customizing the display of the currently selected value (including prefix/suffix and visibility).
src/Plotly.NET/Layout/ObjectAbstractions/Common/Slider · high confidence
Added F\# notebook examples for box/violin and scatterplot matrix charts
New interactive notebooks have been added to the publication example charts directory to demonstrate statistical visualization capabilities using F\# and Plotly.NET. The BoxPlot notebook shows how to create standard, notched, and combined box-and-violin plots to analyze data distributions, while the Splom notebook demonstrates scatterplot matrices for exploring pairwise relationships in the Iris dataset using Deedle for data handling.
publication · high confidence
Expanded trace object abstractions with new chart types and parameter coverage
The object abstractions in the Traces layer have been significantly expanded to support new chart types and improve parameter coverage for existing ones. New types include Bins, Box, Caps, Contours, Cumulative, Dimensions, Error, FinanceMarker, FunnelConnector, Gradient, Icicle (with Root, Leaf, and Tiling sub-types), Indicator (with Symbol, Delta, Number, Bar, and Step sub-types), Lighting, and LightPosition. The Marker abstraction has been reworked to include additional properties such as Angle, AngleRef, CornerRadius, StandOff, and MultiSize variants, aligning with recent Plotly.js updates. These changes provide users with more granular control over trace styling and enable the creation of more complex visualizations like Icicle and Indicator charts.
src/Plotly.NET/Traces/ObjectAbstractions · high confidence
Introduce C\# extension methods and custom Optional type for Plotly.NET charts
The Plotly.NET.CSharp package now provides a set of C\# extension methods (GenericChartExtensions) for fluid-style chart styling and creation, including methods to get layout/traces, save HTML, show charts, and configure X/Y axis styles. To support the underlying F\# API's handling of optional parameters with generic constraints, a custom Optional\<T\> record struct is introduced, allowing both reference and value types to be passed as optional arguments while correctly distinguishing between unset and default values. This change also includes internal utilities for type formatting and tuple conversion to facilitate the C\# interop.
src/Plotly.NET.CSharp · high confidence
Introduce Plotly.NET.ImageExport with PuppeteerSharp rendering and scale support
The new Plotly.NET.ImageExport package enables converting charts to static images (PNG, JPG, SVG) using a headless Chromium browser via PuppeteerSharp. Users can export charts to base64 strings or save them directly to disk, specifying width, height, and a new scale factor to control resolution. The library includes an AsyncHelper to prevent deadlocks in synchronous contexts and allows configuring the browser executable path and navigation timeouts.
src/Plotly.NET.ImageExport · high confidence
Layout object now supports persistent selections and new shape styling
The Layout object in Plotly.NET has been updated to support persistent and editable selections over cartesian subplots, exposing \ActiveSelection\, \NewSelection\, and \Selections\ properties that allow users to maintain selection state across plot updates. Additionally, the layout now includes \NewShape\ and \ActiveShape\ properties to control the behavior and styling of newly drawn shapes, enhancing the interactivity and customization of user annotations.
src/Plotly.NET/Layout · high confidence
New agent skill for generating chart test baselines
Added a new 'chart-baseline-generation' skill and its supporting script to help agents create accurate test expectations for Plotly.NET charts. This tooling allows agents to generate real chart output (HTML, data, layout) and extract stable segments for assertions, replacing the need to manually write or guess expected strings. It includes a configuration file granting permissions to run necessary build and test commands.
.claude · high confidence
New chart baseline generation skill for test fixtures
Added a new Codex skill, 'chart-baseline-generation', which provides agents with a standardized workflow for generating and refreshing expected chart output values in Plotly.NET tests. This skill centralizes the use of a specific F\# script to extract stable data, layout, and HTML segments from actual chart rendering, ensuring that test assertions are based on real output rather than hand-written strings, and supports both F\# core tests and C\# wrapper tests.
.codex · high confidence
New chart baseline generation tooling for test maintenance
Added a centralized workflow and script (\tools/chart-baseline-generation/generate-chart-markup.fsx\) to help maintainers generate test baselines from actual chart rendering output. This tool loads the necessary Plotly.NET assemblies, renders a chart to HTML, and extracts stable sections (data, layout, config, or plotly-call) to be copied into tests, reducing reliance on hand-written expected strings. The change includes the main F\# script, a README with usage instructions, and an opencode skill definition to guide the workflow.
.opencode, tools · high confidence
New common abstractions for Plotly.NET configuration and styling
This change introduces a suite of new types in the CommonAbstractions module to support Plotly.js features and improve type safety. It adds a statically typed \Color\ and \ARGB\ representation (replacing raw strings) along with \ColorKeyword\ for standard web colors. New layout and trace configuration objects are provided, including \AutoRangeOptions\ for axis scaling, \ColorBar\ for color axis styling, \EncodedTypedArray\ for efficient base64-encoded data payloads (supporting plotly.js \>= 2.28.0), and \Padding\ for layout spacing. Additionally, \Line\ and \Font\ objects are introduced to allow structured styling of plot lines and text elements.
src/Plotly.NET/CommonAbstractions · high confidence
New configuration abstractions for chart edits and image export options
The library introduces new object abstractions in the Config module to provide structured configuration for interactive chart edits and image export settings. The new Edits type allows users to control which chart elements are editable, including annotations (position, tail, text), axis titles, colorbars, legends, shapes, and the global title. Additionally, the ToImageButtonOptions type enables configuration of export parameters such as image format, filename, width, height, and scale, giving users finer control over how charts are saved as images.
src/Plotly.NET/Config/ObjectAbstractions · high confidence
New devcontainer environment for agent-assisted development
Developers can now use a pre-configured VS Code devcontainer to work in an isolated sandbox that includes the .NET 10 SDK, Node.js, and GitHub CLI. The environment is specifically set up for AI agent workflows, automatically installing and configuring the Claude Code, Codex, and OpenCode CLI tools with permission-skipping flags to facilitate seamless interaction within the container. It also includes necessary system dependencies for running Plotly.NET tests and mounts local AI configuration directories for persistent agent settings.
.devcontainer · high confidence
New object abstractions for 3D scene layout and camera configuration
This change introduces dedicated type abstractions for configuring 3D scenes in Plotly.NET, located in the \src/Plotly.NET/Layout/ObjectAbstractions/3D\ directory. It adds \AspectRatio\, \Camera\ (including nested \CameraCenter\, \CameraEye\, \CameraUp\, and \CameraProjection\ types), and \Scene\ objects. These types provide a structured API for setting 3D layout properties such as aspect ratios, camera positioning, and axis assignments (X, Y, Z) via \init\ and \style\ methods, replacing previous ad-hoc or dynamic object usage for these specific 3D layout components.
src/Plotly.NET/Layout/ObjectAbstractions/3D · high confidence
New typed abstractions for Geo and Mapbox layout configurations
This change introduces a new set of statically typed F\# classes in the \Plotly.NET.LayoutObjects\ namespace to configure map layouts, replacing the previous dynamic object approach. The diff adds \Geo\ and \GeoProjection\ (including \GeoProjectionRotation\) for standard geographic traces, allowing users to control projection types, map rotation, and geographic features like coastlines, land, and countries. It also adds \Mapbox\, \MapboxBounds\, \MapboxCluster\, \MapboxLayer\, and \MapboxLayerSymbol\ for Mapbox-based traces, enabling configuration of map styles, access tokens, view bounds, point clustering, and custom layer symbols. These types provide a structured API for setting properties such as center coordinates, zoom levels, bearing, pitch, and layer visibility.
src/Plotly.NET/Layout/ObjectAbstractions/Map · high confidence
Removals
Removal of legacy scaffolding and template files
The src/FSharp.Plotly directory has been cleaned of default scaffolding artifacts, including App.config, AssemblyInfo.fs, Library.fs, Script.fsx, and Paket configuration files (paket.references, paket.template). This removes the initial template structure and associated build/runtime configuration files that were part of the project's early setup.
src/FSharp.Plotly · high confidence
Architecture
C\# Chart API methods are split into individual files
The C\# Chart API implementation in \src/Plotly.NET.CSharp/ChartAPI\ has been reorganized from a monolithic structure into a one-method-per-file layout. This change extracts specific charting capabilities—such as \Combine\, \Grid\, \Invisible\, \SingleStack\, \AnnotatedHeatmap\, \Area\, \Bar\, \BoxPlot\, \Bubble\, \Candlestick\, and \Column\—into their own dedicated source files (e.g., \Chart/Combine.cs\, \Chart2D/Bar.cs\). For users, this maintains the existing public API surface but improves code maintainability and navigation by isolating each chart type's logic into its own file.
src/Plotly.NET.CSharp/ChartAPI · high confidence
Chart API restructured into modular 2D chart files
The Chart API implementation has been reorganized from a single monolithic file into separate, modular source files for each 2D chart type (e.g., Area, Bar, Distribution, Finance). This change improves code maintainability and clarity by isolating the creation and styling logic for specific chart types like OHLC, Box Plot, and Bar charts into their own dedicated modules while preserving the existing public API surface.
src/Plotly.NET/ChartAPI · high confidence
Repository restructured and renamed to Plotly.NET with modernized tooling
The project has been renamed from FSharp.Plotly to Plotly.NET and restructured into a monorepo containing core F\# and idiomatic C\# packages, interactive notebook extensions, and image export capabilities. The build system has migrated from the legacy ProjectScaffold (paket/build.fsx) to a FAKE-based pipeline targeting .NET 10, and the library now bundles plotly.js v2.28.0. Legacy CI configurations (Travis, AppVeyor) and the old solution file have been removed in favor of GitHub Actions, and the repository now includes an .editorconfig for F\# formatting, a CITATION.cff, and a Code of Conduct.
(repo-wide) · high confidence
Behavioural changes
Expand DisplayOptions with document metadata and Plotly.js loading strategies
The DisplayOptions object now supports setting DocumentTitle, DocumentCharset, DocumentDescription, and DocumentFavicon, which are applied to the HTML document head. It also introduces PlotlyJSReference to control how Plotly.js is loaded, offering options to use a CDN, include the full source code for offline use, use RequireJS, or omit the reference entirely. When combining DisplayOptions, these new fields are overwritten by the second object's values, while AdditionalHeadTags and ChartDescription are appended.
src/Plotly.NET/DisplayOptions · high confidence
Expanded Config options for Plotly.js v2.14 and v2.10.0 features
The Config object now exposes new parameters to support recent Plotly.js updates. Users can enable moving selections via the new \EditSelection\ option (added for Plotly.js v2.14) and control MathJax typesetting with \TypesetMath\ (added for Plotly.js v2.10.0). Additionally, the \plot3dPixelRatio\ option has been renamed to \plotGlPixelRatio\ to reflect the underlying library's deprecation of the former name.
src/Plotly.NET/Config · high confidence
Introduce global chart defaults and embed Plotly.js v2.28.0
The library now exposes a \Defaults\ module allowing users to configure global defaults for chart generation, including container dimensions, configuration, display options (such as document title, favicon, and CDN reference), and chart templates, which apply to all subsequently generated charts. Additionally, the bundled Plotly.js library has been updated to version 2.28.0, bringing new features like encoded typed array support and multi-legend capabilities to the generated HTML output.
src/Plotly.NET · high confidence
Migrate build system to FAKE and project-based pipeline
The build infrastructure has been replaced with a new project-based pipeline using FAKE (F\# Make). This change introduces a modular build script structure with dedicated modules for basic tasks, testing, packaging, documentation, and release management. Users can now leverage improved test execution capabilities, including fast incremental test runs that skip the clean step, and more flexible prerelease packaging workflows. The new system also standardizes documentation generation and NuGet publishing processes through explicit build tasks.
build · high confidence
Refactored polar subplot layout with new AngularAxis and RadialAxis abstractions
The polar subplot layout objects have been restructured to use new, statically typed \AngularAxis\ and \RadialAxis\ abstractions. This change introduces dedicated types for configuring angular and radial scales, including support for new Plotly.js features such as \ticklabelstep\, \labelalias\, \griddash\, and \autorange\ options. Users can now configure polar plots with more granular control over axis properties like direction, rotation, period, and tick formatting through these updated object models.
src/Plotly.NET/Layout/ObjectAbstractions/Polar · high confidence
Refactored trace API to use DynObj v4 and added encoded data support
The trace definitions in the Traces module have been refactored to use the DynObj v4 API, replacing the previous dynamic object implementation. This change introduces support for encoded data fields (such as \XEncoded\, \YEncoded\, and \IdsEncoded\) which allow passing base64-encoded typed arrays for improved performance with large datasets. Additionally, the API now includes comprehensive styling options for 2D and 3D traces, including new parameters for legend grouping, alignment, and multi-value support.
src/Plotly.NET/Traces · high confidence
Updated layout object abstractions to support Plotly.js v2.25+ features
The layout object abstractions in the Common module have been updated to reflect changes in Plotly.js v2.25, specifically adding support for persistent and editable selections over cartesian subplots via the new \ActiveSelection\ and \ActiveShape\ types. Additionally, the \Legend\ object now supports multi-legend configurations and new styling options like \EntryWidth\ and \EntryWidthMode\, while \Annotation\ and \Hoverlabel\ objects have been refined to include missing parameters and improved optional argument handling for better C\# interop.
src/Plotly.NET/Layout/ObjectAbstractions/Common · high confidence
Test coverage
Added C\# HTML codegen tests for 2D, 3D, and layout chart types; Added C\# console test application for chart generation; Added C\# test utilities for validating Plotly chart HTML output; Added F\# console test app for encoded charts and set visualizations; Added F\# test utilities and data generation helpers; Added JSON generation tests for 2D charts; Added empty test base and placeholder directories; Added interactive test infrastructure for Plotly.NET; Added test coverage for Plotly.js 2.19 through 2.28 upstream features; Added tests for Config, Layout, LinearAxis, and Slider serialization; Added tests for DisplayOptions API and combination logic; Added tests for chart combination, axis styling, color serialization, and encoded typed arrays; Added tests for contour accessibility, 3D grid positioning, hover info, subplot titles, and update menu args; Added tests for image export functionality; Added tests for interactive formatting conventions; Consolidated test chart definitions in FSharpTestBase; Expanded HTML code generation test coverage for 2D, 3D, and domain-specific charts; Removed legacy test infrastructure and dependencies.
Dependencies
Migrate build system to .NET SDK and NuGet, dropping Paket
The project has replaced the legacy Paket dependency manager with standard .NET SDK-style project files and NuGet. This migration removes the old F\# 4.0-based FSharp.Plotly project and its associated Paket lock files, replacing them with modern .NET 10.0 targets for the build infrastructure, C\# bindings, and test suites. The core Plotly.NET library and the ImageExport extension now target netstandard2.0, while the Interactive kernel extension targets netstandard2.1. Key dependencies have been updated to their latest versions, including PuppeteerSharp (24.40.0) for image rendering, Microsoft.DotNet.Interactive (1.0.0-beta.26120.1) for notebook support, and test frameworks like Expecto (10.\*) and Deedle (5.0.0).
(dependencies) · high confidence
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
How this codebase got here
Score
- CAI 60 → 66 (+5.7)
- Rubric changed (rubric-2026.08.19 → rubric-2026.09.15) — scores are not directly comparable.
Lenses
- Code Health 96 → 96 (-0.2)
- Architecture 77 → 100 (+22.9)
- Maturity 53 → 53 (+0.2)
- Readiness 50 → 58 (+8.6)
- Security 100 → 97 (-2.6)
Resolved (379)
- Dependency hygiene not measured — no packages were read
- Duplicated block (10 lines × 17) (src/Plotly.NET/Traces/Trace2D.fs)
- Duplicated block (10 lines × 2) (src/Plotly.NET/ChartAPI/Chart2D/Chart2D_Heatmap.fs)
- Duplicated block (10 lines × 2) (src/Plotly.NET/ChartAPI/Chart3D/Chart3D_VectorField.fs)
- Duplicated block (10 lines × 2) (src/Plotly.NET/ChartAPI/ChartCarpet/ChartCarpet_Scatter.fs)
- Duplicated block (10 lines × 2) (src/Plotly.NET/ChartAPI/ChartCarpet/ChartCarpet_Scatter.fs)
- Duplicated block (10 lines × 2) (src/Plotly.NET/ChartAPI/ChartCarpet/ChartCarpet_Scatter.fs)
- Duplicated block (10 lines × 2) (src/Plotly.NET/ChartAPI/ChartCarpet/ChartCarpet_Scatter.fs)
- Duplicated block (10 lines × 2) (src/Plotly.NET/ChartAPI/ChartDomain/ChartDomain_Pie.fs)
- Duplicated block (10 lines × 2) (src/Plotly.NET/ChartAPI/ChartTernary/ChartTernary_Scatter.fs)
- Duplicated block (10 lines × 2) (src/Plotly.NET/Layout/ObjectAbstractions/Polar/AngularAxis.fs)
- Duplicated block (10 lines × 2) (src/Plotly.NET/Layout/ObjectAbstractions/Smith/ImaginaryAxis.fs)
- Duplicated block (10 lines × 2) (src/Plotly.NET/Templates/ChartTemplates.fs)
- Duplicated block (10 lines × 2) (src/Plotly.NET/Traces/ObjectAbstractions/Sankey.fs)
- Duplicated block (10 lines × 2) (src/Plotly.NET/Traces/ObjectAbstractions/Table.fs)
- Duplicated block (10 lines × 2) (src/Plotly.NET/Traces/Trace2D.fs)
- Duplicated block (10 lines × 2) (src/Plotly.NET/Traces/Trace2D.fs)
- Duplicated block (10 lines × 2) (src/Plotly.NET/Traces/Trace2D.fs)
- Duplicated block (10 lines × 2) (src/Plotly.NET/Traces/Trace2D.fs)
- Duplicated block (10 lines × 2) (src/Plotly.NET/Traces/Trace2D.fs)
- …and 359 more
New (458)
- Documentation: no usage examples (README.md)
- Duplicated block (10 lines × 11) (src/Plotly.NET/Traces/Trace2D.fs)
- Duplicated block (10 lines × 11) (src/Plotly.NET/Traces/Trace2D.fs)
- Duplicated block (10 lines × 120) (src/Plotly.NET/ChartAPI/Chart2D/Chart2D_Area.fs)
- Duplicated block (10 lines × 13) (src/Plotly.NET/Traces/Trace2D.fs)
- Duplicated block (10 lines × 2) (src/Plotly.NET/ChartAPI/ChartDomain/ChartDomain_Hierarchy.fs)
- Duplicated block (10 lines × 2) (src/Plotly.NET/Layout/ObjectAbstractions/Smith/ImaginaryAxis.fs)
- Duplicated block (10 lines × 2) (src/Plotly.NET/Traces/Trace2D.fs)
- Duplicated block (10 lines × 2) (src/Plotly.NET/Traces/Trace2D.fs)
- Duplicated block (10 lines × 3) (src/Plotly.NET/ChartAPI/Chart2D/Chart2D_Heatmap.fs)
- Duplicated block (10 lines × 3) (src/Plotly.NET/Traces/Trace3D.fs)
- Duplicated block (10 lines × 3) (src/Plotly.NET/Traces/TraceDomain.fs)
- Duplicated block (10 lines × 4) (src/Plotly.NET/ChartAPI/ChartCarpet/ChartCarpet_Scatter.fs)
- Duplicated block (10 lines × 4) (src/Plotly.NET/Traces/Trace2D.fs)
- Duplicated block (10 lines × 6) (src/Plotly.NET/Traces/Trace2D.fs)
- Duplicated block (10 lines × 6) (src/Plotly.NET/Traces/Trace2D.fs)
- Duplicated block (10 lines × 6) (src/Plotly.NET/Traces/Trace3D.fs)
- Duplicated block (10 lines × 8) (src/Plotly.NET/Traces/Trace2D.fs)
- Duplicated block (10 lines × 99) (src/Plotly.NET/ChartAPI/Chart2D/Chart2D_Area.fs)
- Duplicated block (10–11 lines × 17) (src/Plotly.NET/Traces/Trace2D.fs)
- …and 438 more
Changes since last survey
- 6 commits — 6 feature/other, 0 fixes
By area
- (repo) — 4 commits
- (root) — 1 commit
- plans/CSharpChartApiFileSplit.md — 1 commit
Notable commits
- change: Clarify encoded array plan and record merge verification
- change: Complete scoped plotly.js 2.28 documentation and validation
- change: Merge dev into C#-refactor
- change: Merge dev into plotly2.28 and preserve split C# wrappers
- change: Merge pull request #502 from plotly/plotly2.28
- change: Merge pull request #503 from plotly/C#-refactor
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
Survey your own repository
plotly/Plotly.NET was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.
About this page
- The score is its most recent published measurement, taken on 23 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
- Measured at commit 6ba0bde4390531805dec8e427f14c16d956d0776 — the exact code this score is about.
- Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
- Measured by watchdog.canine.dev using codehealth-analyzer preprod-955b9cee9818.