BinderNotebook

Static image export

Table of contents

As Plotly.NET generates static html pages that contain charts rendered by plotly.js, static image export needs a lot more overhead under the hood than you might expect. The underlying renderer needs to execute javascript, leading to the usage of headless browsers.

The package Plotly.NET.ImageExport contains extensions for Plotly.NET to render static images. It is designed with extensibility in mind and it is very easy to add a new rendering engine. The current engines are provided:

Rendering engine

Type

Prerequisites

PuppeteerSharp

headless browser

read more here

Saving static images

By referencing the Plotly.NET.ImageExport package, you get access to:

  • jpg via Chart.SaveJPG
  • png via Chart.SavePNG
  • svg via Chart.SaveSVG

(and Extensions for C# style fluent interfaces by opening the GenericChartExtensions namespace)

The parameters for all three functions are exactly the same.

open Plotly.NET
open Plotly.NET.ImageExport

let exampleChart =
    Chart.Histogram2DContour([ 1.; 2.; 2.; 4.; 5. ], [ 1.; 2.; 2.; 4.; 5. ])
exampleChart
|> Chart.saveJPG ("/your/path/without/extension/here", Width = 300, Height = 300)

Generating URIs for static chart images

By referencing the Plotly.NET.ImageExport package, you get access to:

  • jpg via Chart.toBase64JPGString
  • png via Chart.toBase64PNGString
  • svg via Chart.toSVGString

(and Extensions for C# style fluent interfaces by opening the GenericChartExtensions namespace)

let base64JPG = exampleChart |> Chart.toBase64JPGString (Width = 300, Height = 300)

It is very easy to construct a html tag that includes this image via a base64 uri. For SVGs, not even that is necessary and just the SVG string can be used.

$"""<img
    src= "{base64JPG}"
/>"""
namespace Plotly
namespace Plotly.NET
namespace Plotly.NET.ImageExport
val exampleChart: GenericChart.GenericChart
type Chart = static member AnnotatedHeatmap: zData: seq<#seq<'a1>> * annotationText: seq<#seq<string>> * ?Name: string * ?ShowLegend: bool * ?Opacity: float * ?X: seq<'a3> * ?MultiX: seq<seq<'a3>> * ?XGap: int * ?Y: seq<'a4> * ?MultiY: seq<seq<'a4>> * ?YGap: int * ?Text: 'a5 * ?MultiText: seq<'a5> * ?ColorBar: ColorBar * ?ColorScale: Colorscale * ?ShowScale: bool * ?ReverseScale: bool * ?ZSmooth: SmoothAlg * ?Transpose: bool * ?UseWebGL: bool * ?ReverseYAxis: bool * ?UseDefaults: bool -> GenericChart (requires 'a1 :> IConvertible and 'a3 :> IConvertible and 'a4 :> IConvertible and 'a5 :> IConvertible) + 1 overload static member Area: x: seq<#IConvertible> * y: seq<#IConvertible> * ?ShowMarkers: bool * ?Name: string * ?ShowLegend: bool * ?Opacity: float * ?MultiOpacity: seq<float> * ?Text: 'a2 * ?MultiText: seq<'a2> * ?TextPosition: TextPosition * ?MultiTextPosition: seq<TextPosition> * ?MarkerColor: Color * ?MarkerColorScale: Colorscale * ?MarkerOutline: Line * ?MarkerSymbol: MarkerSymbol * ?MultiMarkerSymbol: seq<MarkerSymbol> * ?Marker: Marker * ?LineColor: Color * ?LineColorScale: Colorscale * ?LineWidth: float * ?LineDash: DrawingStyle * ?Line: Line * ?AlignmentGroup: string * ?OffsetGroup: string * ?StackGroup: string * ?Orientation: Orientation * ?GroupNorm: GroupNorm * ?FillColor: Color * ?FillPatternShape: PatternShape * ?FillPattern: Pattern * ?UseWebGL: bool * ?UseDefaults: bool -> GenericChart (requires 'a2 :> IConvertible) + 1 overload static member Bar: values: seq<#IConvertible> * ?Keys: seq<'a1> * ?MultiKeys: seq<seq<'a1>> * ?Name: string * ?ShowLegend: bool * ?Opacity: float * ?MultiOpacity: seq<float> * ?Text: 'a2 * ?MultiText: seq<'a2> * ?MarkerColor: Color * ?MarkerColorScale: Colorscale * ?MarkerOutline: Line * ?MarkerPatternShape: PatternShape * ?MultiMarkerPatternShape: seq<PatternShape> * ?MarkerPattern: Pattern * ?Marker: Marker * ?Base: #IConvertible * ?Width: 'a4 * ?MultiWidth: seq<'a4> * ?TextPosition: TextPosition * ?MultiTextPosition: seq<TextPosition> * ?UseDefaults: bool -> GenericChart (requires 'a1 :> IConvertible and 'a2 :> IConvertible and 'a4 :> IConvertible) + 1 overload static member BoxPlot: ?X: seq<'a0> * ?MultiX: seq<seq<'a0>> * ?Y: seq<'a1> * ?MultiY: seq<seq<'a1>> * ?Name: string * ?ShowLegend: bool * ?Text: 'a2 * ?MultiText: seq<'a2> * ?FillColor: Color * ?MarkerColor: Color * ?Marker: Marker * ?Opacity: float * ?WhiskerWidth: float * ?BoxPoints: BoxPoints * ?BoxMean: BoxMean * ?Jitter: float * ?PointPos: float * ?Orientation: Orientation * ?OutlineColor: Color * ?OutlineWidth: float * ?Outline: Line * ?AlignmentGroup: string * ?OffsetGroup: string * ?Notched: bool * ?NotchWidth: float * ?QuartileMethod: QuartileMethod * ?UseDefaults: bool -> GenericChart (requires 'a0 :> IConvertible and 'a1 :> IConvertible and 'a2 :> IConvertible) + 2 overloads static member Bubble: x: seq<#IConvertible> * y: seq<#IConvertible> * sizes: seq<int> * ?Name: string * ?ShowLegend: bool * ?Opacity: float * ?MultiOpacity: seq<float> * ?Text: 'a2 * ?MultiText: seq<'a2> * ?TextPosition: TextPosition * ?MultiTextPosition: seq<TextPosition> * ?MarkerColor: Color * ?MarkerColorScale: Colorscale * ?MarkerOutline: Line * ?MarkerSymbol: MarkerSymbol * ?MultiMarkerSymbol: seq<MarkerSymbol> * ?Marker: Marker * ?LineColor: Color * ?LineColorScale: Colorscale * ?LineWidth: float * ?LineDash: DrawingStyle * ?Line: Line * ?AlignmentGroup: string * ?OffsetGroup: string * ?StackGroup: string * ?Orientation: Orientation * ?GroupNorm: GroupNorm * ?UseWebGL: bool * ?UseDefaults: bool -> GenericChart (requires 'a2 :> IConvertible) + 1 overload static member Candlestick: ``open`` : seq<#IConvertible> * high: seq<#IConvertible> * low: seq<#IConvertible> * close: seq<#IConvertible> * ?X: seq<'a4> * ?MultiX: seq<seq<'a4>> * ?Name: string * ?ShowLegend: bool * ?Opacity: float * ?Text: 'a5 * ?MultiText: seq<'a5> * ?Line: Line * ?IncreasingColor: Color * ?Increasing: FinanceMarker * ?DecreasingColor: Color * ?Decreasing: FinanceMarker * ?WhiskerWidth: float * ?ShowXAxisRangeSlider: bool * ?UseDefaults: bool -> GenericChart (requires 'a4 :> IConvertible and 'a5 :> IConvertible) + 2 overloads static member Column: values: seq<#IConvertible> * ?Keys: seq<'a1> * ?MultiKeys: seq<seq<'a1>> * ?Name: string * ?ShowLegend: bool * ?Opacity: float * ?MultiOpacity: seq<float> * ?Text: 'a2 * ?MultiText: seq<'a2> * ?MarkerColor: Color * ?MarkerColorScale: Colorscale * ?MarkerOutline: Line * ?MarkerPatternShape: PatternShape * ?MultiMarkerPatternShape: seq<PatternShape> * ?MarkerPattern: Pattern * ?Marker: Marker * ?Base: #IConvertible * ?Width: 'a4 * ?MultiWidth: seq<'a4> * ?TextPosition: TextPosition * ?MultiTextPosition: seq<TextPosition> * ?UseDefaults: bool -> GenericChart (requires 'a1 :> IConvertible and 'a2 :> IConvertible and 'a4 :> IConvertible) + 1 overload static member Contour: zData: seq<#seq<'a1>> * ?Name: string * ?ShowLegend: bool * ?Opacity: float * ?X: seq<'a2> * ?MultiX: seq<seq<'a2>> * ?Y: seq<'a3> * ?MultiY: seq<seq<'a3>> * ?Text: 'a4 * ?MultiText: seq<'a4> * ?ColorBar: ColorBar * ?ColorScale: Colorscale * ?ShowScale: bool * ?ReverseScale: bool * ?Transpose: bool * ?ContourLineColor: Color * ?ContourLineDash: DrawingStyle * ?ContourLineSmoothing: float * ?ContourLine: Line * ?ContoursColoring: ContourColoring * ?ContoursOperation: ConstraintOperation * ?ContoursType: ContourType * ?ShowContourLabels: bool * ?ContourLabelFont: Font * ?Contours: Contours * ?FillColor: Color * ?NContours: int * ?UseDefaults: bool -> GenericChart (requires 'a1 :> IConvertible and 'a2 :> IConvertible and 'a3 :> IConvertible and 'a4 :> IConvertible) static member Funnel: x: seq<#IConvertible> * y: seq<#IConvertible> * ?Name: string * ?ShowLegend: bool * ?Opacity: float * ?Width: float * ?Offset: float * ?Text: 'a2 * ?MultiText: seq<'a2> * ?TextPosition: TextPosition * ?MultiTextPosition: seq<TextPosition> * ?Orientation: Orientation * ?AlignmentGroup: string * ?OffsetGroup: string * ?MarkerColor: Color * ?MarkerOutline: Line * ?Marker: Marker * ?TextInfo: TextInfo * ?ConnectorLineColor: Color * ?ConnectorLineStyle: DrawingStyle * ?ConnectorFillColor: Color * ?ConnectorLine: Line * ?Connector: FunnelConnector * ?InsideTextFont: Font * ?OutsideTextFont: Font * ?UseDefaults: bool -> GenericChart (requires 'a2 :> IConvertible) static member Heatmap: zData: seq<#seq<'a1>> * ?X: seq<'a2> * ?MultiX: seq<seq<'a2>> * ?Y: seq<'a3> * ?MultiY: seq<seq<'a3>> * ?Name: string * ?ShowLegend: bool * ?Opacity: float * ?XGap: int * ?YGap: int * ?Text: 'a4 * ?MultiText: seq<'a4> * ?ColorBar: ColorBar * ?ColorScale: Colorscale * ?ShowScale: bool * ?ReverseScale: bool * ?ZSmooth: SmoothAlg * ?Transpose: bool * ?UseWebGL: bool * ?ReverseYAxis: bool * ?UseDefaults: bool -> GenericChart (requires 'a1 :> IConvertible and 'a2 :> IConvertible and 'a3 :> IConvertible and 'a4 :> IConvertible) + 1 overload ...
static member Chart.Histogram2DContour: x: seq<#System.IConvertible> * y: seq<#System.IConvertible> * ?Name: string * ?ShowLegend: bool * ?Opacity: float * ?Z: seq<#seq<'d>> * ?HistFunc: StyleParam.HistFunc * ?HistNorm: StyleParam.HistNorm * ?NBinsX: int * ?NBinsY: int * ?BinGroup: string * ?XBinGroup: string * ?XBins: TraceObjects.Bins * ?YBinGroup: string * ?YBins: TraceObjects.Bins * ?Marker: TraceObjects.Marker * ?ContourLineColor: Color * ?ContourLineDash: StyleParam.DrawingStyle * ?ContourLineSmoothing: float * ?ContourLine: Line * ?ColorBar: ColorBar * ?ColorScale: StyleParam.Colorscale * ?ShowScale: bool * ?ReverseScale: bool * ?Contours: TraceObjects.Contours * ?NContours: int * ?UseDefaults: bool -> GenericChart.GenericChart (requires 'd :> System.IConvertible)
static member Chart.Histogram2DContour: ?X: seq<'a0> * ?MultiX: seq<seq<'a0>> * ?Y: seq<'a1> * ?MultiY: seq<seq<'a1>> * ?Name: string * ?ShowLegend: bool * ?Opacity: float * ?Z: seq<#seq<'a3>> * ?HistFunc: StyleParam.HistFunc * ?HistNorm: StyleParam.HistNorm * ?NBinsX: int * ?NBinsY: int * ?BinGroup: string * ?XBinGroup: string * ?XBins: TraceObjects.Bins * ?YBinGroup: string * ?YBins: TraceObjects.Bins * ?Marker: TraceObjects.Marker * ?ContourLineColor: Color * ?ContourLineDash: StyleParam.DrawingStyle * ?ContourLineSmoothing: float * ?ContourLine: Line * ?ColorBar: ColorBar * ?ColorScale: StyleParam.Colorscale * ?ShowScale: bool * ?ReverseScale: bool * ?Contours: TraceObjects.Contours * ?NContours: int * ?UseDefaults: bool -> GenericChart.GenericChart (requires 'a0 :> System.IConvertible and 'a1 :> System.IConvertible and 'a3 :> System.IConvertible)
static member Chart.saveJPG: path: string * ?EngineType: ExportEngine * ?Width: int * ?Height: int -> (GenericChart.GenericChart -> unit)
val base64JPG: string
static member Chart.toBase64JPGString: ?EngineType: ExportEngine * ?Width: int * ?Height: int -> (GenericChart.GenericChart -> string)