3D Volume Plots in F#

How to make 3D Volume plots in F# with Plotly.


Plotly is known for its graphing libraries, but it's also a broader ecosystem for building interactive data apps, AI data analysis tools, and deploying and hosting Dash apps. Explore the full set of tools and platforms designed to help turn data into action. Discover Plotly.

Note: We are retiring documentation for R, MATLAB, Julia, and F#. Learn more about this change here.

In [1]:
#r "nuget: Plotly.NET, 2.0.0-preview.6"
#r "nuget: Plotly.NET.Interactive, 2.0.0-preview.6"
#r "nuget: FSharp.Data"
Installed Packages
  • FSharp.Data, 4.2.4
  • Plotly.NET, 2.0.0-preview.6
  • Plotly.NET.Interactive, 2.0.0-preview.6

Loading extensions from Plotly.NET.Interactive.dll

Added Kernel Extension including formatters for Plotly.NET charts.

Simple volume plot with go.Volume

In [2]:
open System
open Plotly.NET


let N = 50
let rnd = System.Random()

let mirroredXAxis =
    Axis.LinearAxis.init(
        Showspikes = false,
        Backgroundcolor ="rgb(229, 236, 246)",
        Showbackground=true
    )

let mirroredLogYAxis =
    Axis.LinearAxis.init(
        Showspikes = false,
        Backgroundcolor ="rgb(229, 236, 246)",
        Showbackground=true
    )
let mirroredZAxis =
    Axis.LinearAxis.init(
        Showspikes = false,
        Backgroundcolor ="rgb(229, 236, 246)",
        Showbackground=true
    )

let margin =Margin.init(Left =10.0, Bottom=10.0,Top =10.0, Right  = 20.0 )
let layout = Layout.init(Width= 700.,  Margin=margin)

let x = [-8.0;-8.0;-8.0;-8.0;-8.0;-8.0;-8.0;-8.0;-8.0;-8.0;-8.0;-8.0;-8.0;-8.0;-8.0;-8.0;-2.666666666666667;-2.666666666666667;-2.666666666666667;-2.666666666666667;-2.666666666666667;-2.666666666666667;-2.666666666666667;-2.666666666666667;-2.666666666666667;-2.666666666666667;-2.666666666666667;-2.666666666666667;-2.666666666666667;-2.666666666666667;-2.666666666666667;-2.666666666666667;2.666666666666666;2.666666666666666;2.666666666666666;2.666666666666666;2.666666666666666;2.666666666666666;2.666666666666666;2.666666666666666;2.666666666666666;2.666666666666666;2.666666666666666;2.666666666666666;2.666666666666666;2.666666666666666;2.666666666666666;2.666666666666666;8.0;8.0;8.0;8.0;8.0;8.0;8.0;8.0;8.0;8.0;8.0;8.0;8.0;8.0;8.0;8.0]
let y =[-8.0;-8.0;-8.0;-8.0;-8.0;-8.0;-8.0;-8.0;-8.0;-8.0;-8.0;-8.0;-8.0;-8.0;-8.0;-8.0;-2.666666666666667;-2.666666666666667;-2.666666666666667;-2.666666666666667;-2.666666666666667;-2.666666666666667;-2.666666666666667;-2.666666666666667;-2.666666666666667;-2.666666666666667;-2.666666666666667;-2.666666666666667;-2.666666666666667;-2.666666666666667;-2.666666666666667;-2.666666666666667;2.666666666666666;2.666666666666666;2.666666666666666;2.666666666666666;2.666666666666666;2.666666666666666;2.666666666666666;2.666666666666666;2.666666666666666;2.666666666666666;2.666666666666666;2.666666666666666;2.666666666666666;2.666666666666666;2.666666666666666;2.666666666666666;8.0;8.0;8.0;8.0;8.0;8.0;8.0;8.0;8.0;8.0;8.0;8.0;8.0;8.0;8.0;8.0]
let z =[-8.0;-8.0;-8.0;-8.0;-8.0;-8.0;-8.0;-8.0;-8.0;-8.0;-8.0;-8.0;-8.0;-8.0;-8.0;-8.0;-2.666666666666667;-2.666666666666667;-2.666666666666667;-2.666666666666667;-2.666666666666667;-2.666666666666667;-2.666666666666667;-2.666666666666667;-2.666666666666667;-2.666666666666667;-2.666666666666667;-2.666666666666667;-2.666666666666667;-2.666666666666667;-2.666666666666667;-2.666666666666667;2.666666666666666;2.666666666666666;2.666666666666666;2.666666666666666;2.666666666666666;2.666666666666666;2.666666666666666;2.666666666666666;2.666666666666666;2.666666666666666;2.666666666666666;2.666666666666666;2.666666666666666;2.666666666666666;2.666666666666666;2.666666666666666;8.0;8.0;8.0;8.0;8.0;8.0;8.0;8.0;8.0;8.0;8.0;8.0;8.0;8.0;8.0;8.0]
let value =[0.00015530955861889912;0.004994853639720335;0.004994853639720164;0.00015530955861889912;0.004994853639720335;0.005865742088537837;0.005865742088537603;0.004994853639720335;0.004994853639720164;0.005865742088537603;0.0058657420885372515;0.004994853639720164;0.00015530955861889912;0.004994853639720335;0.004994853639720164;0.00015530955861889912;0.004994853639720335;0.005865742088537837;0.005865742088537603;0.004994853639720335;0.005865742088537837;0.005967638441171089;0.00596763844117072;0.005865742088537837;0.005865742088537603;0.005967638441170904;0.005967638441170535;0.005865742088537603;0.004994853639720335;0.005865742088537837;0.005865742088537603;0.004994853639720335;0.004994853639720164;0.005865742088537603;0.0058657420885372515;0.004994853639720164;0.005865742088537603;0.005967638441170904;0.005967638441170535;0.005865742088537603;0.0058657420885372515;0.005967638441170535;0.005967638441170165;0.0058657420885372515;0.004994853639720164;0.005865742088537603;0.0058657420885372515;0.004994853639720164;0.00015530955861889912;0.004994853639720335;0.004994853639720164;0.00015530955861889912;0.004994853639720335;0.005865742088537837;0.005865742088537603;0.004994853639720335;0.004994853639720164;0.005865742088537603;0.0058657420885372515;0.004994853639720164;0.00015530955861889912;0.004994853639720335;0.004994853639720164;0.00015530955861889912]

let findAllIndices predicate =
    Array.indexed
    >> Array.filter (snd >> predicate)
    >> Array.map fst


let volume3d =
        Trace3d.initVolume (fun volume3d ->
            volume3d?x <- x
            volume3d?y <-y
            volume3d?z <-z
            volume3d?value <-x
            volume3d?isomin <-0.1
            volume3d?isomax <-0.8
            volume3d?opacity<-0.5
            volume3d?color <- "lightpink"
            volume3d
            )
        |> GenericChart.ofTraceObject
        |> Chart.withLayout layout
In [3]:
volume3d
Out[3]: